Apply H.J.'s patch to revert change to elfxx-target.h
authorNick Clifton <nickc@redhat.com>
Fri, 24 Aug 2001 16:36:04 +0000 (16:36 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 24 Aug 2001 16:36:04 +0000 (16:36 +0000)
Apply my patch to allow SREC as output format.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elflink.h
bfd/elfxx-target.h
bfd/linker.c
include/ChangeLog
include/bfdlink.h

index 7e92107..25896d5 100644 (file)
@@ -1,3 +1,37 @@
+2001-08-24  Nick Clifton  <nickc@cambridge.redhat.com>
+
+       * 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  <hjl@gnu.org>
+
+       * 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  <aoliva@redhat.com>
 
        * bfd.c (bfd_alt_mach_code): New function.
index a048e6f..93e8e6d 100644 (file)
@@ -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)
 \f
 /* Constant information held for an ELF backend.  */
 
index d1aab9e..6077811 100644 (file)
--- 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;
 }
 \f
@@ -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.  */
index 8af57e8..c2bcc45 100644 (file)
@@ -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;
 
index a4c5e1d..2c7f095 100644 (file)
@@ -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
index 89b9526..d3a3343 100644 (file)
@@ -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);
 }
 
index 55f85ad..72b2311 100644 (file)
@@ -1,3 +1,11 @@
+2001-08-24  H.J. Lu  <hjl@gnu.org>
+
+       * 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  <jakub@redhat.com>
 
        * bfdlink.h (struct bfd_link_info): Add combreloc and
index 1dd2842..bfed980 100644 (file)
@@ -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
+  };
 \f
 /* 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