diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/aout-target.h | 4 | ||||
-rw-r--r-- | bfd/aoutx.h | 9 | ||||
-rw-r--r-- | bfd/coffgen.c | 18 | ||||
-rw-r--r-- | bfd/cofflink.c | 47 | ||||
-rw-r--r-- | bfd/elflink.c | 11 | ||||
-rw-r--r-- | bfd/elfxx-aarch64.c | 32 | ||||
-rw-r--r-- | bfd/elfxx-x86.c | 20 | ||||
-rw-r--r-- | bfd/format.c | 45 | ||||
-rw-r--r-- | bfd/i386aout.c | 1 | ||||
-rw-r--r-- | bfd/libaout.h | 7 | ||||
-rw-r--r-- | bfd/pdp11.c | 9 | ||||
-rw-r--r-- | bfd/version.h | 2 |
12 files changed, 124 insertions, 81 deletions
diff --git a/bfd/aout-target.h b/bfd/aout-target.h index f513e1b..1b71104 100644 --- a/bfd/aout-target.h +++ b/bfd/aout-target.h @@ -286,9 +286,6 @@ MY (set_sizes) (bfd *abfd) #ifndef MY_add_dynamic_symbols #define MY_add_dynamic_symbols 0 #endif -#ifndef MY_add_one_symbol -#define MY_add_one_symbol 0 -#endif #ifndef MY_link_dynamic_object #define MY_link_dynamic_object 0 #endif @@ -312,7 +309,6 @@ static const struct aout_backend_data MY (backend_data) = MY_set_sizes, MY_exec_header_not_counted, MY_add_dynamic_symbols, - MY_add_one_symbol, MY_link_dynamic_object, MY_write_dynamic_symbol, MY_check_dynamic_reloc, diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 63c654f..81e0804 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2973,9 +2973,6 @@ NAME (aout, link_hash_table_create) (bfd *abfd) static bool aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **); struct external_nlist *syms; bfd_size_type sym_count; char *strings; @@ -3013,10 +3010,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) return false; obj_aout_sym_hashes (abfd) = sym_hash; - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - p = syms; pend = p + sym_count; for (; p < pend; p++, sym_hash++) @@ -3167,7 +3160,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) break; } - if (! ((*add_one_symbol) + if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, string, copy, false, (struct bfd_link_hash_entry **) sym_hash))) return false; diff --git a/bfd/coffgen.c b/bfd/coffgen.c index f87e54f..ab4d790 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -42,6 +42,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "elf-bfd.h" #include "hashtab.h" /* Extract a long section name at STRINDEX and copy it to the bfd objstack. @@ -1270,9 +1271,24 @@ coff_write_alien_symbol (bfd *abfd, if (c != (coff_symbol_type *) NULL) native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; } + + const elf_symbol_type *elfsym = elf_symbol_from (symbol); + if (elfsym + && (symbol->flags & BSF_FUNCTION) + && elfsym->internal_elf_sym.st_size) + { + /* coff_data (abfd)->local_n_btshft is what ought to be used here, + just that it's set only when reading in COFF objects. */ + native->u.syment.n_type = DT_FCN << 4; + native->u.syment.n_numaux = 1; + native[1].u.auxent.x_sym.x_misc.x_fsize + = elfsym->internal_elf_sym.st_size; + /* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also + be set, which would require updating the field once the next + function is seen. */ + } } - native->u.syment.n_type = 0; if (symbol->flags & BSF_FILE) native->u.syment.n_sclass = C_FILE; else if (symbol->flags & BSF_LOCAL) diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 501731b..38278e2 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -27,6 +27,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "elf-bfd.h" #include "safe-ctype.h" static bool coff_link_add_object_symbols (bfd *, struct bfd_link_info *); @@ -931,14 +932,52 @@ _bfd_coff_final_link (bfd *abfd, bfd_vma written = 0; bool rewrite = false; - if (! (sym->flags & BSF_LOCAL) - || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC - | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC - | BSF_SYNTHETIC)) + if ((sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC + | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC + | BSF_SYNTHETIC)) || ((sym->flags & BSF_DEBUGGING) && ! (sym->flags & BSF_FILE))) continue; + if (! (sym->flags & BSF_LOCAL)) + { + /* For ELF symbols try to represent their function-ness and + size, if available. */ + if (! (sym->flags & BSF_FUNCTION)) + continue; + + const elf_symbol_type *elfsym = elf_symbol_from (sym); + if (!elfsym) + continue; + + struct coff_link_hash_entry *hent + = (struct coff_link_hash_entry *) bfd_hash_lookup + (&info->hash->table, bfd_asymbol_name (sym), + false, false); + if (!hent) + continue; + + /* coff_data (abfd)->local_n_btshft is what ought to be used + here, just that it's set only when reading in COFF + objects. */ + hent->type = DT_FCN << 4; + if (!elfsym->internal_elf_sym.st_size) + continue; + + hent->aux = bfd_zalloc (abfd, sizeof (*hent->aux)); + if (!hent->aux) + continue; + + hent->numaux = 1; + hent->aux->x_sym.x_misc.x_fsize + = elfsym->internal_elf_sym.st_size; + /* FIXME ->x_sym.x_fcnary.x_fcn.x_endndx would better + also be set, yet that would likely need to happen + elsewhere anyway. */ + + continue; + } + /* See if we are discarding symbols with this name. */ if ((flaginfo.info->strip == strip_some && (bfd_hash_lookup (flaginfo.info->keep_hash, diff --git a/bfd/elflink.c b/bfd/elflink.c index a76e8e3..919f2a7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -6290,8 +6290,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) continue; /* In the pre-LTO-plugin pass we must not mistakenly - include this archive member if an earlier BFD - defined this symbol. */ + include this archive member if an earlier shared + library defined this symbol. */ struct elf_link_hash_table *htab = elf_hash_table (info); if (htab->first_hash) { @@ -6299,7 +6299,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) = ((struct elf_link_first_hash_entry *) bfd_hash_lookup (htab->first_hash, symdef->name, false, false)); - if (e && e->abfd != abfd) + if (e + && (e->abfd->flags & DYNAMIC) != 0 + && e->abfd != abfd) continue; } } @@ -14408,7 +14410,8 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info) if (o->flags & SEC_GROUP) { asection *first = elf_next_in_group (o); - o->gc_mark = first->gc_mark; + if (first != NULL) + o->gc_mark = first->gc_mark; } if (o->gc_mark) diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index 45a0205..68e004ef 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -930,28 +930,20 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info) GNU properties (if found). */ bfd *pbfd = _bfd_elf_link_setup_gnu_properties (info); - /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update - outprop accordingly. */ if (pbfd != NULL) { - /* The property list is sorted in order of type. */ - for (elf_property_list *p = elf_properties (pbfd); - (p != NULL) - && (GNU_PROPERTY_AARCH64_FEATURE_1_AND <= p->property.pr_type); - p = p->next) - { - /* This merge of features should happen only once as all the identical - properties are supposed to have been merged at this stage by - _bfd_elf_link_setup_gnu_properties(). */ - if (p->property.pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) - { - outprop = (p->property.u.number - & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI - | GNU_PROPERTY_AARCH64_FEATURE_1_PAC - | GNU_PROPERTY_AARCH64_FEATURE_1_GCS)); - break; - } - } + elf_property_list *p; + elf_property_list *plist = elf_properties (pbfd); + + /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update + outprop accordingly. */ + if ((p = _bfd_elf_find_property (plist, + GNU_PROPERTY_AARCH64_FEATURE_1_AND, NULL)) + != NULL) + outprop = p->property.u.number + & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI + | GNU_PROPERTY_AARCH64_FEATURE_1_PAC + | GNU_PROPERTY_AARCH64_FEATURE_1_GCS); } tdata->gnu_property_aarch64_feature_1_and = outprop; diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 6ea41f2..bc9bb70 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -609,8 +609,7 @@ _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab, return &ret->elf; } -/* Create an entry in a x86 ELF linker hash table. NB: THIS MUST BE IN - SYNC WITH _bfd_elf_link_hash_newfunc. */ +/* Create an entry in an x86 ELF linker hash table. */ struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry, @@ -629,27 +628,14 @@ _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry, } /* Call the allocation method of the superclass. */ - entry = _bfd_link_hash_newfunc (entry, table, string); + entry = _bfd_elf_link_hash_newfunc (entry, table, string); if (entry != NULL) { struct elf_x86_link_hash_entry *eh = (struct elf_x86_link_hash_entry *) entry; - struct elf_link_hash_table *htab - = (struct elf_link_hash_table *) table; - memset (&eh->elf.size, 0, - (sizeof (struct elf_x86_link_hash_entry) - - offsetof (struct elf_link_hash_entry, size))); + memset (&eh->elf + 1, 0, sizeof (*eh) - sizeof (eh->elf)); /* Set local fields. */ - eh->elf.indx = -1; - eh->elf.dynindx = -1; - eh->elf.got = htab->init_got_refcount; - eh->elf.plt = htab->init_plt_refcount; - /* Assume that we have been called by a non-ELF symbol reader. - This flag is then reset by the code which reads an ELF input - file. This ensures that a symbol created by a non-ELF symbol - reader will have the flag set correctly. */ - eh->elf.non_elf = 1; eh->plt_second.offset = (bfd_vma) -1; eh->plt_got.offset = (bfd_vma) -1; eh->tlsdesc_got = (bfd_vma) -1; diff --git a/bfd/format.c b/bfd/format.c index 7769ad0..a909b70 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -331,6 +331,25 @@ print_and_clear_messages (struct per_xvec_messages *list, free (iter); iter = next; } + + /* Don't retain a pointer to free'd memory. */ + list->next = NULL; +} + +/* Discard all messages associated with TARG in LIST. Unlike + print_and_clear_messages, PER_XVEC_NO_TARGET is not valid for TARG. */ + +static void +clear_messages (struct per_xvec_messages *list, + const bfd_target *targ) +{ + struct per_xvec_messages *iter; + + for (iter = list; iter != NULL; iter = iter->next) + { + if (iter->targ == targ) + clear_warnmsg (&iter->messages); + } } /* This a copy of lto_section defined in GCC (lto-streamer.h). */ @@ -451,7 +470,18 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) /* Avoid clashes with bfd_cache_close_all running in another thread. */ if (!bfd_cache_set_uncloseable (abfd, true, &old_in_format_matches)) - return false; + { + free (matching_vector); + return false; + } + + /* Locking is required here in order to manage _bfd_section_id. */ + if (!bfd_lock ()) + { + bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL); + free (matching_vector); + return false; + } /* Presume the answer is yes. */ abfd->format = format; @@ -461,10 +491,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) of an archive. */ orig_messages = _bfd_set_error_handler_caching (&messages); - /* Locking is required here in order to manage _bfd_section_id. */ - if (!bfd_lock ()) - return false; - preserve_match.marker = NULL; if (!bfd_preserve_save (abfd, &preserve, NULL)) goto err_ret; @@ -545,6 +571,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) /* Change BFD's target temporarily. */ abfd->xvec = *target; + /* It is possible that targets appear multiple times in + bfd_target_vector. If this is the case, then we want to avoid + accumulating duplicate messages for a target in MESSAGES, so + discard any previous messages associated with this target. */ + clear_messages (&messages, abfd->xvec); + if (bfd_seek (abfd, 0, SEEK_SET) != 0) goto err_ret; @@ -754,7 +786,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) out: if (preserve_match.marker != NULL) bfd_preserve_finish (abfd, &preserve_match); - bfd_preserve_restore (abfd, &preserve); + if (preserve.marker != NULL) + bfd_preserve_restore (abfd, &preserve); _bfd_restore_error_handler_caching (orig_messages); print_and_clear_messages (&messages, PER_XVEC_NO_TARGET); bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL); diff --git a/bfd/i386aout.c b/bfd/i386aout.c index fb09597..082ebfb 100644 --- a/bfd/i386aout.c +++ b/bfd/i386aout.c @@ -79,7 +79,6 @@ static const struct aout_backend_data MY (backend_data) = MY (set_sizes), 1, /* Exec header not counted. */ 0, /* Add_dynamic_symbols. */ - 0, /* Add_one_symbol. */ 0, /* Link_dynamic_object. */ 0, /* Write_dynamic_symbol. */ 0, /* Check_dynamic_reloc. */ diff --git a/bfd/libaout.h b/bfd/libaout.h index ca4faec..7628d6a 100644 --- a/bfd/libaout.h +++ b/bfd/libaout.h @@ -177,13 +177,6 @@ struct aout_backend_data (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **); - /* Callback from the add symbols phase of the linker code to handle - adding a single symbol to the global linker hash table. */ - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, bool, bool, - struct bfd_link_hash_entry **); - /* Called to handle linking a dynamic object. */ bool (*link_dynamic_object) (struct bfd_link_info *, bfd *); diff --git a/bfd/pdp11.c b/bfd/pdp11.c index bdd9fc2..2d12033 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -2839,9 +2839,6 @@ aout_link_check_archive_element (bfd *abfd, static bool aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **); struct external_nlist *syms; bfd_size_type sym_count; char *strings; @@ -2875,10 +2872,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) return false; obj_aout_sym_hashes (abfd) = sym_hash; - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - p = syms; pend = p + sym_count; for (; p < pend; p++, sym_hash++) @@ -2951,7 +2944,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) break; } - if (! ((*add_one_symbol) + if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, string, copy, false, (struct bfd_link_hash_entry **) sym_hash))) return false; diff --git a/bfd/version.h b/bfd/version.h index 82120ff..177404d 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250409 +#define BFD_VERSION_DATE 20250423 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ |