diff options
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 42 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 11 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 11 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard.ld | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard1.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard1.s | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard2.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard2.s | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/discard3.d | 11 |
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 |