* elf32-xtensa.c (relax_section): Check for a reference to a discarded
authorBob Wilson <bob.wilson@acm.org>
Wed, 17 Oct 2007 00:30:31 +0000 (00:30 +0000)
committerBob Wilson <bob.wilson@acm.org>
Wed, 17 Oct 2007 00:30:31 +0000 (00:30 +0000)
DWARF section and anticipate its replacement with the kept section.

bfd/ChangeLog
bfd/elf32-xtensa.c

index b85f3b2b2ee069da011160db8b992958bca49b3c..de0deb0be28a87e4d7dc4f1f760f1a3db212d97f 100644 (file)
@@ -1,3 +1,8 @@
+2007-10-16  Bob Wilson  <bob.wilson@acm.org>
+
+       * elf32-xtensa.c (relax_section): Check for a reference to a discarded
+       DWARF section and anticipate its replacement with the kept section.
+       
 2007-10-16  Bob Wilson  <bob.wilson@acm.org>
 
        * elf32-xtensa.c (elf_xtensa_discard_info_for_section): Remove
index 03b95834e0781176df10de6792c1c4edca9fa47f..6bf5609b67c8f7051b2d87051e4c4fb793d83743 100644 (file)
@@ -8150,8 +8150,56 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
             we may need to change the relocation's target offset.  */
 
          target_sec = r_reloc_get_section (&r_rel);
-         target_relax_info = get_xtensa_relax_info (target_sec);
 
+         /* For a reference to a discarded section from a DWARF section,
+            i.e., where action_discarded is PRETEND, the symbol will
+            eventually be modified to refer to the kept section (at least if
+            the kept and discarded sections are the same size).  Anticipate
+            that here and adjust things accordingly.  */
+         if (! elf_xtensa_ignore_discarded_relocs (sec)
+             && elf_xtensa_action_discarded (sec) == PRETEND
+             && sec->sec_info_type != ELF_INFO_TYPE_STABS
+             && target_sec != NULL
+             && elf_discarded_section (target_sec))
+           {
+             /* It would be natural to call _bfd_elf_check_kept_section
+                here, but it's not exported from elflink.c.  It's also a
+                fairly expensive check.  Adjusting the relocations to the
+                discarded section is fairly harmless; it will only adjust
+                some addends and difference values.  If it turns out that
+                _bfd_elf_check_kept_section fails later, it won't matter,
+                so just compare the section names to find the right group
+                member.  */
+             asection *kept = target_sec->kept_section;
+             if (kept != NULL)
+               {
+                 if ((kept->flags & SEC_GROUP) != 0)
+                   {
+                     asection *first = elf_next_in_group (kept);
+                     asection *s = first;
+
+                     kept = NULL;
+                     while (s != NULL)
+                       {
+                         if (strcmp (s->name, target_sec->name) == 0)
+                           {
+                             kept = s;
+                             break;
+                           }
+                         s = elf_next_in_group (s);
+                         if (s == first)
+                           break;
+                       }
+                   }
+               }
+             if (kept != NULL
+                 && ((target_sec->rawsize != 0
+                      ? target_sec->rawsize : target_sec->size)
+                     == (kept->rawsize != 0 ? kept->rawsize : kept->size)))
+               target_sec = kept;
+           }
+
+         target_relax_info = get_xtensa_relax_info (target_sec);
          if (target_relax_info
              && (target_relax_info->is_relaxable_literal_section
                  || target_relax_info->is_relaxable_asm_section))