From 8ea2e4bd701102e0d30274c3c37f1ff60ccb3f1d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 24 Aug 2001 16:36:04 +0000 Subject: [PATCH] Apply H.J.'s patch to revert change to elfxx-target.h Apply my patch to allow SREC as output format. --- bfd/ChangeLog | 34 +++++++++++++++++++ bfd/elf-bfd.h | 4 +++ bfd/elf.c | 18 ++++++++-- bfd/elflink.h | 84 ++++++++++++++++++++++++++++++---------------- bfd/elfxx-target.h | 13 +++++-- bfd/linker.c | 2 ++ include/ChangeLog | 8 +++++ include/bfdlink.h | 11 ++++++ 8 files changed, 140 insertions(+), 34 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7e92107068d..25896d5bf00 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,37 @@ +2001-08-24 Nick Clifton + + * elf-bfd.h (elf_hash_table): Revert definition. + (is_elf_hash_table): New macro. + * elflink.h (elf_link_add_object_symbols): Test + is_elf_hash_table before accessing ELF only fields in hash + structure. + (elf_link_create_dynamic_sections): Fail if not using an ELF + hash structure. + (elf_add_dynamic_entry): Fail if not using an ELF hash + structure. + (elf_link_record_local_dynamic_symbol): Fail if not using an + ELF hash structure. + (size_dynamic_sections): Fail if not using an ELF hash + structure. + (elf_adjust_dynamic_symbol): Fail if not using an ELF + hash structure. + (elf_bfd_final_link): Fail if not using an ELF hash + structure. + +2001-08-24 H.J. Lu + + * elf-bfd.h (elf_hash_table): Return NULL if the linker hash + table is not an ELF linker hash table. + + * elf.c (_bfd_elf_link_hash_table_init): Set the linker hash + table type to bfd_link_elf_hash_table. + + * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_create): Revert + the last change. + + * linker.c (_bfd_link_hash_table_init): Set the linker hash + table type to bfd_link_generic_hash_table. + 2001-08-24 Alexandre Oliva * bfd.c (bfd_alt_mach_code): New function. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index a048e6f5f43..93e8e6d3dfe 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -273,6 +273,10 @@ struct elf_link_hash_table /* Get the ELF linker hash table from a link_info structure. */ #define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash)) + +/* Returns true if the hash table is a struct elf_link_hash_table. */ +#define is_elf_hash_table(p) \ + ((p)->hash->type == bfd_link_elf_hash_table) /* Constant information held for an ELF backend. */ diff --git a/bfd/elf.c b/bfd/elf.c index d1aab9e2f9a..60778115618 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -571,8 +571,15 @@ _bfd_elf_merge_sections (abfd, info) bfd *abfd; struct bfd_link_info *info; { - if (elf_hash_table (info)->merge_info) - _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info); + struct elf_link_hash_table * hash_table; + + hash_table = elf_hash_table (info); + + if (hash_table == NULL) + return false; + + if (hash_table->merge_info) + _bfd_merge_sections (abfd, hash_table->merge_info); return true; } @@ -1047,6 +1054,8 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc) struct bfd_hash_table *, const char *)); { + boolean ret; + table->dynamic_sections_created = false; table->dynobj = NULL; /* The first dynamic symbol is a dummy. */ @@ -1059,7 +1068,10 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc) table->stab_info = NULL; table->merge_info = NULL; table->dynlocal = NULL; - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); + ret = _bfd_link_hash_table_init (& table->root, abfd, newfunc); + table->root.type = bfd_link_elf_hash_table; + + return ret; } /* Create an ELF linker hash table. */ diff --git a/bfd/elflink.h b/bfd/elflink.h index 8af57e824ee..c2bcc45c368 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -916,6 +916,9 @@ elf_link_add_object_symbols (abfd, info) Elf_External_Sym *esymend; struct elf_backend_data *bed; boolean dt_needed; + struct elf_link_hash_table * hash_table; + + hash_table = elf_hash_table (info); bed = get_elf_backend_data (abfd); add_symbol_hook = bed->elf_add_symbol_hook; @@ -970,7 +973,7 @@ elf_link_add_object_symbols (abfd, info) { struct elf_link_hash_entry *h; - h = elf_link_hash_lookup (elf_hash_table (info), name, + h = elf_link_hash_lookup (hash_table, name, false, false, true); /* FIXME: What about bfd_link_hash_common? */ @@ -1085,13 +1088,16 @@ elf_link_add_object_symbols (abfd, info) format. FIXME: If there are no input BFD's of the same format as the output, we can't make a shared library. */ if (info->shared - && ! elf_hash_table (info)->dynamic_sections_created + && is_elf_hash_table (info) + && ! hash_table->dynamic_sections_created && abfd->xvec == info->hash->creator) { if (! elf_link_create_dynamic_sections (abfd, info)) goto error_return; } } + else if (! is_elf_hash_table (info)) + goto error_return; else { asection *s; @@ -1194,7 +1200,7 @@ elf_link_add_object_symbols (abfd, info) n->name = anm; n->by = abfd; n->next = NULL; - for (pn = &elf_hash_table (info)->needed; + for (pn = & hash_table->needed; *pn != NULL; pn = &(*pn)->next) ; @@ -1209,8 +1215,8 @@ elf_link_add_object_symbols (abfd, info) to clear runpath. Do _NOT_ bfd_release, as that frees all more recently bfd_alloc'd blocks as well. */ - if (rpath && elf_hash_table (info)->runpath) - elf_hash_table (info)->runpath = NULL; + if (rpath && hash_table->runpath) + hash_table->runpath = NULL; n = ((struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); @@ -1225,7 +1231,7 @@ elf_link_add_object_symbols (abfd, info) n->name = anm; n->by = abfd; n->next = NULL; - for (pn = &elf_hash_table (info)->runpath; + for (pn = & hash_table->runpath; *pn != NULL; pn = &(*pn)->next) ; @@ -1252,7 +1258,7 @@ elf_link_add_object_symbols (abfd, info) n->name = anm; n->by = abfd; n->next = NULL; - for (pn = &elf_hash_table (info)->runpath; + for (pn = & hash_table->runpath; *pn != NULL; pn = &(*pn)->next) ; @@ -1277,22 +1283,20 @@ elf_link_add_object_symbols (abfd, info) /* If this is the first dynamic object found in the link, create the special sections required for dynamic linking. */ - if (! elf_hash_table (info)->dynamic_sections_created) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } + if (! hash_table->dynamic_sections_created) + if (! elf_link_create_dynamic_sections (abfd, info)) + goto error_return; if (add_needed) { /* Add a DT_NEEDED entry for this dynamic object. */ - oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name, + oldsize = _bfd_stringtab_size (hash_table->dynstr); + strindex = _bfd_stringtab_add (hash_table->dynstr, name, true, false); if (strindex == (bfd_size_type) -1) goto error_return; - if (oldsize == _bfd_stringtab_size (elf_hash_table (info)->dynstr)) + if (oldsize == _bfd_stringtab_size (hash_table->dynstr)) { asection *sdyn; Elf_External_Dyn *dyncon, *dynconend; @@ -1302,8 +1306,7 @@ elf_link_add_object_symbols (abfd, info) have already included this dynamic object in the link, just ignore it. There is no reason to include a particular dynamic object more than once. */ - sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj, - ".dynamic"); + sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); BFD_ASSERT (sdyn != NULL); dyncon = (Elf_External_Dyn *) sdyn->contents; @@ -1313,8 +1316,7 @@ elf_link_add_object_symbols (abfd, info) { Elf_Internal_Dyn dyn; - elf_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon, - &dyn); + elf_swap_dyn_in (hash_table->dynobj, dyncon, & dyn); if (dyn.d_tag == DT_NEEDED && dyn.d_un.d_val == strindex) { @@ -1969,25 +1971,28 @@ elf_link_add_object_symbols (abfd, info) bfd_size_type oldsize; bfd_size_type strindex; + if (! is_elf_hash_table (info)) + goto error_return; + /* The symbol from a DT_NEEDED object is referenced from the regular object to create a dynamic executable. We have to make sure there is a DT_NEEDED entry for it. */ dt_needed = false; - oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, + oldsize = _bfd_stringtab_size (hash_table->dynstr); + strindex = _bfd_stringtab_add (hash_table->dynstr, elf_dt_soname (abfd), true, false); if (strindex == (bfd_size_type) -1) goto error_return; if (oldsize - == _bfd_stringtab_size (elf_hash_table (info)->dynstr)) + == _bfd_stringtab_size (hash_table->dynstr)) { asection *sdyn; Elf_External_Dyn *dyncon, *dynconend; - sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj, + sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); BFD_ASSERT (sdyn != NULL); @@ -1998,7 +2003,7 @@ elf_link_add_object_symbols (abfd, info) { Elf_Internal_Dyn dyn; - elf_swap_dyn_in (elf_hash_table (info)->dynobj, + elf_swap_dyn_in (hash_table->dynobj, dyncon, &dyn); BFD_ASSERT (dyn.d_tag != DT_NEEDED || dyn.d_un.d_val != strindex); @@ -2155,6 +2160,7 @@ elf_link_add_object_symbols (abfd, info) && ! info->relocateable && ! info->traditional_format && info->hash->creator->flavour == bfd_target_elf_flavour + && is_elf_hash_table (info) && (info->strip != strip_all && info->strip != strip_debugger)) { asection *stab, *stabstr; @@ -2170,7 +2176,7 @@ elf_link_add_object_symbols (abfd, info) secdata = elf_section_data (stab); if (! _bfd_link_section_stabs (abfd, - &elf_hash_table (info)->stab_info, + & hash_table->stab_info, stab, stabstr, &secdata->stab_info)) goto error_return; @@ -2178,15 +2184,15 @@ elf_link_add_object_symbols (abfd, info) } } - if (! info->relocateable && ! dynamic) + if (! info->relocateable && ! dynamic + && is_elf_hash_table (info)) { asection *s; for (s = abfd->sections; s != NULL; s = s->next) if ((s->flags & SEC_MERGE) - && ! _bfd_merge_section (abfd, - &elf_hash_table (info)->merge_info, - s, &elf_section_data (s)->merge_info)) + && ! _bfd_merge_section (abfd, & hash_table->merge_info, s, + & elf_section_data (s)->merge_info)) goto error_return; } @@ -2219,6 +2225,9 @@ elf_link_create_dynamic_sections (abfd, info) struct elf_link_hash_entry *h; struct elf_backend_data *bed; + if (! is_elf_hash_table (info)) + return false; + if (elf_hash_table (info)->dynamic_sections_created) return true; @@ -2343,6 +2352,9 @@ elf_add_dynamic_entry (info, tag, val) size_t newsize; bfd_byte *newcontents; + if (! is_elf_hash_table (info)) + return false; + dynobj = elf_hash_table (info)->dynobj; s = bfd_get_section_by_name (dynobj, ".dynamic"); @@ -2379,6 +2391,9 @@ elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx) unsigned long dynstr_index; char *name; + if (! is_elf_hash_table (info)) + return false; + /* See if the entry exists already. */ for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) if (entry->input_bfd == input_bfd && entry->input_indx == input_indx) @@ -2895,6 +2910,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, if (info->hash->creator->flavour != bfd_target_elf_flavour) return true; + if (! is_elf_hash_table (info)) + return false; + /* The backend may have to create some sections regardless of whether we're dynamic or not. */ bed = get_elf_backend_data (output_bfd); @@ -3542,12 +3560,14 @@ elf_fix_symbol_flags (h, eif) backend specifically; we can't just clear PLT-related data here. */ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0 && eif->info->shared + && is_elf_hash_table (eif->info) && (eif->info->symbolic || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) { struct elf_backend_data *bed; + bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) @@ -3602,6 +3622,9 @@ elf_adjust_dynamic_symbol (h, data) if (h->root.type == bfd_link_hash_indirect) return true; + if (! is_elf_hash_table (eif->info)) + return false; + /* Fix the symbol flags. */ if (! elf_fix_symbol_flags (h, eif)) return false; @@ -4512,6 +4535,9 @@ elf_bfd_final_link (abfd, info) size_t relativecount = 0; asection *reldyn = 0; + if (! is_elf_hash_table (info)) + return false; + if (info->shared) abfd->flags |= DYNAMIC; diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index a4c5e1d94bf..2c7f0956eb2 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -162,11 +162,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ _bfd_elf_canonicalize_dynamic_reloc #endif +#ifdef elf_backend_relocate_section #ifndef bfd_elfNN_bfd_link_hash_table_create #define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create #endif -#ifndef elf_backend_relocate_section -/* If no backend relocate_section routine, use the generic linker. */ +#else /* ! defined (elf_backend_relocate_section) */ +/* If no backend relocate_section routine, use the generic linker. + Note - this will prevent the port from being able to use some of + the other features of the ELF linker, because the generic hash structure + does not have the fields needed by the ELF linker. In particular it + means that linking directly to S-records will not work. */ +#ifndef bfd_elfNN_bfd_link_hash_table_create +#define bfd_elfNN_bfd_link_hash_table_create \ + _bfd_generic_link_hash_table_create +#endif #ifndef bfd_elfNN_bfd_link_add_symbols #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols #endif diff --git a/bfd/linker.c b/bfd/linker.c index 89b95269154..d3a334350c7 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -483,6 +483,8 @@ _bfd_link_hash_table_init (table, abfd, newfunc) table->creator = abfd->xvec; table->undefs = NULL; table->undefs_tail = NULL; + table->type = bfd_link_generic_hash_table; + return bfd_hash_table_init (&table->table, newfunc); } diff --git a/include/ChangeLog b/include/ChangeLog index 55f85ad061a..72b2311dfca 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,11 @@ +2001-08-24 H.J. Lu + + * bfdlink.h (bfd_link_hash_table_type): New. The linker hash + table type, bfd_link_generic_hash_table and + bfd_link_elf_hash_table. + (bfd_link_hash_table): Add a new field, type, for the linker + hash table type. + 2001-08-23 Jakub Jelinek * bfdlink.h (struct bfd_link_info): Add combreloc and diff --git a/include/bfdlink.h b/include/bfdlink.h index 1dd2842382d..bfed980f64c 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -41,6 +41,15 @@ enum bfd_link_discard discard_l, /* Discard local temporary symbols. */ discard_all /* Discard all locals. */ }; + +/* Describes the type of hash table entry structure being used. + Different hash table structure have different fields and so + support different linking features. */ +enum bfd_link_hash_table_type + { + bfd_link_generic_hash_table, + bfd_link_elf_hash_table + }; /* These are the possible types of an entry in the BFD link hash table. */ @@ -146,6 +155,8 @@ struct bfd_link_hash_table struct bfd_link_hash_entry *undefs; /* Entries are added to the tail of the undefs list. */ struct bfd_link_hash_entry *undefs_tail; + /* The type of the ink hash table. */ + enum bfd_link_hash_table_type type; }; /* Look up an entry in a link hash table. If FOLLOW is true, this -- 2.30.2