aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/elf-bfd.h42
-rw-r--r--bfd/elf32-i386.c11
-rw-r--r--bfd/elf64-x86-64.c11
-rw-r--r--ld/testsuite/ChangeLog10
-rw-r--r--ld/testsuite/ld-elf/discard.ld3
-rw-r--r--ld/testsuite/ld-elf/discard1.d9
-rw-r--r--ld/testsuite/ld-elf/discard1.s11
-rw-r--r--ld/testsuite/ld-elf/discard2.d9
-rw-r--r--ld/testsuite/ld-elf/discard2.s12
-rw-r--r--ld/testsuite/ld-elf/discard3.d11
11 files changed, 119 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e3a1e53..74dd28b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 0c975dc..226b95f 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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) \
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 395a6bb..7964c4f 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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;
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 3a24cca..21524fa 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 2239cf6..34666d9 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
index 0000000..bd094f2
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard.ld
@@ -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
index 0000000..b80fbf0
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard1.d
@@ -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
index 0000000..ac3b92f
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard1.s
@@ -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
index 0000000..65a3abe
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard2.d
@@ -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
index 0000000..27b66f4
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard2.s
@@ -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
index 0000000..07962b5
--- /dev/null
+++ b/ld/testsuite/ld-elf/discard3.d
@@ -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