diff options
Diffstat (limited to 'bfd/cofflink.c')
-rw-r--r-- | bfd/cofflink.c | 116 |
1 files changed, 16 insertions, 100 deletions
diff --git a/bfd/cofflink.c b/bfd/cofflink.c index d4e3345..8c3f71b 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -29,9 +29,11 @@ #include "libcoff.h" #include "safe-ctype.h" -static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info); -static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded); -static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info); +static bfd_boolean coff_link_add_object_symbols (bfd *, struct bfd_link_info *); +static bfd_boolean coff_link_check_archive_element + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, + bfd_boolean *); +static bfd_boolean coff_link_add_symbols (bfd *, struct bfd_link_info *); /* Return TRUE if SYM is a weak, external symbol. */ #define IS_WEAK_EXTERNAL(abfd, sym) \ @@ -190,74 +192,6 @@ coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) return TRUE; } -/* Look through the symbols to see if this object file should be - included in the link. */ - -static bfd_boolean -coff_link_check_ar_symbols (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean *pneeded, - bfd **subsbfd) -{ - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - *pneeded = FALSE; - - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - enum coff_symbol_classification classification; - - bfd_coff_swap_sym_in (abfd, esym, &sym); - - classification = bfd_coff_classify_symbol (abfd, &sym); - if (classification == COFF_SYMBOL_GLOBAL - || classification == COFF_SYMBOL_COMMON) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct bfd_link_hash_entry *h; - - /* This symbol is externally visible, and is defined by this - object file. */ - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return FALSE; - h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); - - /* Auto import. */ - if (!h - && info->pei386_auto_import - && CONST_STRNEQ (name, "__imp_")) - h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE); - - /* We are only interested in symbols that are currently - undefined. If a symbol is currently known to be common, - COFF linkers do not bring in an object file which defines - it. */ - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) - { - if (!(*info->callbacks - ->add_archive_element) (info, abfd, name, subsbfd)) - return FALSE; - *pneeded = TRUE; - return TRUE; - } - } - - esym += (sym.n_numaux + 1) * symesz; - } - - /* We do not need this object file. */ - return TRUE; -} - /* Check a single archive element to see if we need to include it in the link. *PNEEDED is set according to whether this element is needed in the link or not. This is called via @@ -266,41 +200,23 @@ coff_link_check_ar_symbols (bfd *abfd, static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, + struct bfd_link_hash_entry *h, + const char *name, bfd_boolean *pneeded) { - bfd *oldbfd; - bfd_boolean needed; + *pneeded = FALSE; - if (!_bfd_coff_get_external_symbols (abfd)) - return FALSE; + /* We are only interested in symbols that are currently undefined. + If a symbol is currently known to be common, COFF linkers do not + bring in an object file which defines it. */ + if (h->type != bfd_link_hash_undefined) + return TRUE; - oldbfd = abfd; - if (!coff_link_check_ar_symbols (abfd, info, pneeded, &abfd)) + if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd)) return FALSE; + *pneeded = TRUE; - needed = *pneeded; - if (needed) - { - /* Potentially, the add_archive_element hook may have set a - substitute BFD for us. */ - if (abfd != oldbfd) - { - if (!info->keep_memory - && !_bfd_coff_free_symbols (oldbfd)) - return FALSE; - if (!_bfd_coff_get_external_symbols (abfd)) - return FALSE; - } - if (!coff_link_add_symbols (abfd, info)) - return FALSE; - } - - if (!info->keep_memory || !needed) - { - if (!_bfd_coff_free_symbols (abfd)) - return FALSE; - } - return TRUE; + return coff_link_add_object_symbols (abfd, info); } /* Add all the symbols from an object file to the hash table. */ |