OSDN Git Service

PR 233
authoramodra <amodra>
Mon, 11 Oct 2004 13:28:56 +0000 (13:28 +0000)
committeramodra <amodra>
Mon, 11 Oct 2004 13:28:56 +0000 (13:28 +0000)
* elflink.c (elf_link_input_bfd): Try harder to support
relocations against symbols in removed linkonce sections.

bfd/ChangeLog
bfd/elflink.c

index 09b4e2d..a2d4bff 100644 (file)
@@ -1,5 +1,11 @@
 2004-10-11  Alan Modra  <amodra@bigpond.net.au>
 
+       PR 233
+       * elflink.c (elf_link_input_bfd): Try harder to support
+       relocations against symbols in removed linkonce sections.
+
+2004-10-11  Alan Modra  <amodra@bigpond.net.au>
+
        * elflink.c (elf_link_input_bfd): Revert PR 354 change.
 
        PR 354
index 08c0aee..834f09a 100644 (file)
@@ -6733,44 +6733,10 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
-                     if ((o->flags & SEC_DEBUGGING) != 0)
-                       {
-                         BFD_ASSERT (r_symndx != 0);
-
-                         /* Try to preserve debug information.
-                            FIXME: This is quite broken.  Modifying
-                            the symbol here means we will be changing
-                            all uses of the symbol, not just those in
-                            debug sections.  The only thing that makes
-                            this half reasonable is that debug sections
-                            tend to come after other sections.  Of
-                            course, that doesn't help with globals.
-                            ??? All link-once sections of the same name
-                            ought to define the same set of symbols, so
-                            it would seem that globals ought to always
-                            be defined in the kept section.  */
-                         if (sec->kept_section != NULL)
-                           {
-                             asection *member;
+                     asection *kept;
 
-                             /* Check if it is a linkonce section or
-                                member of a comdat group.  */
-                             if (elf_sec_group (sec) == NULL
-                                 && sec->size == sec->kept_section->size)
-                               {
-                                 *ps = sec->kept_section;
-                                 continue;
-                               }
-                             else if (elf_sec_group (sec) != NULL
-                                      && (member = match_group_member (sec, sec->kept_section))
-                                      && sec->size == member->size)
-                               {
-                                 *ps = member;
-                                 continue;
-                               }
-                           }
-                       }
-                     else if (complain)
+                     BFD_ASSERT (r_symndx != 0);
+                     if (complain && (o->flags & SEC_DEBUGGING) == 0)
                        {
                          (*_bfd_error_handler)
                            (_("`%s' referenced in section `%A' of %B: "
@@ -6778,6 +6744,32 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                             o, input_bfd, sec, sec->owner, sym_name);
                        }
 
+                     /* Try to do the best we can to support buggy old
+                        versions of gcc.  If we've warned, or this is
+                        debugging info, pretend that the symbol is
+                        really defined in the kept linkonce section.
+                        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.
+                        The only thing that makes this half reasonable
+                        is that we warn in non-debug sections, and
+                        debug sections tend to come after other
+                        sections.  */
+                     kept = sec->kept_section;
+                     if (kept != NULL
+                         && (complain
+                             || (o->flags & SEC_DEBUGGING) != 0))
+                       {
+                         if (elf_sec_group (sec) != NULL)
+                           kept = match_group_member (sec, kept);
+                         if (kept != NULL
+                             && sec->size == kept->size)
+                           {
+                             *ps = kept;
+                             continue;
+                           }
+                       }
+
                      /* Remove the symbol reference from the reloc, but
                         don't kill the reloc completely.  This is so that
                         a zero value will be written into the section,