if ((abfd->flags & BFD_IN_MEMORY) != 0) { if (direction == SEEK_SET) abfd->where = position; else abfd->where += position; return 0; }
bfd_seek (abfd, position, direction)     bfd *abfd;     file_ptr position;     int direction;{  int result;  FILE *f;  file_ptr file_position;  /* For the time being, a BFD may not seek to it's end.  The problem     is that we don't easily have a way to recognize the end of an     element in an archive. */  BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);  if (direction == SEEK_CUR && position == 0)    return 0;#ifdef FILE_OFFSET_IS_CHAR_INDEX  if (abfd->format != bfd_archive && abfd->my_archive == 0)    {#if 0      /* Explanation for this code: I'm only about 95+% sure that the above	 conditions are sufficient and that all i/o calls are properly	 adjusting the `where' field.  So this is sort of an `assert'	 that the `where' field is correct.  If we can go a while without	 tripping the abort, we can probably safely disable this code,	 so that the real optimizations happen.  */      file_ptr where_am_i_now;      where_am_i_now = ftell (bfd_cache_lookup (abfd));      if (abfd->my_archive)	where_am_i_now -= abfd->origin;      if (where_am_i_now != abfd->where)	abort ();#endif      if (direction == SEEK_SET && position == abfd->where)	return 0;    }  else    {      /* We need something smarter to optimize access to archives.	 Currently, anything inside an archive is read via the file	 handle for the archive.  Which means that a bfd_seek on one	 component affects the `current position' in the archive, as	 well as in any other component.	 It might be sufficient to put a spike through the cache	 abstraction, and look to the archive for the file position,	 but I think we should try for something cleaner.	 In the meantime, no optimization for archives.  */    }#endif  f = bfd_cache_lookup (abfd);  file_position = position;  if (direction == SEEK_SET && abfd->my_archive != NULL)    file_position += abfd->origin;  result = fseek (f, file_position, direction);  if (result != 0)    {      /* Force redetermination of `where' field.  */      bfd_tell (abfd);      bfd_set_error (bfd_error_system_call);    }  else    {#ifdef FILE_OFFSET_IS_CHAR_INDEX      /* Adjust `where' field.  */      if (direction == SEEK_SET)	abfd->where = position;      else	abfd->where += position;#endif    }  return result;}