* elflink.h (elf_link_add_object_symbols): Handle indirect and
authorIan Lance Taylor <ian@airs.com>
Fri, 1 Sep 1995 18:08:28 +0000 (18:08 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 1 Sep 1995 18:08:28 +0000 (18:08 +0000)
warning symbols.  If any section is named .gnu.warning.XXX, treat
the contents as a warning to be issued if the symbol XXX is
referenced.
(elf_link_output_extsym): For an indirect or warning symbol, just
output the symbol it points to.

bfd/ChangeLog
bfd/elflink.h

index c689d9dc8df0f0215fabd147a4cbc1afa8fa6795..02494db9cce8197f7555609c3f4a8860cf9b9f92 100644 (file)
@@ -1,3 +1,26 @@
+Fri Sep  1 13:20:25 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * elflink.h (elf_link_add_object_symbols): Handle indirect and
+       warning symbols.  If any section is named .gnu.warning.XXX, treat
+       the contents as a warning to be issued if the symbol XXX is
+       referenced.
+       (elf_link_output_extsym): For an indirect or warning symbol, just
+       output the symbol it points to.
+
+       * linker.c (_bfd_link_hash_newfunc): Don't bother to set bfd_error
+       if bfd_hash_allocate fails, since it will already be set.
+       (generic_link_hash_newfunc): Likewise.
+       (archive_hash_newfunc): Likewise.
+       (hash_entry_bfd): New static function.
+       (_bfd_generic_link_add_one_symbol): Pass new arguments to warning
+       callback.  Allocate a new warning using the hash table newfunc.
+       Use bfd_hash_replace to update the entry in the hash table, rather
+       than assuming we can copy the fields with structure assignment.
+
+       * hash.c (bfd_hash_replace): New function.
+       * bfd-in.h (bfd_hash_replace): Declare.
+       * bfd-in2.h: Rebuild.
+
 Fri Sep  1 08:12:50 1995  James G. Smith  <jsmith@beauty.cygnus.com>
 
        * config.bfd: Add mips*vr4300-*-elf* target.
index b625ae09b331aa6f9fe59385c778b14d8e61a315..ec12292f343c298161d6ae0c495a2a3a1e6c8b7f 100644 (file)
@@ -258,6 +258,52 @@ elf_link_add_object_symbols (abfd, info)
   add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook;
   collect = get_elf_backend_data (abfd)->collect;
 
+  /* As a GNU extension, any input sections which are named
+     .gnu.warning.SYMBOL are treated as warning symbols for the given
+     symbol.  This differs from .gnu.warning sections, which generate
+     warnings when they are included in an output file.  */
+  if (! info->shared)
+    {
+      asection *s;
+
+      for (s = abfd->sections; s != NULL; s = s->next)
+       {
+         const char *name;
+
+         name = bfd_get_section_name (abfd, s);
+         if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
+           {
+             char *msg;
+             bfd_size_type sz;
+
+             sz = bfd_section_size (abfd, s);
+             msg = (char *) bfd_alloc (abfd, sz);
+             if (msg == NULL)
+               {
+                 bfd_set_error (bfd_error_no_memory);
+                 goto error_return;
+               }
+
+             if (! bfd_get_section_contents (abfd, s, msg, (file_ptr) 0, sz))
+               goto error_return;
+
+             if (! (_bfd_generic_link_add_one_symbol
+                    (info, abfd, 
+                     name + sizeof ".gnu.warning." - 1,
+                     BSF_WARNING, s, (bfd_vma) 0, msg, false, collect,
+                     (struct bfd_link_hash_entry **) NULL)))
+               goto error_return;
+
+             if (! info->relocateable)
+               {
+                 /* Clobber the section size so that the warning does
+                     not get copied into the output file.  */
+                 s->_raw_size = 0;
+               }
+           }
+       }
+    }
+
   /* A stripped shared library might only have a dynamic symbol table,
      not a regular symbol table.  In that case we can still go ahead
      and link using the dynamic symbol table.  */
@@ -507,7 +553,7 @@ elf_link_add_object_symbols (abfd, info)
       asection *sec;
       flagword flags;
       const char *name;
-      struct elf_link_hash_entry *h = NULL;
+      struct elf_link_hash_entry *h;
       boolean definition;
       boolean new_weakdef;
 
@@ -607,6 +653,10 @@ elf_link_add_object_symbols (abfd, info)
            goto error_return;
          *sym_hash = h;
 
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
          /* If we are looking at a dynamic object, and this is a
             definition, we need to see if it has already been defined
             by some other object.  If it has, we want to use the
@@ -649,13 +699,19 @@ elf_link_add_object_symbols (abfd, info)
              false, collect, (struct bfd_link_hash_entry **) sym_hash)))
        goto error_return;
 
+      h = *sym_hash;
+      while (h->root.type == bfd_link_hash_indirect
+            || h->root.type == bfd_link_hash_warning)
+       h = (struct elf_link_hash_entry *) h->root.u.i.link;
+      *sym_hash = h;
+
       new_weakdef = false;
       if (dynamic
          && definition
          && (flags & BSF_WEAK) != 0
          && ELF_ST_TYPE (sym.st_info) != STT_FUNC
          && info->hash->creator->flavour == bfd_target_elf_flavour
-         && (*sym_hash)->weakdef == NULL)
+         && h->weakdef == NULL)
        {
          /* Keep a list of all weak defined non function symbols from
             a dynamic object, using the weakdef field.  Later in this
@@ -669,15 +725,15 @@ elf_link_add_object_symbols (abfd, info)
             dynamic object, and we will be using that previous
             definition anyhow.  */
 
-         (*sym_hash)->weakdef = weaks;
-         weaks = *sym_hash;
+         h->weakdef = weaks;
+         weaks = h;
          new_weakdef = true;
        }
 
       /* Get the alignment of a common symbol.  */
       if (sym.st_shndx == SHN_COMMON
-         && (*sym_hash)->root.type == bfd_link_hash_common)
-       (*sym_hash)->root.u.c.p->alignment_power = bfd_log2 (sym.st_value);
+         && h->root.type == bfd_link_hash_common)
+       h->root.u.c.p->alignment_power = bfd_log2 (sym.st_value);
 
       if (info->hash->creator->flavour == bfd_target_elf_flavour)
        {
@@ -2451,8 +2507,8 @@ elf_link_output_extsym (h, data)
 
     case bfd_link_hash_indirect:
     case bfd_link_hash_warning:
-      /* I have no idea how these should be handled.  */
-      return true;
+      return (elf_link_output_extsym
+             ((struct elf_link_hash_entry *) h->root.u.i.link, data));
     }
 
   /* If this symbol should be put in the .dynsym section, then put it