OSDN Git Service

bfd/
authoramodra <amodra>
Sun, 30 Sep 2007 13:32:59 +0000 (13:32 +0000)
committeramodra <amodra>
Sun, 30 Sep 2007 13:32:59 +0000 (13:32 +0000)
* elflink.c (resolve_symbol): Handle symbols in SEC_MERGE
sections.  Don't test symbol st_shndx.  Don't bother with
bfd_link_hash_common symbols.  Print longs rather than ints
in debug messages.
(eval_symbol): Replace "sym" and "advanced" params with "symp".
Replace "addr" and "section_offset" params with "dot".  Don't
cast bfd_vma values to signed, cast them to bfd_signed_vma.
(bfd_elf_perform_complex_relocation): Delete "output_bfd", "info",
"local_syms" and "local_sections" params.  Add "relocation".
Delete code calculating relocation value.
(evaluate_complex_relocation_symbols): Delete function.  Fold into..
(elf_link_input_bfd): ..existing code examining relocs.
* elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype.
* elf32-mep.c (mep_elf_check_relocs): Delete function.
(mep_elf_gc_sweep_hook, mep_elf_gc_mark_hook): Likewise.
(mep_elf_object_p): Don't set elf_bad_symtab.
(elf_backend_check_relocs): Don't define.
(elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): Likewise.
(elf_backend_can_gc_sections, USE_RELA): Likwise.
(mep_elf_relocate_section): Move bfd_elf_perform_complex_relocation
call after we have calculated reloc value.  Delete local sym
debug code.  Use RELOC_FOR_GLOBAL_SYMBOL.  Delete addend
adjusting code..
(elf_backend_rela_normal): ..instead define this.
ld/testsuite/
* ld-selective/sel-dump.exp: Add am33, m88k, mep to xfails.
* ld-selective/selective.exp: Don't run for same target list
we xfail sel-dump.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-mep.c
bfd/elflink.c
ld/testsuite/ChangeLog
ld/testsuite/ld-selective/sel-dump.exp
ld/testsuite/ld-selective/selective.exp

index 3d0777f..95a31df 100644 (file)
@@ -1,3 +1,30 @@
+2007-09-29  Alan Modra  <amodra@bigpond.net.au>
+
+       * elflink.c (resolve_symbol): Handle symbols in SEC_MERGE
+       sections.  Don't test symbol st_shndx.  Don't bother with
+       bfd_link_hash_common symbols.  Print longs rather than ints
+       in debug messages.
+       (eval_symbol): Replace "sym" and "advanced" params with "symp".
+       Replace "addr" and "section_offset" params with "dot".  Don't
+       cast bfd_vma values to signed, cast them to bfd_signed_vma.
+       (bfd_elf_perform_complex_relocation): Delete "output_bfd", "info",
+       "local_syms" and "local_sections" params.  Add "relocation".
+       Delete code calculating relocation value.
+       (evaluate_complex_relocation_symbols): Delete function.  Fold into..
+       (elf_link_input_bfd): ..existing code examining relocs.
+       * elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype.
+       * elf32-mep.c (mep_elf_check_relocs): Delete function.
+       (mep_elf_gc_sweep_hook, mep_elf_gc_mark_hook): Likewise.
+       (mep_elf_object_p): Don't set elf_bad_symtab.
+       (elf_backend_check_relocs): Don't define.
+       (elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): Likewise.
+       (elf_backend_can_gc_sections, USE_RELA): Likwise.
+       (mep_elf_relocate_section): Move bfd_elf_perform_complex_relocation
+       call after we have calculated reloc value.  Delete local sym
+       debug code.  Use RELOC_FOR_GLOBAL_SYMBOL.  Delete addend
+       adjusting code..
+       (elf_backend_rela_normal): ..instead define this.
+
 2007-09-28  Alan Modra  <amodra@bigpond.net.au>
 
        * elf-m10300.c (mn10300_elf_check_relocs): Delete dead code.
index d8d81df..a707cef 100644 (file)
@@ -1814,14 +1814,7 @@ extern bfd_boolean bfd_elf_match_symbols_in_sections
   (asection *, asection *, struct bfd_link_info *);
 
 extern void bfd_elf_perform_complex_relocation
-  (bfd *                   output_bfd ATTRIBUTE_UNUSED,
-   struct bfd_link_info *  info,
-   bfd *                   input_bfd,
-   asection *              input_section,
-   bfd_byte *              contents,
-   Elf_Internal_Rela *     rel,
-   Elf_Internal_Sym *      local_syms,
-   asection **             local_sections);
+  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma);
 
 extern bfd_boolean _bfd_elf_setup_sections
   (bfd *);
index d1ee6a9..e5d33ca 100644 (file)
@@ -402,48 +402,6 @@ mep_info_to_howto_rela
   r_type = ELF32_R_TYPE (dst->r_info);
   cache_ptr->howto = & mep_elf_howto_table [r_type];
 }
-
-/* Look through the relocs for a section during the first phase.
-   Since we don't do .gots or .plts, we just need to consider the
-   virtual table relocs for gc.  */
-
-static bfd_boolean
-mep_elf_check_relocs
-    (bfd *                     abfd,
-     struct bfd_link_info *    info,
-     asection *                sec,
-     const Elf_Internal_Rela * relocs)
-{
-  Elf_Internal_Shdr *           symtab_hdr;
-  struct elf_link_hash_entry ** sym_hashes;
-  struct elf_link_hash_entry ** sym_hashes_end;
-  const Elf_Internal_Rela *     rel;
-  const Elf_Internal_Rela *     rel_end;
-
-  if (info->relocatable)
-    return TRUE;
-
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
-
-  rel_end = relocs + sec->reloc_count;
-  for (rel = relocs; rel < rel_end; rel++)
-    {
-      struct elf_link_hash_entry *h;
-      unsigned long r_symndx;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx < symtab_hdr->sh_info)
-        h = NULL;
-      else
-        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-    }
-  return TRUE;
-}
-
 \f
 /* Relocate a MEP ELF section.
    There is some attempt to make this function usable for many architectures,
@@ -513,18 +471,7 @@ mep_elf_relocate_section
       int                          r_type;
 
       r_type = ELF32_R_TYPE (rel->r_info);
-
       r_symndx = ELF32_R_SYM (rel->r_info);
-
-      /* Is this a complex relocation?  */
-      if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC)
-       {
-         bfd_elf_perform_complex_relocation (output_bfd, info,
-                                             input_bfd, input_section, contents,
-                                             rel, local_syms, local_sections);
-         continue;
-       }
-
       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
@@ -539,56 +486,17 @@ mep_elf_relocate_section
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
-#if 0
-         fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
-                  sec->name, name, sym->st_name,
-                  sec->output_section->vma, sec->output_offset,
-                  sym->st_value, rel->r_addend);
-#endif
        }
       else
        {
-         relocation = 0;
-         h = sym_hashes [r_symndx];
+         bfd_boolean warned, unresolved_reloc;
 
-         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;
+         RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
+                                 r_symndx, symtab_hdr, sym_hashes,
+                                 h, sec, relocation,
+                                 unresolved_reloc, warned);
 
          name = h->root.root.string;
-
-         if (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-           {
-             sec = h->root.u.def.section;
-             relocation = (h->root.u.def.value
-                           + sec->output_section->vma
-                           + sec->output_offset);
-#if 0
-             fprintf (stderr,
-                      "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
-                      sec->name, name, h->root.u.def.value,
-                      sec->output_section->vma, sec->output_offset, relocation);
-#endif
-           }
-         else if (h->root.type == bfd_link_hash_undefweak)
-           {
-#if 0
-             fprintf (stderr, "undefined: sec: %s, name: %s\n",
-                      sec->name, name);
-#endif
-           }
-         else if (!info->relocatable)
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset,
-                     (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
-               return FALSE;
-#if 0
-             fprintf (stderr, "unknown: name: %s\n", name);
-#endif
-           }
        }
 
       if (sec != NULL && elf_discarded_section (sec))
@@ -603,18 +511,15 @@ mep_elf_relocate_section
        }
 
       if (info->relocatable)
-       {
-         /* This is a relocatable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-         if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-           rel->r_addend += sec->output_offset;
-         continue;
-       }
+       continue;
 
       switch (r_type)
        {
+       case R_RELC:
+         bfd_elf_perform_complex_relocation (input_bfd, input_section,
+                                             contents, rel, relocation);
+         continue;
+
        default:
          r = mep_final_link_relocate (howto, input_bfd, input_section,
                                         contents, rel, relocation);
@@ -676,63 +581,6 @@ mep_elf_relocate_section
   return TRUE;
 }
 \f
-
-/* Update the got entry reference counts for the section being
-   removed.  */
-
-static bfd_boolean
-mep_elf_gc_sweep_hook
-    (bfd *                     abfd ATTRIBUTE_UNUSED,
-     struct bfd_link_info *    info ATTRIBUTE_UNUSED,
-     asection *                sec ATTRIBUTE_UNUSED,
-     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
-{
-  return TRUE;
-}
-
-/* Return the section that should be marked against GC for a given
-   relocation.  */
-
-static asection *
-mep_elf_gc_mark_hook
-    (asection *                   sec,
-     struct bfd_link_info *       info ATTRIBUTE_UNUSED,
-     Elf_Internal_Rela *          rel,
-     struct elf_link_hash_entry * h,
-     Elf_Internal_Sym *           sym)
-{
-  if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-       default:
-         switch (h->root.type)
-           {
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-
-           default:
-             break;
-           }
-       }
-    }
-  else
-    {
-      if (!(elf_bad_symtab (sec->owner)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-    }
-
-  return NULL;
-}
-
-\f
 /* Function to set the ELF flag bits.  */
 
 static bfd_boolean
@@ -899,11 +747,6 @@ elf32_mep_machine (bfd * abfd)
 static bfd_boolean
 mep_elf_object_p (bfd * abfd)
 {
-  /* Irix 5 and 6 is broken.  Object file symbol tables are not always
-     sorted correctly such that local symbols preceed global symbols,
-     and the sh_info field in the symbol table is not always right.  */
-  /* This is needed for the RELC support code.  */
-  elf_bad_symtab (abfd) = TRUE;
   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
   return TRUE;
 }
@@ -940,23 +783,17 @@ mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
 #define elf_info_to_howto_rel                  NULL
 #define elf_info_to_howto                      mep_info_to_howto_rela
 #define elf_backend_relocate_section           mep_elf_relocate_section
-#define elf_backend_gc_mark_hook               mep_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook              mep_elf_gc_sweep_hook
-#define elf_backend_check_relocs                mep_elf_check_relocs
 #define elf_backend_object_p                   mep_elf_object_p
 #define elf_backend_section_flags              mep_elf_section_flags
 #define elf_backend_fake_sections              mep_elf_fake_sections
 
-#define elf_backend_can_gc_sections            1
-
 #define bfd_elf32_bfd_reloc_type_lookup                mep_reloc_type_lookup
-#define bfd_elf32_bfd_reloc_name_lookup        mep_reloc_name_lookup
+#define bfd_elf32_bfd_reloc_name_lookup                mep_reloc_name_lookup
 #define bfd_elf32_bfd_set_private_flags                mep_elf_set_private_flags
 #define bfd_elf32_bfd_copy_private_bfd_data    mep_elf_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   mep_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_print_private_bfd_data   mep_elf_print_private_bfd_data
 
-/* We use only the RELA entries.  */
-#define USE_RELA
+#define elf_backend_rela_normal                        1
 
 #include "elf32-target.h"
index ce59c3a..cac22b7 100644 (file)
@@ -7281,7 +7281,6 @@ resolve_symbol (const char *                  name,
   struct bfd_link_hash_entry *  global_entry;
   const char *                  candidate = NULL;
   Elf_Internal_Shdr *           symtab_hdr;
-  asection *                    sec = NULL;
   size_t                        i;
   
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
@@ -7289,7 +7288,6 @@ resolve_symbol (const char *                  name,
   for (i = 0; i < locsymcount; ++ i)
     {
       sym = isymbuf + i;
-      sec = finfo->sections [i];
 
       if (ELF_ST_BIND (sym->st_info) != STB_LOCAL)
        continue;
@@ -7298,26 +7296,18 @@ resolve_symbol (const char *                  name,
                                                   symtab_hdr->sh_link,
                                                   sym->st_name);
 #ifdef DEBUG
-      printf ("Comparing string: '%s' vs. '%s' = 0x%x\n", 
-             name, candidate, (unsigned int)sym->st_value);
+      printf ("Comparing string: '%s' vs. '%s' = 0x%lx\n",
+             name, candidate, (unsigned long) sym->st_value);
 #endif
       if (candidate && strcmp (candidate, name) == 0)
        {
-         * result = sym->st_value;
+         asection *sec = finfo->sections [i];
 
-         if (sym->st_shndx > SHN_UNDEF && 
-             sym->st_shndx < SHN_LORESERVE)
-           {
-#ifdef DEBUG
-             printf ("adjusting for sec '%s' @ 0x%x + 0x%x\n",
-                     sec->output_section->name, 
-                     (unsigned int)sec->output_section->vma, 
-                     (unsigned int)sec->output_offset);
-#endif
-             * result += sec->output_offset + sec->output_section->vma;
-           }
+         *result = _bfd_elf_rel_local_sym (input_bfd, sym, &sec, 0);
+         *result += sec->output_offset + sec->output_section->vma;
 #ifdef DEBUG
-         printf ("Found symbol with effective value %8.8x\n", (unsigned int)* result);
+         printf ("Found symbol with value %8.8lx\n",
+                 (unsigned long) *result);
 #endif
          return TRUE;
        }
@@ -7335,24 +7325,12 @@ resolve_symbol (const char *                  name,
        + global_entry->u.def.section->output_section->vma 
        + global_entry->u.def.section->output_offset;
 #ifdef DEBUG
-      printf ("Found GLOBAL symbol '%s' with value %8.8x\n",
-             global_entry->root.string, (unsigned int)*result);
+      printf ("Found GLOBAL symbol '%s' with value %8.8lx\n",
+             global_entry->root.string, (unsigned long) *result);
 #endif
       return TRUE;
     } 
 
-  if (global_entry->type == bfd_link_hash_common)
-    {
-      *result = global_entry->u.def.value +
-       bfd_com_section_ptr->output_section->vma +
-       bfd_com_section_ptr->output_offset;
-#ifdef DEBUG
-      printf ("Found COMMON symbol '%s' with value %8.8x\n",
-             global_entry->root.string, (unsigned int)*result);
-#endif
-      return TRUE;
-    }
-  
   return FALSE;
 }
 
@@ -7402,12 +7380,10 @@ undefined_reference (const char *  reftype,
 
 static bfd_boolean
 eval_symbol (bfd_vma *                     result,
-            char *                        sym,
-            char **                       advanced,
+            const char **                 symp,
             bfd *                         input_bfd,
             struct elf_final_link_info *  finfo,
-            bfd_vma                       addr,
-            bfd_vma                       section_offset,
+            bfd_vma                       dot,
             Elf_Internal_Sym *            isymbuf,
             size_t                        locsymcount,
             int                           signed_p)
@@ -7418,6 +7394,7 @@ eval_symbol (bfd_vma *                     result,
   bfd_vma       b;
   const int     bufsz = 4096;
   char          symbuf [bufsz];
+  const char *sym = *symp;
   const char *  symend;
   bfd_boolean   symbol_is_section = FALSE;
 
@@ -7433,21 +7410,21 @@ eval_symbol (bfd_vma *                     result,
   switch (* sym)
     {
     case '.':
-      * result = addr + section_offset;
-      * advanced = sym + 1;
+      *result = dot;
+      *symp = sym + 1;
       return TRUE;
 
     case '#':
-      ++ sym;
-      * result = strtoul (sym, advanced, 16);
+      ++sym;
+      *result = strtoul (sym, (char **) symp, 16);
       return TRUE;
 
     case 'S':
       symbol_is_section = TRUE;
     case 's':      
-      ++ sym;
-      symlen = strtol (sym, &sym, 10);
-      ++ sym; /* Skip the trailing ':'.  */
+      ++sym;
+      symlen = strtol (sym, (char **) symp, 10);
+      sym = *symp + 1; /* Skip the trailing ':'.  */
 
       if ((symend < sym) || ((symlen + 1) > bufsz))
        {
@@ -7457,7 +7434,7 @@ eval_symbol (bfd_vma *                     result,
 
       memcpy (symbuf, sym, symlen);
       symbuf [symlen] = '\0';
-      * advanced = sym + symlen;
+      *symp = sym + symlen;
       
       /* Is it always possible, with complex symbols, that gas "mis-guessed" 
         the symbol as a section, or vice-versa. so we're pretty liberal in our
@@ -7496,15 +7473,14 @@ eval_symbol (bfd_vma *                     result,
       sym += strlen (#op);                                     \
       if (* sym == ':')                                                \
         ++ sym;                                                        \
-      if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \
-                       section_offset, isymbuf, locsymcount,   \
-                       signed_p))                              \
+      *symp = sym;                                             \
+      if (!eval_symbol (&a, symp, input_bfd, finfo, dot,       \
+                       isymbuf, locsymcount, signed_p))        \
         return FALSE;                                          \
       if (signed_p)                                             \
-        * result = op ((signed)a);                             \
+       *result = op ((bfd_signed_vma) a);                      \
       else                                                      \
         * result = op a;                                        \
-      * advanced = sym;                                        \
       return TRUE;                                             \
     }
 
@@ -7514,20 +7490,18 @@ eval_symbol (bfd_vma *                     result,
       sym += strlen (#op);                                     \
       if (* sym == ':')                                                \
         ++ sym;                                                        \
-      if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \
-                       section_offset, isymbuf, locsymcount,   \
-                       signed_p))                              \
+      *symp = sym;                                             \
+      if (!eval_symbol (&a, symp, input_bfd, finfo, dot,       \
+                       isymbuf, locsymcount, signed_p))        \
         return FALSE;                                          \
-      ++ sym;                                                  \
-      if (!eval_symbol (&b, sym, &sym, input_bfd, finfo, addr, \
-                       section_offset, isymbuf, locsymcount,   \
-                       signed_p))                              \
+      ++*symp;                                                 \
+      if (!eval_symbol (&b, symp, input_bfd, finfo, dot,       \
+                       isymbuf, locsymcount, signed_p))        \
         return FALSE;                                          \
       if (signed_p)                                             \
-        * result = ((signed) a) op ((signed) b);               \
+       *result = ((bfd_signed_vma) a) op ((bfd_signed_vma) b); \
       else                                                      \
         * result = a op b;                                      \
-      * advanced = sym;                                                \
       return TRUE;                                             \
     }
 
@@ -7561,141 +7535,6 @@ eval_symbol (bfd_vma *                     result,
     }
 }
 
-/* Entry point to evaluator, called from elf_link_input_bfd.  */
-
-static bfd_boolean
-evaluate_complex_relocation_symbols (bfd *input_bfd,
-                                    struct elf_final_link_info *finfo,
-                                    Elf_Internal_Sym *isymbuf,
-                                    size_t locsymcount)
-{
-  const struct elf_backend_data * bed;
-  Elf_Internal_Shdr *             symtab_hdr;
-  struct elf_link_hash_entry **   sym_hashes;
-  asection *                      reloc_sec;
-  bfd_boolean                     result = TRUE;
-
-  /* For each section, we're going to check and see if it has any
-     complex relocations, and we're going to evaluate any of them
-     we can.  */
-
-  if (finfo->info->relocatable)
-    return TRUE;
-
-  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (input_bfd);
-  bed = get_elf_backend_data (input_bfd);
-
-  for (reloc_sec = input_bfd->sections; reloc_sec; reloc_sec = reloc_sec->next)
-    {
-      Elf_Internal_Rela * internal_relocs;
-      unsigned long i;
-
-      /* This section was omitted from the link.  */
-      if (! reloc_sec->linker_mark)
-       continue;
-
-      /* Only process sections containing relocs.  */
-      if ((reloc_sec->flags & SEC_RELOC) == 0)
-       continue;
-
-      if (reloc_sec->reloc_count == 0)
-       continue;
-
-      /* Read in the relocs for this section.  */
-      internal_relocs
-       = _bfd_elf_link_read_relocs (input_bfd, reloc_sec, NULL,
-                                    (Elf_Internal_Rela *) NULL,
-                                    FALSE);
-      if (internal_relocs == NULL)
-       continue;
-
-      for (i = reloc_sec->reloc_count; i--;)
-       {
-         Elf_Internal_Rela * rel;
-         char * sym_name;
-         bfd_vma index;
-         Elf_Internal_Sym * sym;
-         bfd_vma result;
-         bfd_vma section_offset;
-         bfd_vma addr;
-         int signed_p = 0;
-
-         rel = internal_relocs + i;
-         section_offset = reloc_sec->output_section->vma
-           + reloc_sec->output_offset;
-         addr = rel->r_offset;
-
-         index = ELF32_R_SYM (rel->r_info);
-         if (bed->s->arch_size == 64)
-           index >>= 24;
-
-         if (index == STN_UNDEF)
-           continue;
-
-         if (index < locsymcount)
-           {
-             /* The symbol is local.  */
-             sym = isymbuf + index;
-
-             /* We're only processing STT_RELC or STT_SRELC type symbols.  */
-             if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) &&
-                 (ELF_ST_TYPE (sym->st_info) != STT_SRELC))
-               continue;
-
-             sym_name = bfd_elf_string_from_elf_section
-               (input_bfd, symtab_hdr->sh_link, sym->st_name);
-
-             signed_p = (ELF_ST_TYPE (sym->st_info) == STT_SRELC);
-           }
-         else
-           {
-             /* The symbol is global.  */
-             struct elf_link_hash_entry * h;
-
-             if (elf_bad_symtab (input_bfd))
-               continue;
-
-             h = sym_hashes [index - locsymcount];
-             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 (h->type != STT_RELC && h->type != STT_SRELC)
-               continue;
-
-             signed_p = (h->type == STT_SRELC);
-             sym_name = (char *) h->root.root.string;
-           }
-#ifdef DEBUG
-         printf ("Encountered a complex symbol!");
-         printf (" (input_bfd %s, section %s, reloc %ld\n",
-                 input_bfd->filename, reloc_sec->name, i);
-         printf (" symbol: idx  %8.8lx, name %s\n",
-                 index, sym_name);
-         printf (" reloc : info %8.8lx, addr %8.8lx\n",
-                 rel->r_info, addr);
-         printf (" Evaluating '%s' ...\n ", sym_name);
-#endif
-         if (eval_symbol (& result, sym_name, & sym_name, input_bfd, 
-                          finfo, addr, section_offset, isymbuf, locsymcount,
-                          signed_p))
-           /* Symbol evaluated OK.  Update to absolute value.  */
-           set_symbol_value (input_bfd, isymbuf, locsymcount, index, result);
-
-         else
-           result = FALSE;
-       }
-
-      if (internal_relocs != elf_section_data (reloc_sec)->relocs)
-       free (internal_relocs);
-    }
-
-  /* If nothing went wrong, then we adjusted 
-     everything we wanted to adjust.  */
-  return result;
-}
-
 static void
 put_value (bfd_vma        size,
           unsigned long  chunksz,
@@ -7791,84 +7630,20 @@ decode_complex_addend
 }
 
 void
-bfd_elf_perform_complex_relocation
-    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
-     struct bfd_link_info *  info,
-     bfd *                   input_bfd,
-     asection *              input_section,
-     bfd_byte *              contents,
-     Elf_Internal_Rela *     rel,
-     Elf_Internal_Sym *      local_syms,
-     asection **             local_sections)
-{
-  const struct elf_backend_data * bed;
-  Elf_Internal_Shdr * symtab_hdr;
-  asection * sec;
-  bfd_vma relocation = 0, shift, x;
-  bfd_vma r_symndx;
-  bfd_vma mask;
-  unsigned long start, oplen, len, wordsz, 
-    chunksz, lsb0_p, signed_p, trunc_p;
+bfd_elf_perform_complex_relocation (bfd *input_bfd,
+                                   asection *input_section,
+                                   bfd_byte *contents,
+                                   Elf_Internal_Rela *rel,
+                                   bfd_vma relocation)
+{
+  bfd_vma shift, x, mask;
+  unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p;
 
   /*  Perform this reloc, since it is complex.
       (this is not to say that it necessarily refers to a complex
       symbol; merely that it is a self-describing CGEN based reloc.
       i.e. the addend has the complete reloc information (bit start, end,
       word size, etc) encoded within it.).  */ 
-  r_symndx = ELF32_R_SYM (rel->r_info);
-  bed = get_elf_backend_data (input_bfd);
-  if (bed->s->arch_size == 64)
-    r_symndx >>= 24;
-
-#ifdef DEBUG
-  printf ("Performing complex relocation %ld...\n", r_symndx);
-#endif
-
-  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
-  if (r_symndx < symtab_hdr->sh_info)
-    {
-      /* The symbol is local.  */
-      Elf_Internal_Sym * sym;
-
-      sym = local_syms + r_symndx;
-      sec = local_sections [r_symndx];
-      relocation = sym->st_value;
-      if (sym->st_shndx > SHN_UNDEF && 
-         sym->st_shndx < SHN_LORESERVE)
-       relocation += (sec->output_offset +
-                      sec->output_section->vma);
-    }
-  else
-    {
-      /* The symbol is global.  */
-      struct elf_link_hash_entry **sym_hashes;
-      struct elf_link_hash_entry * h;
-
-      sym_hashes = elf_sym_hashes (input_bfd);
-      h = sym_hashes [r_symndx];
-
-      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 (h->root.type == bfd_link_hash_defined
-         || h->root.type == bfd_link_hash_defweak)
-       {
-         sec = h->root.u.def.section;
-         relocation = h->root.u.def.value;
-
-         if (! bfd_is_abs_section (sec))
-           relocation += (sec->output_section->vma 
-                          + sec->output_offset); 
-       }
-      if (h->root.type == bfd_link_hash_undefined
-         && !((*info->callbacks->undefined_symbol)
-              (info, h->root.root.string, input_bfd,
-               input_section, rel->r_offset,
-               info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-               || ELF_ST_VISIBILITY (h->other))))
-       return;
-    }
 
   decode_complex_addend (& start, & oplen, & len, & wordsz, 
                         & chunksz, & lsb0_p, & signed_p, 
@@ -9213,10 +8988,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
        return FALSE;
     }
 
-  if (! evaluate_complex_relocation_symbols (input_bfd, finfo, isymbuf,
-                                            locsymcount))
-    return FALSE;
-
   /* Relocate the contents of each section.  */
   sym_hashes = elf_sym_hashes (input_bfd);
   for (o = input_bfd->sections; o != NULL; o = o->next)
@@ -9258,8 +9029,10 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
       if ((o->flags & SEC_RELOC) != 0)
        {
          Elf_Internal_Rela *internal_relocs;
+         Elf_Internal_Rela *rel, *relend;
          bfd_vma r_type_mask;
          int r_sym_shift;
+         int action_discarded;
          int ret;
 
          /* Get the swapped relocs.  */
@@ -9281,76 +9054,107 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
              r_sym_shift = 32;
            }
 
-         /* Run through the relocs looking for any against symbols
-            from discarded sections and section symbols from
-            removed link-once sections.  Complain about relocs
-            against discarded sections.  Zero relocs against removed
-            link-once sections.  */
+         action_discarded = -1;
          if (!elf_section_ignore_discarded_relocs (o))
+           action_discarded = (*bed->action_discarded) (o);
+
+         /* Run through the relocs evaluating complex reloc symbols and
+            looking for relocs against symbols from discarded sections
+            or section symbols from removed link-once sections.
+            Complain about relocs against discarded sections.  Zero
+            relocs against removed link-once sections.  */
+
+         rel = internal_relocs;
+         relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
+         for ( ; rel < relend; rel++)
            {
-             Elf_Internal_Rela *rel, *relend;
-             unsigned int action = (*bed->action_discarded) (o);
+             unsigned long r_symndx = rel->r_info >> r_sym_shift;
+             unsigned int s_type;
+             asection **ps, *sec;
+             struct elf_link_hash_entry *h = NULL;
+             const char *sym_name;
 
-             rel = internal_relocs;
-             relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
-             for ( ; rel < relend; rel++)
-               {
-                 unsigned long r_symndx = rel->r_info >> r_sym_shift;
-                 asection **ps, *sec;
-                 struct elf_link_hash_entry *h = NULL;
-                 const char *sym_name;
+             if (r_symndx == STN_UNDEF)
+               continue;
 
-                 if (r_symndx == STN_UNDEF)
-                   continue;
+             if (r_symndx >= locsymcount
+                 || (elf_bad_symtab (input_bfd)
+                     && finfo->sections[r_symndx] == NULL))
+               {
+                 h = sym_hashes[r_symndx - extsymoff];
 
-                 if (r_symndx >= locsymcount
-                     || (elf_bad_symtab (input_bfd)
-                         && finfo->sections[r_symndx] == NULL))
+                 /* Badly formatted input files can contain relocs that
+                    reference non-existant symbols.  Check here so that
+                    we do not seg fault.  */
+                 if (h == NULL)
                    {
-                     h = sym_hashes[r_symndx - extsymoff];
+                     char buffer [32];
 
-                     /* Badly formatted input files can contain relocs that
-                        reference non-existant symbols.  Check here so that
-                        we do not seg fault.  */
-                     if (h == NULL)
-                       {
-                         char buffer [32];
+                     sprintf_vma (buffer, rel->r_info);
+                     (*_bfd_error_handler)
+                       (_("error: %B contains a reloc (0x%s) for section %A "
+                          "that references a non-existent global symbol"),
+                        input_bfd, o, buffer);
+                     bfd_set_error (bfd_error_bad_value);
+                     return FALSE;
+                   }
 
-                         sprintf_vma (buffer, rel->r_info);
-                         (*_bfd_error_handler)
-                           (_("error: %B contains a reloc (0x%s) for section %A "
-                              "that references a non-existent global symbol"),
-                            input_bfd, o, buffer);
-                         bfd_set_error (bfd_error_bad_value);
-                         return FALSE;
-                       }
+                 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;
 
-                     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;
+                 s_type = h->type;
 
-                     if (h->root.type != bfd_link_hash_defined
-                         && h->root.type != bfd_link_hash_defweak)
-                       continue;
+                 ps = NULL;
+                 if (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak)
+                   ps = &h->root.u.def.section;
 
-                     ps = &h->root.u.def.section;
-                     sym_name = h->root.root.string;
-                   }
-                 else
-                   {
-                     Elf_Internal_Sym *sym = isymbuf + r_symndx;
-                     ps = &finfo->sections[r_symndx];
-                     sym_name = bfd_elf_sym_name (input_bfd,
-                                                  symtab_hdr,
-                                                  sym, *ps);
-                   }
+                 sym_name = h->root.root.string;
+               }
+             else
+               {
+                 Elf_Internal_Sym *sym = isymbuf + r_symndx;
 
+                 s_type = ELF_ST_TYPE (sym->st_info);
+                 ps = &finfo->sections[r_symndx];
+                 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+                                              sym, *ps);
+               }
+
+             if (s_type == STT_RELC || s_type == STT_SRELC)
+               {
+                 bfd_vma val;
+                 bfd_vma dot = (rel->r_offset
+                                + o->output_offset + o->output_section->vma);
+#ifdef DEBUG
+                 printf ("Encountered a complex symbol!");
+                 printf (" (input_bfd %s, section %s, reloc %ld\n",
+                         input_bfd->filename, o->name, rel - internal_relocs);
+                 printf (" symbol: idx  %8.8lx, name %s\n",
+                         r_symndx, sym_name);
+                 printf (" reloc : info %8.8lx, addr %8.8lx\n",
+                         (unsigned long) rel->r_info,
+                         (unsigned long) rel->r_offset);
+#endif
+                 if (!eval_symbol (&val, &sym_name, input_bfd, finfo, dot,
+                                   isymbuf, locsymcount, s_type == STT_SRELC))
+                   return FALSE;
+
+                 /* Symbol evaluated OK.  Update to absolute value.  */
+                 set_symbol_value (input_bfd, isymbuf, locsymcount,
+                                   r_symndx, val);
+                 continue;
+               }
+
+             if (action_discarded != -1 && ps != NULL)
+               {
                  /* Complain if the definition comes from a
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
                      BFD_ASSERT (r_symndx != 0);
-                     if (action & COMPLAIN)
+                     if (action_discarded & COMPLAIN)
                        (*finfo->info->callbacks->einfo)
                          (_("%X`%s' referenced in section `%A' of %B: "
                             "defined in discarded section `%A' of %B\n"),
@@ -9362,7 +9166,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                         FIXME: This is quite broken.  Modifying the
                         symbol here means we will be changing all later
                         uses of the symbol, not just in this section.  */
-                     if (action & PRETEND)
+                     if (action_discarded & PRETEND)
                        {
                          asection *kept;
 
index 701cac3..cecfd3c 100644 (file)
@@ -1,3 +1,9 @@
+2007-09-29  Alan Modra  <amodra@bigpond.net.au>
+
+       * ld-selective/sel-dump.exp: Add am33, m88k, mep to xfails.
+       * ld-selective/selective.exp: Don't run for same target list
+       we xfail sel-dump.
+
 2007-09-29  Mike Frysinger  <vapier@gentoo.org>
 
        * ld-alpha/tlsbin.rd: Use [0-9]+ to match section header count and
index 2f6f5de..76a7577 100644 (file)
@@ -28,8 +28,8 @@ set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
 for { set i 0 } { $i < [llength $test_list] } { incr i } {
     # We need to strip the ".d", but can leave the dirname.
     verbose [file rootname [lindex $test_list $i]]
-    setup_xfail "alpha*-*" "arc*-*" "d30v*-*" "dlx*-*" "hppa64-*-*"
-    setup_xfail "i370*-*" "i860*-*" "i960*-*" "ia64*-*" "mn10200-*"
-    setup_xfail  "or32-*" "pj-*"
+    setup_xfail "alpha*-*" "am33*-*" "arc*-*" "d30v*-*" "dlx*-*"
+    setup_xfail "hppa*64-*-*" "i370*-*" "i860*-*" "i960*-*" "ia64*-*"
+    setup_xfail "m88*-*" "mn10200-*" "mep-*" "or32-*" "pj-*"
     run_dump_test [file rootname [lindex $test_list $i]]
 }
index bae4372..191cd63 100644 (file)
@@ -27,8 +27,15 @@ if ![is_elf_format] {
     return
 }
 
-# Alpha and IA64 do not support selective linking
-if {[istarget "alpha*-*-*"] || [istarget "ia64-*-*"]} {
+# These targets do not support selective linking
+if {[istarget "alpha*-*-*"] || [istarget "am33*-*-*"] ||
+    [istarget "arc-*-*"] || [istarget "d30v-*-*"] ||
+    [istarget "dlx-*-*"] || [istarget "hppa*64*-*-*"] ||
+    [istarget "i370-*-*"] || [istarget "i860-*-*"] ||
+    [istarget "i960-*-*"] || [istarget "ia64-*-*"] ||
+    [istarget "m88*-*-*"] || [istarget "mn10200-*-*"] ||
+    [istarget "mep-*-*"] || [istarget "or32-*-*"] ||
+    [istarget "pj*-*-*"]} {
     return
 }