Remove relocation against discarded sections for relocatable link.
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 30 Apr 2010 18:27:32 +0000 (18:27 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 30 Apr 2010 18:27:32 +0000 (18:27 +0000)
bfd/

2010-04-30  H.J. Lu  <hongjiu.lu@intel.com>

PR ld/11542
* elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): New.

* elf32-i386.c (elf_i386_relocate_section): Use it.
* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.

ld/testsuite/

2010-04-30  H.J. Lu  <hongjiu.lu@intel.com>

PR ld/11542
* ld-elf/discard.ld: New.
* ld-elf/discard1.d: Likewise.
* ld-elf/discard1.s: Likewise.
* ld-elf/discard2.d: Likewise.
* ld-elf/discard2.s: Likewise.
* ld-elf/discard3.d: Likewise.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-elf/discard.ld [new file with mode: 0644]
ld/testsuite/ld-elf/discard1.d [new file with mode: 0644]
ld/testsuite/ld-elf/discard1.s [new file with mode: 0644]
ld/testsuite/ld-elf/discard2.d [new file with mode: 0644]
ld/testsuite/ld-elf/discard2.s [new file with mode: 0644]
ld/testsuite/ld-elf/discard3.d [new file with mode: 0644]

index e3a1e53..74dd28b 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/11542
+       * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): New.
+
+       * elf32-i386.c (elf_i386_relocate_section): Use it.
+       * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
 2010-04-30  Tristan Gingold  <gingold@adacore.com>
 
        * vms-lib.c (vms_read_block): New function.
index 0c975dc..226b95f 100644 (file)
@@ -2328,6 +2328,48 @@ extern asection _bfd_elf_large_com_section;
     }                                                                  \
   while (0)
 
+/* This macro is to avoid lots of duplicated code in the body of the
+   loop over relocations in xxx_relocate_section() in the various
+   elfxx-xxxx.c files.
+   
+   Handle relocations against symbols from removed linkonce sections,
+   or sections discarded by a linker script.  When doing a relocatable
+   link, we remove such relocations.  Otherwise, we just want the
+   section contents zeroed and avoid any special processing.  */
+#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section,        \
+                                       rel, relend, howto, contents)   \
+  {                                                                    \
+    if (info->relocatable                                              \
+       && (input_section->flags & SEC_DEBUGGING))                      \
+      {                                                                        \
+       /* Only remove relocations in debug sections since other        \
+          sections may require relocations.  */                        \
+       Elf_Internal_Shdr *rel_hdr;                                     \
+                                                                       \
+       rel_hdr = &elf_section_data (input_section->output_section)->rel_hdr; \
+                                                                       \
+       /* Avoid empty output section.  */                              \
+       if (rel_hdr->sh_size > rel_hdr->sh_entsize)                     \
+         {                                                             \
+           rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
+           rel_hdr = &elf_section_data (input_section)->rel_hdr;       \
+           rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
+                                                                       \
+           memmove (rel, rel + 1, (relend - rel) * sizeof (*rel));     \
+                                                                       \
+           input_section->reloc_count--;                               \
+           relend--;                                                   \
+           rel--;                                                      \
+           continue;                                                   \
+         }                                                             \
+      }                                                                        \
+                                                                       \
+    _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);  \
+    rel->r_info = 0;                                                   \
+    rel->r_addend = 0;                                                 \
+    continue;                                                          \
+  }
+
 /* Will a symbol be bound to the the definition within the shared
    library, if any.  A unique symbol can never be bound locally.  */
 #define SYMBOLIC_BIND(INFO, H) \
index 395a6bb..7964c4f 100644 (file)
@@ -2955,15 +2955,8 @@ elf_i386_relocate_section (bfd *output_bfd,
        }
 
       if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
 
       if (info->relocatable)
        continue;
index 3a24cca..21524fa 100644 (file)
@@ -2685,15 +2685,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        }
 
       if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
 
       if (info->relocatable)
        continue;
index 2239cf6..34666d9 100644 (file)
@@ -1,3 +1,13 @@
+2010-04-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/11542
+       * ld-elf/discard.ld: New.
+       * ld-elf/discard1.d: Likewise.
+       * ld-elf/discard1.s: Likewise.
+       * ld-elf/discard2.d: Likewise.
+       * ld-elf/discard2.s: Likewise.
+       * ld-elf/discard3.d: Likewise.
+
 2010-04-22  Alan Modra  <amodra@gmail.com>
 
        * ld-elf/extract-symbol-1sec.d: Update lma.
diff --git a/ld/testsuite/ld-elf/discard.ld b/ld/testsuite/ld-elf/discard.ld
new file mode 100644 (file)
index 0000000..bd094f2
--- /dev/null
@@ -0,0 +1,3 @@
+SECTIONS {
+        /DISCARD/ : { *(.discard) }
+}
diff --git a/ld/testsuite/ld-elf/discard1.d b/ld/testsuite/ld-elf/discard1.d
new file mode 100644 (file)
index 0000000..b80fbf0
--- /dev/null
@@ -0,0 +1,9 @@
+#source: discard1.s
+#ld: -r -T discard.ld
+#readelf: -r
+#target: x86_64-*-linux-gnu i?86-*-linux-gnu
+
+Relocation section '.rel.*.debug_info' at offset 0x[0-9a-z]+ contains 1 entries:
+[ \t]+Offset[ \t]+Info[ \t]+Type[ \t]+Sym.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+bar.*
+#pass
diff --git a/ld/testsuite/ld-elf/discard1.s b/ld/testsuite/ld-elf/discard1.s
new file mode 100644 (file)
index 0000000..ac3b92f
--- /dev/null
@@ -0,0 +1,11 @@
+       .globl bar
+       .data
+bar:
+       .long   1
+       .section        .discard,"aw",%progbits
+       .align 4
+there:
+       .long   2
+       .section        .debug_info,"",%progbits
+       .long   bar
+       .long   there
diff --git a/ld/testsuite/ld-elf/discard2.d b/ld/testsuite/ld-elf/discard2.d
new file mode 100644 (file)
index 0000000..65a3abe
--- /dev/null
@@ -0,0 +1,9 @@
+#source: discard2.s
+#ld: -r -T discard.ld
+#readelf: -r
+#target: x86_64-*-linux-gnu i?86-*-linux-gnu
+
+Relocation section '.rel.*.debug_info' at offset 0x[0-9a-z]+ contains 1 entries:
+[ \t]+Offset[ \t]+Info[ \t]+Type[ \t]+Sym.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+here.*
+#pass
diff --git a/ld/testsuite/ld-elf/discard2.s b/ld/testsuite/ld-elf/discard2.s
new file mode 100644 (file)
index 0000000..27b66f4
--- /dev/null
@@ -0,0 +1,12 @@
+       .globl here
+       .data
+here:
+       .long   1
+       .globl there
+       .section        .discard,"aw",%progbits
+       .align 4
+there:
+       .long   2
+       .section        .debug_info,"",%progbits
+       .long   here
+       .long   there
diff --git a/ld/testsuite/ld-elf/discard3.d b/ld/testsuite/ld-elf/discard3.d
new file mode 100644 (file)
index 0000000..07962b5
--- /dev/null
@@ -0,0 +1,11 @@
+#source: discard1.s
+#source: discard2.s
+#ld: -r -T discard.ld
+#readelf: -r
+#target: x86_64-*-linux-gnu i?86-*-linux-gnu
+
+Relocation section '.rel.*.debug_info' at offset 0x[0-9a-z]+ contains 2 entries:
+[ \t]+Offset[ \t]+Info[ \t]+Type[ \t]+Sym.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+bar.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+here.*
+#pass