bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 18 Jun 2003 00:30:04 +0000 (00:30 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 18 Jun 2003 00:30:04 +0000 (00:30 +0000)
2003-06-17  H.J. Lu <hongjiu.lu@intel.com>

* section.c (struct sec): Put back kept_section.
(STD_SECTION): Put back kept_section initialization.
* bfd-in2.h: Regenerate.

* elflink.h (elf_link_input_bfd): Also check discarded linkonce
sections for relocateable output. Use kept_section to preserve
debug information discarded by linkonce.

ld/

2003-06-17  H.J. Lu <hongjiu.lu@intel.com>

* ldlang.c (section_already_linked): Put back assignment of
kept_section.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elflink.h
bfd/section.c
ld/ChangeLog
ld/ldlang.c

index f799d2ed9882fdcb596a593fecff9f75ca354850..f0570bbd30c288a1a3432f51164db2dc65f02478 100644 (file)
@@ -1,3 +1,13 @@
+2003-06-17  H.J. Lu <hongjiu.lu@intel.com>
+
+       * section.c (struct sec): Put back kept_section.
+       (STD_SECTION): Put back kept_section initialization.
+       * bfd-in2.h: Regenerate.
+
+       * elflink.h (elf_link_input_bfd): Also check discarded linkonce
+       sections for relocateable output. Use kept_section to preserve
+       debug information discarded by linkonce.
+
 2003-06-17  Roland McGrath  <roland@redhat.com>
 
        * elfxx-ia64.c (elfNN_ia64_relocate_section): Support
index 072812e4f14b3c1efc2d052c39bd7021b4f5ae4a..71346c1260aed0394c82ecdfd806486da47c1d03 100644 (file)
@@ -1408,6 +1408,10 @@ typedef struct sec
   /* Optional information about a COMDAT entry; NULL if not COMDAT.  */
   struct bfd_comdat_info *comdat;
 
+  /* Points to the kept section if this section is a link-once section,
+     and is discarded.  */
+  struct sec *kept_section;
+
   /* When a section is being output, this value changes as more
      linenumbers are written out.  */
   file_ptr moving_line_filepos;
index b960c73f9cbce6d0f773a9f662ca6892224dc796..64554e716ed287039ea7c33cf7c4217fbe7e54e2 100644 (file)
@@ -5005,9 +5005,9 @@ elf_link_input_bfd (finfo, input_bfd)
             from discarded sections and section symbols from
             removed link-once sections.  Complain about relocs
             against discarded sections.  Zero relocs against removed
-            link-once sections.  */
-         if (!finfo->info->relocateable
-             && !elf_section_ignore_discarded_relocs (o))
+            link-once sections.  Preserve debug information as much
+            as we can.  */
+         if (!elf_section_ignore_discarded_relocs (o))
            {
              Elf_Internal_Rela *rel, *relend;
 
@@ -5016,6 +5016,7 @@ elf_link_input_bfd (finfo, input_bfd)
              for ( ; rel < relend; rel++)
                {
                  unsigned long r_symndx = ELF_R_SYM (rel->r_info);
+                 asection *sec;
 
                  if (r_symndx >= locsymcount
                      || (elf_bad_symtab (input_bfd)
@@ -5030,14 +5031,22 @@ elf_link_input_bfd (finfo, input_bfd)
 
                      /* Complain if the definition comes from a
                         discarded section.  */
+                     sec = h->root.u.def.section;
                      if ((h->root.type == bfd_link_hash_defined
                           || h->root.type == bfd_link_hash_defweak)
-                         && elf_discarded_section (h->root.u.def.section))
+                         && elf_discarded_section (sec))
                        {
                          if ((o->flags & SEC_DEBUGGING) != 0)
                            {
                              BFD_ASSERT (r_symndx != 0);
-                             memset (rel, 0, sizeof (*rel));
+                             /* Try to preserve debug information.  */
+                             if ((o->flags & SEC_DEBUGGING) != 0
+                                 && sec->kept_section != NULL
+                                 && sec->_cooked_size == sec->kept_section->_cooked_size)
+                               h->root.u.def.section
+                                 = sec->kept_section;
+                             else
+                               memset (rel, 0, sizeof (*rel));
                            }
                          else
                            finfo->info->callbacks->error_handler
@@ -5051,7 +5060,7 @@ elf_link_input_bfd (finfo, input_bfd)
                    }
                  else
                    {
-                     asection *sec = finfo->sections[r_symndx];
+                     sec = finfo->sections[r_symndx];
 
                      if (sec != NULL && elf_discarded_section (sec))
                        {
@@ -5059,9 +5068,18 @@ elf_link_input_bfd (finfo, input_bfd)
                              || (sec->flags & SEC_LINK_ONCE) != 0)
                            {
                              BFD_ASSERT (r_symndx != 0);
-                             rel->r_info
-                               = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
-                             rel->r_addend = 0;
+                             /* Try to preserve debug information.  */
+                             if ((o->flags & SEC_DEBUGGING) != 0
+                                 && sec->kept_section != NULL
+                                 && sec->_cooked_size == sec->kept_section->_cooked_size)
+                               finfo->sections[r_symndx]
+                                 = sec->kept_section;
+                             else
+                               {
+                                 rel->r_info
+                                   = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
+                                 rel->r_addend = 0;
+                               }
                            }
                          else
                            {
index 6facfe2066dde5ef732cb99935b84e8072a14025..44edb073caa5deda4fe15fd314b655824b51e7b6 100644 (file)
@@ -493,6 +493,10 @@ CODE_FRAGMENT
 .  {* Optional information about a COMDAT entry; NULL if not COMDAT.  *}
 .  struct bfd_comdat_info *comdat;
 .
+.  {* Points to the kept section if this section is a link-once section,
+.     and is discarded.  *}
+.  struct sec *kept_section;
+.
 .  {* When a section is being output, this value changes as more
 .     linenumbers are written out.  *}
 .  file_ptr moving_line_filepos;
@@ -640,8 +644,8 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */        \
        0,            NULL,     NULL,     NULL,   0,                    \
                                                                        \
-    /* entsize, comdat, moving_line_filepos,                         */        \
-       0,       NULL,   0,                                             \
+    /* entsize, comdat, kept_section, moving_line_filepos,           */        \
+       0,       NULL,   NULL,        0,                                \
                                                                        \
     /* target_index, used_by_bfd, constructor_chain, owner,          */        \
        0,            NULL,        NULL,              NULL,             \
index 11811de5963278a1ecea737b8422543f1bbdad0f..dcc5a56487a12f35bfefbac4668da21ed5d68444 100644 (file)
@@ -1,3 +1,8 @@
+2003-06-17  H.J. Lu <hongjiu.lu@intel.com>
+
+       * ldlang.c (section_already_linked): Put back assignment of
+       kept_section.
+
 2003-06-17  Rainer Keuchel  <rkeuchel@allgeier.com>
 
        * pe-dll.c (generate_reloc): Catch and ignore an ARM_26D
index fccab0d681af0745030ce6f3e8f3e16d76017bcc..83d43b83ad094c41d63043f62ae9ab93fbd2e9e8 100644 (file)
@@ -1089,8 +1089,11 @@ section_already_linked (abfd, sec, data)
 
          /* Set the output_section field so that lang_add_section
             does not create a lang_input_section structure for this
-            section.  */
+            section.  Since there might be a symbol in the section
+            being discarded, we must retain a pointer to the section
+            which we are really going to use.  */
          sec->output_section = bfd_abs_section_ptr;
+         sec->kept_section = l->sec;
 
          if (flags & SEC_GROUP)
            bfd_discard_group (abfd, sec);