2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 1 Apr 2005 03:49:46 +0000 (03:49 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 1 Apr 2005 03:49:46 +0000 (03:49 +0000)
* elf-bfd.h (_bfd_elf_check_kept_section): New.

* elf.c (assign_section_numbers): When sh_link points to a
discarded section, call _bfd_elf_check_kept_section to see if
the kept section can be used. Otherwise reject sh_link
pointing to discarded section.

* elflink.c (_bfd_elf_check_kept_section): New.
(elf_link_input_bfd): Use it.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elflink.c

index c5b78870290b6e53107110eb254b83feb2ff0ce2..5a948c52499bcdb21387fe32a2e403ffb996f54f 100644 (file)
@@ -1,3 +1,15 @@
+2005-03-31  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf-bfd.h (_bfd_elf_check_kept_section): New.
+
+       * elf.c (assign_section_numbers): When sh_link points to a
+       discarded section, call _bfd_elf_check_kept_section to see if
+       the kept section can be used. Otherwise reject sh_link
+       pointing to discarded section.
+
+       * elflink.c (_bfd_elf_check_kept_section): New.
+       (elf_link_input_bfd): Use it.
+
 2005-04-01  Alan Modra  <amodra@bigpond.net.au>
 
        * elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs
index a5047de7a69f2a47bb7a238e10a190f4d006e7c7..9d3871b04360ff2a7f5d0e7a23a64ead1535a21e 100644 (file)
@@ -1441,6 +1441,8 @@ extern void _bfd_elf_section_already_linked
   (bfd *, struct bfd_section *);
 extern void bfd_elf_set_group_contents
   (bfd *, asection *, void *);
+extern asection *_bfd_elf_check_kept_section
+  (asection *);
 extern void _bfd_elf_link_just_syms
   (asection *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_copy_private_header_data
index dfbad3cb2bb594774474fccc84e140825d80db51..3aa91a438c625fb53d8542a0a033ec47044048cd 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2919,7 +2919,25 @@ assign_section_numbers (bfd *abfd)
                        }
                      else
                        {
-                         s = elf_shdrp[elfsec]->bfd_section->output_section;
+                         s = elf_shdrp[elfsec]->bfd_section;
+                         if (elf_discarded_section (s))
+                           {
+                             asection *kept;
+                              (*_bfd_error_handler)
+                                 (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
+                                  abfd, d->this_hdr.bfd_section,
+                                  s, s->owner);
+                              /* Point to the kept section if it has
+                                 the same size as the discarded
+                                 one.  */
+                              kept = _bfd_elf_check_kept_section (s);
+                              if (kept == NULL)
+                                {
+                                  bfd_set_error (bfd_error_bad_value);
+                                  return FALSE;
+                                }
+                           }
+                         s = s->output_section;
                          BFD_ASSERT (s != NULL);
                          d->this_hdr.sh_link = elf_section_data (s)->this_idx;
                        }
index 8134834cd914c2b99646ede486676e9878ec188a..d37b19ba92ac1ca4d048252addd9cfb85424357d 100644 (file)
@@ -6700,6 +6700,26 @@ match_group_member (asection *sec, asection *group)
   return NULL;
 }
 
+/* Check if the kept section of a discarded section SEC can be used
+   to replace it. Return the replacement if it is OK. Otherwise return
+   NULL. */
+
+asection *
+_bfd_elf_check_kept_section (asection *sec)
+{
+  asection *kept;
+
+  kept = sec->kept_section;
+  if (kept != NULL)
+    {
+      if (elf_sec_group (sec) != NULL)
+       kept = match_group_member (sec, kept);
+      if (kept != NULL && sec->size != kept->size)
+       kept = NULL;
+    }
+  return kept;
+}
+
 /* Link an input file into the linker output file.  This function
    handles all the sections and relocations of the input file at once.
    This is so that we only have to read the local symbols once, and
@@ -7013,8 +7033,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
-                     asection *kept;
-
                      BFD_ASSERT (r_symndx != 0);
                      if (action & COMPLAIN)
                        {
@@ -7035,13 +7053,12 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                         is that we warn in non-debug sections, and
                         debug sections tend to come after other
                         sections.  */
-                     kept = sec->kept_section;
-                     if (kept != NULL && (action & PRETEND))
+                     if (action & PRETEND)
                        {
-                         if (elf_sec_group (sec) != NULL)
-                           kept = match_group_member (sec, kept);
-                         if (kept != NULL
-                             && sec->size == kept->size)
+                         asection *kept;
+
+                         kept = _bfd_elf_check_kept_section (sec);
+                         if (kept != NULL)
                            {
                              *ps = kept;
                              continue;