Tue Feb 18 17:22:59 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
[deliverable/binutils-gdb.git] / bfd / linker.c
index 5aae5459fd42ac76bc963e9ab388785d7a33557d..1b48f199fe3c10445487383ce603bc74fb7009ca 100644 (file)
@@ -406,9 +406,6 @@ SUBSUBSECTION
        file at the end of <<NAME(aout,final_link)>>.
 */
 
-static struct bfd_hash_entry *generic_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
-          const char *));
 static boolean generic_link_read_symbols
   PARAMS ((bfd *));
 static boolean generic_link_add_symbols
@@ -424,6 +421,7 @@ static boolean generic_link_check_archive_element
 static boolean generic_link_add_symbol_list
   PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
           boolean collect));
+static bfd *hash_entry_bfd PARAMS ((struct bfd_link_hash_entry *));
 static void set_symbol_from_hash
   PARAMS ((asymbol *, struct bfd_link_hash_entry *));
 static boolean generic_add_output_symbol
@@ -455,10 +453,7 @@ _bfd_link_hash_newfunc (entry, table, string)
     ret = ((struct bfd_link_hash_entry *)
           bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)));
   if (ret == (struct bfd_link_hash_entry *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct bfd_link_hash_entry *)
@@ -518,6 +513,88 @@ bfd_link_hash_lookup (table, string, create, copy, follow)
   return ret;
 }
 
+/* Look up a symbol in the main linker hash table if the symbol might
+   be wrapped.  This should only be used for references to an
+   undefined symbol, not for definitions of a symbol.  */
+
+struct bfd_link_hash_entry *
+bfd_wrapped_link_hash_lookup (abfd, info, string, create, copy, follow)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     const char *string;
+     boolean create;
+     boolean copy;
+     boolean follow;
+{
+  if (info->wrap_hash != NULL)
+    {
+      const char *l;
+
+      l = string;
+      if (*l == bfd_get_symbol_leading_char (abfd))
+       ++l;
+
+#undef WRAP
+#define WRAP "__wrap_"
+
+      if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
+       {
+         char *n;
+         struct bfd_link_hash_entry *h;
+
+         /* This symbol is being wrapped.  We want to replace all
+             references to SYM with references to __wrap_SYM.  */
+
+         n = (char *) bfd_malloc (strlen (l) + sizeof WRAP + 1);
+         if (n == NULL)
+           return NULL;
+
+         /* Note that symbol_leading_char may be '\0'.  */
+         n[0] = bfd_get_symbol_leading_char (abfd);
+         n[1] = '\0';
+         strcat (n, WRAP);
+         strcat (n, l);
+         h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
+         free (n);
+         return h;
+       }
+
+#undef WRAP
+
+#undef REAL
+#define REAL "__real_"
+
+      if (*l == '_'
+         && strncmp (l, REAL, sizeof REAL - 1) == 0
+         && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1,
+                             false, false) != NULL)
+       {
+         char *n;
+         struct bfd_link_hash_entry *h;
+
+         /* This is a reference to __real_SYM, where SYM is being
+             wrapped.  We want to replace all references to __real_SYM
+             with references to SYM.  */
+
+         n = (char *) bfd_malloc (strlen (l + sizeof REAL - 1) + 2);
+         if (n == NULL)
+           return NULL;
+
+         /* Note that symbol_leading_char may be '\0'.  */
+         n[0] = bfd_get_symbol_leading_char (abfd);
+         n[1] = '\0';
+         strcat (n, l + sizeof REAL - 1);
+         h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
+         free (n);
+         return h;
+       }
+
+#undef REAL
+    }
+
+  return bfd_link_hash_lookup (info->hash, string, create, copy, follow);
+}
+
 /* Traverse a generic link hash table.  The only reason this is not a
    macro is to do better type checking.  This code presumes that an
    argument passed as a struct bfd_hash_entry * may be caught as a
@@ -553,8 +630,8 @@ bfd_link_add_undef (table, h)
 \f
 /* Routine to create an entry in an generic link hash table.  */
 
-static struct bfd_hash_entry *
-generic_link_hash_newfunc (entry, table, string)
+struct bfd_hash_entry *
+_bfd_generic_link_hash_newfunc (entry, table, string)
      struct bfd_hash_entry *entry;
      struct bfd_hash_table *table;
      const char *string;
@@ -568,10 +645,7 @@ generic_link_hash_newfunc (entry, table, string)
     ret = ((struct generic_link_hash_entry *)
           bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)));
   if (ret == (struct generic_link_hash_entry *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct generic_link_hash_entry *)
@@ -597,14 +671,11 @@ _bfd_generic_link_hash_table_create (abfd)
   struct generic_link_hash_table *ret;
 
   ret = ((struct generic_link_hash_table *)
-        malloc (sizeof (struct generic_link_hash_table)));
-  if (!ret)
-      {
-       bfd_set_error (bfd_error_no_memory);
-       return (struct bfd_link_hash_table *) NULL;
-      }
+        bfd_alloc (abfd, sizeof (struct generic_link_hash_table)));
+  if (ret == NULL)
+    return (struct bfd_link_hash_table *) NULL;
   if (! _bfd_link_hash_table_init (&ret->root, abfd,
-                                  generic_link_hash_newfunc))
+                                  _bfd_generic_link_hash_newfunc))
     {
       free (ret);
       return (struct bfd_link_hash_table *) NULL;
@@ -633,10 +704,7 @@ generic_link_read_symbols (abfd)
        return false;
       abfd->outsymbols = (asymbol **) bfd_alloc (abfd, symsize);
       if (abfd->outsymbols == NULL && symsize != 0)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
       symcount = bfd_canonicalize_symtab (abfd, abfd->outsymbols);
       if (symcount < 0)
        return false;
@@ -770,10 +838,7 @@ archive_hash_newfunc (entry, table, string)
     ret = ((struct archive_hash_entry *)
           bfd_hash_allocate (table, sizeof (struct archive_hash_entry)));
   if (ret == (struct archive_hash_entry *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct archive_hash_entry *)
@@ -1196,16 +1261,21 @@ generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect)
          struct generic_link_hash_entry *h;
 
          name = bfd_asymbol_name (p);
-         if ((p->flags & BSF_INDIRECT) != 0
-             || bfd_is_ind_section (p->section))
-           string = bfd_asymbol_name ((asymbol *) p->value);
-         else if ((p->flags & BSF_WARNING) != 0)
+         if (((p->flags & BSF_INDIRECT) != 0
+              || bfd_is_ind_section (p->section))
+             && pp + 1 < ppend)
+           {
+             pp++;
+             string = bfd_asymbol_name (*pp);
+           }
+         else if ((p->flags & BSF_WARNING) != 0
+                  && pp + 1 < ppend)
            {
              /* The name of P is actually the warning string, and the
-                value is actually a pointer to the symbol to warn
-                about.  */
+                next symbol is the one to warn about.  */
              string = name;
-             name = bfd_asymbol_name ((asymbol *) p->value);
+             pp++;
+             name = bfd_asymbol_name (*pp);
            }
          else
            string = NULL;
@@ -1321,13 +1391,13 @@ enum link_action
 static const enum link_action link_action[8][8] =
 {
   /* current\prev    new    undef  undefw def    defw   com    indr   warn  */
-  /* UNDEF_ROW         */  {UND,   NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
+  /* UNDEF_ROW         */  {UND,   NOACT, UND,   REF,   REF,   NOACT, REFC,  WARNC },
   /* UNDEFW_ROW        */  {WEAK,  NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
   /* DEF_ROW   */  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MDEF,  CYCLE },
   /* DEFW_ROW  */  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE },
   /* COMMON_ROW        */  {COM,   COM,   COM,   CREF,  CREF,  BIG,   CREF,  WARNC },
   /* INDR_ROW  */  {IND,   IND,   IND,   MDEF,  IND,   CIND,  MIND,  CYCLE },
-  /* WARN_ROW   */  {MWARN, WARN,  WARN,  CWARN, CWARN, WARN,  CWARN, CYCLE },
+  /* WARN_ROW   */  {MWARN, WARN,  WARN,  CWARN, CWARN, WARN,  CWARN, MWARN },
   /* SET_ROW   */  {SET,   SET,   SET,   SET,   SET,   SET,   CYCLE, CYCLE }
 };
 
@@ -1354,6 +1424,30 @@ static const enum link_action link_action[8][8] =
    Adding an entry to a set does not count as a reference to a set,
    and no warning is issued (SET_ROW/warn).  */
 
+/* Return the BFD in which a hash entry has been defined, if known.  */
+
+static bfd *
+hash_entry_bfd (h)
+     struct bfd_link_hash_entry *h;
+{
+  while (h->type == bfd_link_hash_warning)
+    h = h->u.i.link;
+  switch (h->type)
+    {
+    default:
+      return NULL;
+    case bfd_link_hash_undefined:
+    case bfd_link_hash_undefweak:
+      return h->u.undef.abfd;
+    case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
+      return h->u.def.section->owner;
+    case bfd_link_hash_common:
+      return h->u.c.p->section->owner;
+    }
+  /*NOTREACHED*/
+}
+
 /* Add a symbol to the global hash table.
    ABFD is the BFD the symbol comes from.
    NAME is the name of the symbol.
@@ -1412,13 +1506,13 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
     row = DEF_ROW;
 
   if (hashp != NULL && *hashp != NULL)
-    {
-      h = *hashp;
-      BFD_ASSERT (strcmp (h->root.string, name) == 0);
-    }
+    h = *hashp;
   else
     {
-      h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
+      if (row == UNDEF_ROW || row == UNDEFW_ROW)
+       h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false);
+      else
+       h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
       if (h == NULL)
        {
          if (hashp != NULL)
@@ -1427,11 +1521,13 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
        }
     }
 
-  if (info->notice_hash != (struct bfd_hash_table *) NULL
-      && (bfd_hash_lookup (info->notice_hash, name, false, false)
-         != (struct bfd_hash_entry *) NULL))
+  if (info->notice_all
+      || (info->notice_hash != (struct bfd_hash_table *) NULL
+         && (bfd_hash_lookup (info->notice_hash, name, false, false)
+             != (struct bfd_hash_entry *) NULL)))
     {
-      if (! (*info->callbacks->notice) (info, name, abfd, section, value))
+      if (! (*info->callbacks->notice) (info, h->root.string, abfd, section,
+                                       value))
        return false;
     }
 
@@ -1471,7 +1567,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
             previously common.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, name,
+                (info, h->root.string,
                  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
                  abfd, bfd_link_hash_defined, (bfd_vma) 0)))
            return false;
@@ -1479,7 +1575,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
        case DEF:
        case DEFW:
          {
-           enum bfd_link_order_type oldtype;
+           enum bfd_link_hash_type oldtype;
 
            /* Define a symbol.  */
            oldtype = h->type;
@@ -1534,7 +1630,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
                        if (! ((*info->callbacks->constructor)
                               (info,
                                c == 'I' ? true : false,
-                               name, abfd, section, value)))
+                               h->root.string, abfd, section, value)))
                          return false;
                      }
                  }
@@ -1605,7 +1701,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
             two sizes.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, name,
+                (info, h->root.string,
                  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
                  abfd, bfd_link_hash_common, value)))
            return false;
@@ -1638,7 +1734,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
            else
              obfd = NULL;
            if (! ((*info->callbacks->multiple_common)
-                  (info, name, obfd, h->type, (bfd_vma) 0,
+                  (info, h->root.string, obfd, h->type, (bfd_vma) 0,
                    abfd, bfd_link_hash_common, value)))
              return false;
          }
@@ -1679,8 +1775,8 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
              break;
 
            if (! ((*info->callbacks->multiple_definition)
-                  (info, name, msec->owner, msec, mval, abfd, section,
-                   value)))
+                  (info, h->root.string, msec->owner, msec, mval, abfd,
+                   section, value)))
              return false;
          }
          break;
@@ -1689,7 +1785,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
          /* Create an indirect symbol from an existing common symbol.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, name,
+                (info, h->root.string,
                  h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
                  abfd, bfd_link_hash_indirect, (bfd_vma) 0)))
            return false;
@@ -1701,8 +1797,8 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
 
            /* STRING is the name of the symbol we want to indirect
               to.  */
-           inh = bfd_link_hash_lookup (info->hash, string, true, copy,
-                                       false);
+           inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true,
+                                               copy, false);
            if (inh == (struct bfd_link_hash_entry *) NULL)
              return false;
            if (inh->type == bfd_link_hash_new)
@@ -1737,7 +1833,10 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
          /* Issue a warning and cycle.  */
          if (h->u.i.warning != NULL)
            {
-             if (! (*info->callbacks->warning) (info, h->u.i.warning))
+             if (! (*info->callbacks->warning) (info, h->u.i.warning,
+                                                h->root.string, abfd,
+                                                (asection *) NULL,
+                                                (bfd_vma) 0))
                return false;
              /* Only issue a warning once.  */
              h->u.i.warning = NULL;
@@ -1759,7 +1858,9 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
 
        case WARN:
          /* Issue a warning.  */
-         if (! (*info->callbacks->warning) (info, string))
+         if (! (*info->callbacks->warning) (info, string, h->root.string,
+                                            hash_entry_bfd (h),
+                                            (asection *) NULL, (bfd_vma) 0))
            return false;
          break;
 
@@ -1771,7 +1872,10 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
             ensure this.  */
          if (h->next != NULL || info->hash->undefs_tail == h)
            {
-             if (! (*info->callbacks->warning) (info, string))
+             if (! (*info->callbacks->warning) (info, string, h->root.string,
+                                                hash_entry_bfd (h),
+                                                (asection *) NULL,
+                                                (bfd_vma) 0))
                return false;
              break;
            }
@@ -1783,27 +1887,33 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
 
            /* STRING is the warning to give.  */
            sub = ((struct bfd_link_hash_entry *)
-                  bfd_hash_allocate (&info->hash->table,
-                                     sizeof (struct bfd_link_hash_entry)));
-           if (!sub)
-             {
-               bfd_set_error (bfd_error_no_memory);
-               return false;
-             }
+                  ((*info->hash->table.newfunc)
+                   ((struct bfd_hash_entry *) NULL, &info->hash->table,
+                    h->root.string)));
+           if (sub == NULL)
+             return false;
            *sub = *h;
-           h->type = bfd_link_hash_warning;
-           h->u.i.link = sub;
+           sub->type = bfd_link_hash_warning;
+           sub->u.i.link = h;
            if (! copy)
-             h->u.i.warning = string;
+             sub->u.i.warning = string;
            else
              {
                char *w;
 
                w = bfd_hash_allocate (&info->hash->table,
                                       strlen (string) + 1);
+               if (w == NULL)
+                 return false;
                strcpy (w, string);
-               h->u.i.warning = w;
+               sub->u.i.warning = w;
              }
+
+           bfd_hash_replace (&info->hash->table,
+                             (struct bfd_hash_entry *) h,
+                             (struct bfd_hash_entry *) sub);
+           if (hashp != NULL)
+             *hashp = sub;
          }
          break;
        }
@@ -1830,6 +1940,12 @@ _bfd_generic_final_link (abfd, info)
   abfd->symcount = 0;
   outsymalloc = 0;
 
+  /* Mark all sections which will be included in the output file.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    for (p = o->link_order_head; p != NULL; p = p->next)
+      if (p->type == bfd_indirect_link_order)
+       p->u.indirect.section->linker_mark = true;
+
   /* Build the output symbol table.  */
   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
     if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc))
@@ -1873,12 +1989,9 @@ _bfd_generic_final_link (abfd, info)
                                                       input_section);
                  if (relsize < 0)
                    return false;
-                 relocs = (arelent **) malloc ((size_t) relsize);
+                 relocs = (arelent **) bfd_malloc ((size_t) relsize);
                  if (!relocs && relsize != 0)
-                   {
-                     bfd_set_error (bfd_error_no_memory);
-                     return false;
-                   }
+                   return false;
                  symbols = _bfd_generic_link_get_symbols (input_bfd);
                  reloc_count = bfd_canonicalize_reloc (input_bfd,
                                                        input_section,
@@ -1886,7 +1999,8 @@ _bfd_generic_final_link (abfd, info)
                                                        symbols);
                  if (reloc_count < 0)
                    return false;
-                 BFD_ASSERT (reloc_count == input_section->reloc_count);
+                 BFD_ASSERT ((unsigned long) reloc_count
+                             == input_section->reloc_count);
                  o->reloc_count += reloc_count;
                  free (relocs);
                }
@@ -1898,10 +2012,7 @@ _bfd_generic_final_link (abfd, info)
                                           (o->reloc_count
                                            * sizeof (arelent *))));
              if (!o->orelocation)
-               {
-                 bfd_set_error (bfd_error_no_memory);
-                 return false;
-               }
+               return false;
              o->flags |= SEC_RELOC;
              /* Reset the count so that it can be used as an index
                 when putting in the output relocs.  */
@@ -1957,16 +2068,10 @@ generic_add_output_symbol (output_bfd, psymalloc, sym)
        *psymalloc = 124;
       else
        *psymalloc *= 2;
-      if (output_bfd->outsymbols == (asymbol **) NULL)
-       newsyms = (asymbol **) malloc (*psymalloc * sizeof (asymbol *));
-      else
-       newsyms = (asymbol **) realloc (output_bfd->outsymbols,
-                                       *psymalloc * sizeof (asymbol *));
+      newsyms = (asymbol **) bfd_realloc (output_bfd->outsymbols,
+                                         *psymalloc * sizeof (asymbol *));
       if (newsyms == (asymbol **) NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
       output_bfd->outsymbols = newsyms;
     }
 
@@ -2056,6 +2161,11 @@ _bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc)
                  the relocs in the output format being used.  */
              h = NULL;
            }
+         else if (bfd_is_und_section (bfd_get_section (sym)))
+           h = ((struct generic_link_hash_entry *)
+                bfd_wrapped_link_hash_lookup (output_bfd, info,
+                                              bfd_asymbol_name (sym),
+                                              false, false, true));
          else
            h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
                                               bfd_asymbol_name (sym),
@@ -2120,10 +2230,11 @@ _bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc)
 
       /* This switch is straight from the old code in
         write_file_locals in ldsym.c.  */
-      if (info->strip == strip_some
-         && (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
-                              false, false)
-             == (struct bfd_hash_entry *) NULL))
+      if (info->strip == strip_all
+         || (info->strip == strip_some
+             && (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
+                                  false, false)
+                 == (struct bfd_hash_entry *) NULL)))
        output = false;
       else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
        {
@@ -2186,6 +2297,11 @@ _bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc)
       else
        abort ();
 
+      /* If this symbol is in a section which is not being included
+        in the output file, then we don't want to output the symbol.  */
+      if (sym->section->linker_mark == false)
+       output = false;
+
       if (output)
        {
          if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
@@ -2209,8 +2325,22 @@ set_symbol_from_hash (sym, h)
   switch (h->type)
     {
     default:
-    case bfd_link_hash_new:
       abort ();
+      break;
+    case bfd_link_hash_new:
+      /* This can happen when a constructor symbol is seen but we are
+         not building constructors.  */
+      if (sym->section != NULL)
+       {
+         BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0);
+       }
+      else
+       {
+         sym->flags |= BSF_CONSTRUCTOR;
+         sym->section = bfd_abs_section_ptr;
+         sym->value = 0;
+       }
+      break;
     case bfd_link_hash_undefined:
       sym->section = bfd_und_section_ptr;
       sym->value = 0;
@@ -2271,10 +2401,7 @@ _bfd_generic_link_write_global_symbol (h, data)
     return true;
 
   if (h->sym != (asymbol *) NULL)
-    {
-      sym = h->sym;
-      BFD_ASSERT (strcmp (bfd_asymbol_name (sym), h->root.root.string) == 0);
-    }
+    sym = h->sym;
   else
     {
       sym = bfd_make_empty_symbol (wginfo->output_bfd);
@@ -2316,10 +2443,7 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order)
 
   r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
   if (r == (arelent *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
       
   r->address = link_order->offset;
   r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
@@ -2336,9 +2460,10 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order)
     {
       struct generic_link_hash_entry *h;
 
-      h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
+      h = ((struct generic_link_hash_entry *)
+          bfd_wrapped_link_hash_lookup (abfd, info,
                                         link_order->u.reloc.p->u.name,
-                                        false, false, true);
+                                        false, false, true));
       if (h == (struct generic_link_hash_entry *) NULL
          || ! h->written)
        {
@@ -2366,10 +2491,7 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order)
       size = bfd_get_reloc_size (r->howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
       if (buf == (bfd_byte *) NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
       rstat = _bfd_relocate_contents (r->howto, abfd,
                                      link_order->u.reloc.p->addend, buf);
       switch (rstat)
@@ -2420,10 +2542,7 @@ bfd_new_link_order (abfd, section)
   new = ((struct bfd_link_order *)
         bfd_alloc_by_size_t (abfd, sizeof (struct bfd_link_order)));
   if (!new)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   new->type = bfd_undefined_link_order;
   new->offset = 0;
@@ -2489,12 +2608,9 @@ default_fill_link_order (abfd, info, sec, link_order)
   BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0);
 
   size = (size_t) link_order->size;
-  space = (char *) malloc (size);
+  space = (char *) bfd_malloc (size);
   if (space == NULL && size != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   fill = link_order->u.fill.value;
   for (i = 0; i < size; i += 2)
@@ -2545,7 +2661,11 @@ default_indirect_link_order (output_bfd, info, output_section, link_order,
         because somebody is attempting to link together different
         types of object files.  Handling this case correctly is
         difficult, and sometimes impossible.  */
-      abort ();
+      (*_bfd_error_handler)
+       ("Attempt to do relocateable link with %s input and %s output",
+        bfd_get_target (input_bfd), bfd_get_target (output_bfd));
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
     }
 
   if (! generic_linker)
@@ -2587,6 +2707,10 @@ default_indirect_link_order (output_bfd, info, output_section, link_order,
                 generic_link_add_symbol_list.  */
              if (sym->udata.p != NULL)
                h = (struct bfd_link_hash_entry *) sym->udata.p;
+             else if (bfd_is_und_section (bfd_get_section (sym)))
+               h = bfd_wrapped_link_hash_lookup (output_bfd, info,
+                                                 bfd_asymbol_name (sym),
+                                                 false, false, true);
              else
                h = bfd_link_hash_lookup (info->hash,
                                          bfd_asymbol_name (sym),
@@ -2598,12 +2722,10 @@ default_indirect_link_order (output_bfd, info, output_section, link_order,
     }
 
   /* Get and relocate the section contents.  */
-  contents = (bfd_byte *) malloc (bfd_section_size (input_bfd, input_section));
+  contents = ((bfd_byte *)
+             bfd_malloc (bfd_section_size (input_bfd, input_section)));
   if (contents == NULL && bfd_section_size (input_bfd, input_section) != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
   new_contents = (bfd_get_relocated_section_contents
                  (output_bfd, info, link_order, contents, info->relocateable,
                   _bfd_generic_link_get_symbols (input_bfd)));
This page took 0.061748 seconds and 4 git commands to generate.