コード例 #1
0
ファイル: arm-macosx-tdep.c プロジェクト: aosm/gdb
static enum gdb_osabi
arm_mach_o_osabi_sniffer_use_dyld_hint (bfd *abfd)
{
  if (osabi_seen_in_attached_dyld == GDB_OSABI_UNKNOWN)
    return GDB_OSABI_UNKNOWN;

  bfd *nbfd = NULL;
  for (;;)
    {
      bfd_arch_info_type *arch_info;
      nbfd = bfd_openr_next_archived_file (abfd, nbfd);

      if (nbfd == NULL)
        break;
      if (!bfd_check_format (nbfd, bfd_object))
        continue;
      arch_info = bfd_get_arch_info (nbfd);

      if (arch_info->arch == bfd_arch_arm)
	{
	  if (arch_info->mach == bfd_mach_arm_4T
	      && osabi_seen_in_attached_dyld == GDB_OSABI_DARWIN)
	    return GDB_OSABI_DARWIN;
	  
	  if (arch_info->mach == bfd_mach_arm_6
	      && osabi_seen_in_attached_dyld == GDB_OSABI_DARWINV6)
	    return GDB_OSABI_DARWINV6;
	}
    }

  return GDB_OSABI_UNKNOWN;
}
コード例 #2
0
ファイル: bfdtest1.c プロジェクト: LLInuJIbKa/binutils
int
main (int argc, char **argv)
{
  bfd *archive;
  bfd *last, *next;

  if (argc != 2)
    die ("bad usage");

  archive = bfd_openr (argv[1], NULL);

  if (!bfd_check_format (archive, bfd_archive))
    {
      bfd_close (archive);
      die ("bfd_check_format");
    }

  for (last = bfd_openr_next_archived_file (archive, NULL);
       last;
       last = next)
    {
      next = bfd_openr_next_archived_file (archive, last);
      bfd_close (last);
    }

  for (last = bfd_openr_next_archived_file (archive, NULL);
       last;
       last = next)
    {
      next = bfd_openr_next_archived_file (archive, last);
      bfd_close (last);
    }

  if (!bfd_close (archive))
    die ("bfd_close");

  return 0;
}
コード例 #3
0
ファイル: rlink.c プロジェクト: BackupTheBerlios/wrapl-svn
static void add_bfd(bfd *Bfd) {
	if (bfd_check_format(Bfd, bfd_object)) {
		bfd_info_t *BfdInfo = new(bfd_info_t);
		BfdInfo->FileName = Bfd->filename;
		memset(BfdInfo->LocalTable, 0, sizeof(BfdInfo->LocalTable));
		BfdInfo->Symbols = (asymbol **)malloc(bfd_get_symtab_upper_bound(Bfd));
		int NoOfSymbols = bfd_canonicalize_symtab(Bfd, BfdInfo->Symbols);
		bfd_map_over_sections(Bfd, (bfd_map)add_bfd_section, BfdInfo);
		for (int I = NoOfSymbols - 1; I >= 0; --I) {
			asymbol *Sym = BfdInfo->Symbols[I];
			if (Sym->flags & BSF_GLOBAL) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(BfdInfo->LocalTable, Name, Symbol);
				stringtable_put(GlobalTable, Name, Symbol);
			} else if (Sym->section == bfd_com_section_ptr) {
				symbol_t *Symbol = (symbol_t *)stringtable_get(GlobalTable, Sym->name);
				bss_section_t *Section;
				if (!Symbol) {
					const char *Name = strdup(Sym->name);
					Section = new_bss_section(0);
					Symbol = new_symbol(Name, (section_t *)Section, 0);
					stringtable_put(GlobalTable, Name, Symbol);
					stringtable_put(BfdInfo->LocalTable, Name, Symbol);
				} else {
					Section = (bss_section_t *)Symbol->Section;
				};
				if (Sym->value > Section->Size) Section->Size = Sym->value;
			} else if (Sym->flags & BSF_LOCAL) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(BfdInfo->LocalTable, Name, Symbol);
			} else if (Sym->flags & BSF_WEAK) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(WeakTable, Name, Symbol);
			} else if (Sym->section == bfd_und_section_ptr) {
			} else if (Sym->flags & BSF_DEBUGGING) {
			    // This may be supported later
			} else {
				printf("%s: unknown symbol type: %8x.\n", Bfd->filename, Sym->flags);
				exit(1);
			};
		};
	} else if (bfd_check_format(Bfd, bfd_archive)) {
		bfd *Bfd2 = 0;
		while ((Bfd2 = bfd_openr_next_archived_file(Bfd, Bfd2))) add_bfd(Bfd2);
	};
};
コード例 #4
0
ファイル: macosx-fat-utils.c プロジェクト: argp/macgdb
bfd *
open_bfd_matching_arch (bfd *archive_bfd, bfd_format expected_format)
{
  enum gdb_osabi osabi;
  bfd *abfd;
  
  osabi = GDB_OSABI_UNINITIALIZED;
  abfd = NULL;

  osabi = gdbarch_osabi (get_current_arch ());
  if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID))
    osabi = gdbarch_lookup_osabi (archive_bfd);
  
  // FIXME: gdbarch_lookup_osabi() doesn't work yet on archive_bfd, hardcode
  if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID))
    osabi = GDB_OSABI_DARWIN;
  
  for (;;)
    {
      abfd = bfd_openr_next_archived_file (archive_bfd, abfd);
      if (abfd == NULL)
        break;
      if (! bfd_check_format (abfd, expected_format))
        continue;
      if (osabi == gdbarch_lookup_osabi_from_bfd (abfd))
        break;
    }
    
  // Copy the filename of the archive to the binary bfd.
  if (abfd)
  {
    xfree(abfd->filename);
    abfd->filename = archive_bfd->filename;
  }
  
  return abfd;
}
コード例 #5
0
ファイル: Archive.cpp プロジェクト: epronk/nmdepend
void Archive::Read(const char* filename, Symbol::SymbolIndex_t& symbolIndex)
{
   char *target = 0;
   bfd *file;

   file = bfd_openr (filename, target);
   if (file == 0)
   {
      //    bfd_nonfatal (filename);
   //   return FALSE;
   }

   if (bfd_check_format (file, bfd_archive))
   {
      //    display_archive (file);
      bfd *arfile = 0;

      std::cout << "file " << bfd_get_filename (file) << std::endl;

      while(arfile = bfd_openr_next_archived_file (file, arfile))
      {
         const char* objectname = bfd_get_filename (arfile);
         ObjectFile* o = new ObjectFile(objectname, symbolIndex);
         o->SetParent(*this);
         o->Read(arfile);
         std::cout << "file " << bfd_get_filename (arfile) << std::endl;
      }

      if (arfile == NULL)
      {
      //if (bfd_get_error () != bfd_error_no_more_archived_files)
      //bfd_fatal (bfd_get_filename (file));
      //break;
      }
   }
}
コード例 #6
0
static struct vmap *
add_vmap (LdInfo *ldi)
{
  bfd *abfd, *last;
  char *mem, *objname, *filename;
  struct objfile *obj;
  struct vmap *vp;
  int fd;
  ARCH64_DECL (arch64);

  /* This ldi structure was allocated using alloca() in 
     xcoff_relocate_symtab(). Now we need to have persistent object 
     and member names, so we should save them. */

  filename = LDI_FILENAME (ldi, arch64);
  mem = filename + strlen (filename) + 1;
  mem = xstrdup (mem);
  objname = xstrdup (filename);

  fd = LDI_FD (ldi, arch64);
  if (fd < 0)
    /* Note that this opens it once for every member; a possible
       enhancement would be to only open it once for every object.  */
    abfd = bfd_openr (objname, gnutarget);
  else
    abfd = bfd_fdopenr (objname, gnutarget, fd);
  if (!abfd)
    {
      warning (_("Could not open `%s' as an executable file: %s"),
	       objname, bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  /* make sure we have an object file */

  if (bfd_check_format (abfd, bfd_object))
    vp = map_vmap (abfd, 0);

  else if (bfd_check_format (abfd, bfd_archive))
    {
      last = 0;
      /* FIXME??? am I tossing BFDs?  bfd? */
      while ((last = bfd_openr_next_archived_file (abfd, last)))
	if (strcmp (mem, last->filename) == 0)
	  break;

      if (!last)
	{
	  warning (_("\"%s\": member \"%s\" missing."), objname, mem);
	  bfd_close (abfd);
	  return NULL;
	}

      if (!bfd_check_format (last, bfd_object))
	{
	  warning (_("\"%s\": member \"%s\" not in executable format: %s."),
		   objname, mem, bfd_errmsg (bfd_get_error ()));
	  bfd_close (last);
	  bfd_close (abfd);
	  return NULL;
	}

      vp = map_vmap (last, abfd);
    }
  else
    {
      warning (_("\"%s\": not in executable format: %s."),
	       objname, bfd_errmsg (bfd_get_error ()));
      bfd_close (abfd);
      return NULL;
    }
  obj = allocate_objfile (vp->bfd, 0);
  vp->objfile = obj;

  /* Always add symbols for the main objfile.  */
  if (vp == vmap || auto_solib_add)
    vmap_add_symbols (vp);
  return vp;
}
コード例 #7
0
ファイル: ldfile.c プロジェクト: Distrotech/binutils
bfd_boolean
ldfile_try_open_bfd (const char *attempt,
		     lang_input_statement_type *entry)
{
  entry->the_bfd = bfd_openr (attempt, entry->target);

  if (verbose)
    {
      if (entry->the_bfd == NULL)
	info_msg (_("attempt to open %s failed\n"), attempt);
      else
	info_msg (_("attempt to open %s succeeded\n"), attempt);
    }

  if (entry->the_bfd == NULL)
    {
      if (bfd_get_error () == bfd_error_invalid_target)
	einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
      return FALSE;
    }

  /* Linker needs to decompress sections.  */
  entry->the_bfd->flags |= BFD_DECOMPRESS;

  /* This is a linker input BFD.  */
  entry->the_bfd->is_linker_input = 1;

#ifdef ENABLE_PLUGINS
  if (entry->flags.lto_output)
    entry->the_bfd->lto_output = 1;
#endif

  /* If we are searching for this file, see if the architecture is
     compatible with the output file.  If it isn't, keep searching.
     If we can't open the file as an object file, stop the search
     here.  If we are statically linking, ensure that we don't link
     a dynamic object.

     In the code below, it's OK to exit early if the check fails,
     closing the checked BFD and returning FALSE, but if the BFD
     checks out compatible, do not exit early returning TRUE, or
     the plugins will not get a chance to claim the file.  */

  if (entry->flags.search_dirs || !entry->flags.dynamic)
    {
      bfd *check;

      if (bfd_check_format (entry->the_bfd, bfd_archive))
	check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
      else
	check = entry->the_bfd;

      if (check != NULL)
	{
	  if (! bfd_check_format (check, bfd_object))
	    {
	      if (check == entry->the_bfd
		  && entry->flags.search_dirs
		  && bfd_get_error () == bfd_error_file_not_recognized
		  && ! ldemul_unrecognized_file (entry))
		{
		  int token, skip = 0;
		  char *arg, *arg1, *arg2, *arg3;
		  extern FILE *yyin;

		  /* Try to interpret the file as a linker script.  */
		  ldfile_open_command_file (attempt);

		  ldfile_assumed_script = TRUE;
		  parser_input = input_selected;
		  ldlex_both ();
		  token = INPUT_SCRIPT;
		  while (token != 0)
		    {
		      switch (token)
			{
			case OUTPUT_FORMAT:
			  if ((token = yylex ()) != '(')
			    continue;
			  if ((token = yylex ()) != NAME)
			    continue;
			  arg1 = yylval.name;
			  arg2 = NULL;
			  arg3 = NULL;
			  token = yylex ();
			  if (token == ',')
			    {
			      if ((token = yylex ()) != NAME)
				{
				  free (arg1);
				  continue;
				}
			      arg2 = yylval.name;
			      if ((token = yylex ()) != ','
				  || (token = yylex ()) != NAME)
				{
				  free (arg1);
				  free (arg2);
				  continue;
				}
			      arg3 = yylval.name;
			      token = yylex ();
			    }
			  if (token == ')')
			    {
			      switch (command_line.endian)
				{
				default:
				case ENDIAN_UNSET:
				  arg = arg1; break;
				case ENDIAN_BIG:
				  arg = arg2 ? arg2 : arg1; break;
				case ENDIAN_LITTLE:
				  arg = arg3 ? arg3 : arg1; break;
				}
			      if (strcmp (arg, lang_get_output_target ()) != 0)
				skip = 1;
			    }
			  free (arg1);
			  if (arg2) free (arg2);
			  if (arg3) free (arg3);
			  break;
			case NAME:
			case LNAME:
			case VERS_IDENTIFIER:
			case VERS_TAG:
			  free (yylval.name);
			  break;
			case INT:
			  if (yylval.bigint.str)
			    free (yylval.bigint.str);
			  break;
			}
		      token = yylex ();
		    }
		  ldlex_popstate ();
		  ldfile_assumed_script = FALSE;
		  fclose (yyin);
		  yyin = NULL;
		  if (skip)
		    {
		      if (command_line.warn_search_mismatch)
			einfo (_("%P: skipping incompatible %s "
				 "when searching for %s\n"),
			       attempt, entry->local_sym_name);
		      bfd_close (entry->the_bfd);
		      entry->the_bfd = NULL;
		      return FALSE;
		    }
		}
	      goto success;
	    }

	  if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
	    {
	      einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
		     attempt);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }

	  if (entry->flags.search_dirs
	      && !bfd_arch_get_compatible (check, link_info.output_bfd,
					   command_line.accept_unknown_input_arch)
	      /* XCOFF archives can have 32 and 64 bit objects.  */
	      && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
		    && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour
		    && bfd_check_format (entry->the_bfd, bfd_archive)))
	    {
	      if (command_line.warn_search_mismatch)
		einfo (_("%P: skipping incompatible %s "
			 "when searching for %s\n"),
		       attempt, entry->local_sym_name);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }
	}
    }
success:
#ifdef ENABLE_PLUGINS
  /* If plugins are active, they get first chance to claim
     any successfully-opened input file.  We skip archives
     here; the plugin wants us to offer it the individual
     members when we enumerate them, not the whole file.  We
     also ignore corefiles, because that's just weird.  It is
     a needed side-effect of calling  bfd_check_format with
     bfd_object that it sets the bfd's arch and mach, which
     will be needed when and if we want to bfd_create a new
     one using this one as a template.  */
  if (link_info.lto_plugin_active
      && !no_more_claiming
      && bfd_check_format (entry->the_bfd, bfd_object))
    plugin_maybe_claim (entry);
#endif /* ENABLE_PLUGINS */

  /* It opened OK, the format checked out, and the plugins have had
     their chance to claim it, so this is success.  */
  return TRUE;
}
コード例 #8
0
ファイル: load_archive_old.c プロジェクト: n-n-n/BinaryHack
/*
 archive file (*.a) loading test
 */
int main()
{
    int ret;
    int symnum;
    bfd* abfd;
    asymbol** syms;
    int symbol_pos, symbol_size;
    int index;



#ifndef OBJ_TEST
    const char* file = "foo.a";
#else
    const char* file = "hello.o";
#endif
    unsigned char* file_o;

    file_o = load_file(file);

    abfd = bfd_openr(file, NULL);
    assert(abfd);
    ret = bfd_check_format(abfd, bfd_archive);
    //ret = bfd_check_format(abfd, bfd_object);
    assert(ret);

#ifndef OBJ_TEST
    bfd* b = NULL;
#else
    bfd* b = abfd;//NULL;
#endif
    link_list_t* bfds = NULL;
    STEP_LOG("create function map\n");
#ifndef OBJ_TEST
    while(NULL != (b = bfd_openr_next_archived_file(abfd, b))) 
#endif
    {
        ret = bfd_check_format(b, bfd_object);
        assert(ret);
//        STEP_LOG("next\n");
        if (!(bfd_get_file_flags(b) & HAS_SYMS)) {
            assert(bfd_get_error() == bfd_error_no_error);
            /* no symbol */
            bfd_close(abfd);
            return 1;
        }

        if (NULL == bfds) {
            LOG("Add first:0x%08X\n", (int)b);
            bfds = add_item(bfds, &b, sizeof(b));
        } else {
            LOG("Add bfd:0x%08X\n", (int)b);
            add_item(bfds, &b, sizeof(b));
        }

        get_symbols(&syms, &symnum, b);
        create_symbol_function_pos(file_o, b, syms, symnum);
    }
    STEP_LOG("relocate function addresses\n");
    link_list_t* list = bfds;
    while(NULL != list) {
        b = *(bfd**)(list->item);
        get_symbols(&syms, &symnum, b);
        reloc_file(file_o, b, syms);
        list = list->next;
    }
    STEP_LOG("try to get function addressses\n");
    int (*func)();
    void (*func1)(const char*);
    func = NULL;
    func1 = NULL;
    list = bfds;
    while(NULL != list) 
    {
        b = *(bfd**)(list->item);
        LOG("bfd:0x%08X\n", (int)b);

        LOG("call goodby....");
        get_symbols(&syms, &symnum, b);
        symbol_pos = get_symbol_pos("goodby", b, syms, symnum, file_o);
        if (0 != symbol_pos) { 
            func = (int (*) ())(get_function(symbol_pos));
        }

        LOG("call hello_someone....");
        symbol_pos = get_symbol_pos("hello_someone", b, syms, symnum, file_o);
        if (0 != symbol_pos) { 
            func1 = (void (*) (const char*))(get_function(symbol_pos));
        }
        if (NULL != func && NULL != func1) break;
        list = list->next;
    }
    STEP_LOG("try to call functions\n");
    if (NULL != func) {
        func();
    } else {
        LOG("failed to call func\n");
    }
    if (NULL != func1) {
        func1("WORLD!");
    } else {
        LOG("failed to call func\n");
    }


    delete_all_items(bfds);
    free(syms);
    bfd_close(abfd);

    free(file_o);
    return 0;
}
コード例 #9
0
ファイル: arm-macosx-tdep.c プロジェクト: aosm/gdb
static enum gdb_osabi
arm_mach_o_osabi_sniffer (bfd *abfd)
{
  enum gdb_osabi ret;

  /* The way loading works on Darwin is that for FAT files, the
     fork corresponding to the host system will be the one used
     regardless of what the type of the main executable was.
     So the osabi has to be determined solely by the type of
     the host system.  */


  if (strcmp (bfd_get_target (abfd), "mach-o-le") == 0)
    {
      bfd_arch_info_type *arch_info = bfd_get_arch_info (abfd);
      if (arch_info->arch == bfd_arch_arm)
	{
	  if (arch_info->mach == bfd_mach_arm_4T)
	    return GDB_OSABI_DARWIN;
	  else if (arch_info->mach == bfd_mach_arm_6)
	    return GDB_OSABI_DARWINV6;
	}
    }

  /* However, if we are running a cross gdb, we won't know what
     the target architecture is.  FIXME - going to have to determine
     this somehow.  For now, fall back to looking at the binary.  */

  ret = arm_mach_o_osabi_sniffer_use_dyld_hint (abfd);
  if (ret == GDB_OSABI_DARWINV6 || ret == GDB_OSABI_DARWIN)
    return ret;

  if (bfd_check_format (abfd, bfd_archive))
    {
      enum gdb_osabi best = GDB_OSABI_UNKNOWN;
      enum gdb_osabi cur = GDB_OSABI_UNKNOWN;

      bfd *nbfd = NULL;
      for (;;)
        {
          nbfd = bfd_openr_next_archived_file (abfd, nbfd);

          if (nbfd == NULL)
            break;
          if (!bfd_check_format (nbfd, bfd_object))
            continue;

          cur = arm_mach_o_osabi_sniffer (nbfd);
          if (cur == GDB_OSABI_DARWINV6 &&
              best != GDB_OSABI_DARWINV6 && arm_mach_o_query_v6 ())
            best = cur;

          if (cur == GDB_OSABI_DARWIN &&
              best != GDB_OSABI_DARWINV6 && best != GDB_OSABI_DARWIN)
            best = cur;
        }
      return best;
    }

  if (!bfd_check_format (abfd, bfd_object))
    return GDB_OSABI_UNKNOWN;

  return GDB_OSABI_UNKNOWN;
}
コード例 #10
0
bfd_boolean
ldfile_try_open_bfd (const char *attempt,
		     lang_input_statement_type *entry)
{
  entry->the_bfd = bfd_openr (attempt, entry->target);

  if (trace_file_tries)
    {
      if (entry->the_bfd == NULL)
	info_msg (_("attempt to open %s failed\n"), attempt);
      else
	info_msg (_("attempt to open %s succeeded\n"), attempt);
    }

  if (entry->the_bfd == NULL)
    {
      if (bfd_get_error () == bfd_error_invalid_target)
	einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
      return FALSE;
    }

  /* If we are searching for this file, see if the architecture is
     compatible with the output file.  If it isn't, keep searching.
     If we can't open the file as an object file, stop the search
     here.  If we are statically linking, ensure that we don't link
     a dynamic object.  */

  if (entry->search_dirs_flag || !entry->dynamic)
    {
      bfd *check;

      if (bfd_check_format (entry->the_bfd, bfd_archive))
	check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
      else
	check = entry->the_bfd;

      if (check != NULL)
	{
	  if (! bfd_check_format (check, bfd_object))
	    {
	      if (check == entry->the_bfd
		  && entry->search_dirs_flag
		  && bfd_get_error () == bfd_error_file_not_recognized
		  && ! ldemul_unrecognized_file (entry))
		{
		  int token, skip = 0;
		  char *arg, *arg1, *arg2, *arg3;
		  extern FILE *yyin;

		  /* Try to interpret the file as a linker script.  */
		  ldfile_open_command_file (attempt);

		  ldfile_assumed_script = TRUE;
		  parser_input = input_selected;
		  ldlex_both ();
		  token = INPUT_SCRIPT;
		  while (token != 0)
		    {
		      switch (token)
			{
			case OUTPUT_FORMAT:
			  if ((token = yylex ()) != '(')
			    continue;
			  if ((token = yylex ()) != NAME)
			    continue;
			  arg1 = yylval.name;
			  arg2 = NULL;
			  arg3 = NULL;
			  token = yylex ();
			  if (token == ',')
			    {
			      if ((token = yylex ()) != NAME)
				{
				  free (arg1);
				  continue;
				}
			      arg2 = yylval.name;
			      if ((token = yylex ()) != ','
				  || (token = yylex ()) != NAME)
				{
				  free (arg1);
				  free (arg2);
				  continue;
				}
			      arg3 = yylval.name;
			      token = yylex ();
			    }
			  if (token == ')')
			    {
			      switch (command_line.endian)
				{
				default:
				case ENDIAN_UNSET:
				  arg = arg1; break;
				case ENDIAN_BIG:
				  arg = arg2 ? arg2 : arg1; break;
				case ENDIAN_LITTLE:
				  arg = arg3 ? arg3 : arg1; break;
				}
			      if (strcmp (arg, lang_get_output_target ()) != 0)
				skip = 1;
			    }
			  free (arg1);
			  if (arg2) free (arg2);
			  if (arg3) free (arg3);
			  break;
			case NAME:
			case LNAME:
			case VERS_IDENTIFIER:
			case VERS_TAG:
			  free (yylval.name);
			  break;
			case INT:
			  if (yylval.bigint.str)
			    free (yylval.bigint.str);
			  break;
			}
		      token = yylex ();
		    }
		  ldlex_popstate ();
		  ldfile_assumed_script = FALSE;
		  fclose (yyin);
		  yyin = NULL;
		  if (skip)
		    {
		      if (command_line.warn_search_mismatch)
			einfo (_("%P: skipping incompatible %s "
				 "when searching for %s\n"),
			       attempt, entry->local_sym_name);
		      bfd_close (entry->the_bfd);
		      entry->the_bfd = NULL;
		      return FALSE;
		    }
		}
	      return TRUE;
	    }

	  if (!entry->dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
	    {
	      einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
		     attempt);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }

	  if (entry->search_dirs_flag
	      && !bfd_arch_get_compatible (check, link_info.output_bfd,
					   command_line.accept_unknown_input_arch)
	      /* XCOFF archives can have 32 and 64 bit objects.  */
	      && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
		    && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour
		    && bfd_check_format (entry->the_bfd, bfd_archive)))
	    {
	      if (command_line.warn_search_mismatch)
		einfo (_("%P: skipping incompatible %s "
			 "when searching for %s\n"),
		       attempt, entry->local_sym_name);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }
	}
    }

  return TRUE;
}