From b1e24c0220fe6718066991999cb0a6e5b88b569d Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Fri, 3 Nov 2006 00:58:10 +0000 Subject: [PATCH] bfd/ * libbfd-in.h (_bfd_clear_contents): New prototype. * reloc.c (_bfd_clear_contents): New. * libbfd.h: Regenerated. * elf32-arm.c (elf32_arm_final_link_relocate): Use _bfd_clear_contents. * elf32-d10v.c (elf32_d10v_relocate_section): Likewise. * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. * elf32-i386.c (elf_i386_relocate_section): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-s390.c (elf_s390_relocate_section): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise. * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-s390.c (elf_s390_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise. * elfxx-ia64.c (elfNN_ia64_relocate_section): Set value to zero for discarded symbols. * elfxx-mips.c (mips_elf_calculate_relocation): Likewise. ld/testsuite/ * ld-discard/zero-rel.d, ld-discard/zero-rel.s: New files. --- bfd/ChangeLog | 24 ++++++++++++++ bfd/elf32-arm.c | 5 ++- bfd/elf32-d10v.c | 10 ++++++ bfd/elf32-hppa.c | 10 ++++-- bfd/elf32-i386.c | 17 ++++------ bfd/elf32-ppc.c | 5 ++- bfd/elf32-s390.c | 9 ++++-- bfd/elf32-sh.c | 9 ++++++ bfd/elf32-xtensa.c | 10 ++++++ bfd/elf64-ppc.c | 6 +++- bfd/elf64-s390.c | 9 ++++-- bfd/elf64-x86-64.c | 9 ++++-- bfd/elfxx-ia64.c | 6 ++++ bfd/elfxx-mips.c | 5 +++ bfd/elfxx-sparc.c | 9 ++++-- bfd/libbfd-in.h | 4 +++ bfd/libbfd.h | 4 +++ bfd/reloc.c | 66 ++++++++++++++++++++++++++++++++++++++ ld/testsuite/ChangeLog | 4 +++ ld/testsuite/ld-discard/zero-rel.d | 8 +++++ ld/testsuite/ld-discard/zero-rel.s | 11 +++++++ 21 files changed, 216 insertions(+), 24 deletions(-) create mode 100644 ld/testsuite/ld-discard/zero-rel.d create mode 100644 ld/testsuite/ld-discard/zero-rel.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 052a2d1..3b97d52 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,27 @@ +2006-11-02 Daniel Jacobowitz + + * libbfd-in.h (_bfd_clear_contents): New prototype. + * reloc.c (_bfd_clear_contents): New. + * libbfd.h: Regenerated. + + * elf32-arm.c (elf32_arm_final_link_relocate): Use + _bfd_clear_contents. + * elf32-d10v.c (elf32_d10v_relocate_section): Likewise. + * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. + * elf32-i386.c (elf_i386_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-sh.c (sh_elf_relocate_section): Likewise. + * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-s390.c (elf_s390_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise. + + * elfxx-ia64.c (elfNN_ia64_relocate_section): Set value to + zero for discarded symbols. + * elfxx-mips.c (mips_elf_calculate_relocation): Likewise. + 2006-11-01 Thiemo Seufer David Ung diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 2faac89..f8eff70 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3664,7 +3664,10 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, from removed linkonce sections, or sections discarded by a linker script. */ if (r_symndx == 0) - return bfd_reloc_ok; + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + return bfd_reloc_ok; + } /* Handle relocations which should use the PLT entry. ABS32/REL32 will use the symbol's value, which may point to a PLT entry, but we diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index e5d546a..8d7cd94 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -469,6 +469,16 @@ elf32_d10v_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } + if (r_symndx == 0) + { + /* r_symndx will be zero only for relocs against symbols from + removed linkonce sections, or sections discarded by a linker + script. For these relocs, we just want the section contents + zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + continue; + } + if (h != NULL) name = h->root.root.string; else diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index db6e842..c448aac 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -3942,8 +3942,14 @@ elf32_hppa_relocate_section (bfd *output_bfd, /* r_symndx will be zero only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ - if (r_symndx == 0 - || (input_section->flags & SEC_ALLOC) == 0) + if (r_symndx == 0) + { + _bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd, + contents + rela->r_offset); + break; + } + + if ((input_section->flags & SEC_ALLOC) == 0) break; /* The reloc types handled here and this conditional diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 97054a5..7a83c73 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2395,17 +2395,12 @@ elf_i386_relocate_section (bfd *output_bfd, if (r_symndx == 0) { - /* r_symndx will be zero only for relocs against symbols from - removed linkonce sections, or sections discarded by a linker - script. For these relocs, we just want the section contents - zeroed. Avoid any special processing in the switch below. */ - r_type = R_386_NONE; - - relocation = 0; - if (howto->pc_relative) - relocation = (input_section->output_section->vma - + input_section->output_offset - + rel->r_offset); + /* r_symndx will be zero only for relocs against symbols from + removed linkonce sections, or sections discarded by a linker + script. For these relocs, we just want the section contents + zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + continue; } switch (r_type) diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 59bac50..281fab0 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6180,7 +6180,10 @@ ppc_elf_relocate_section (bfd *output_bfd, a linker script. */ dodyn: if (r_symndx == 0) - break; + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + break; + } /* Fall thru. */ if ((input_section->flags & SEC_ALLOC) == 0) diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 83bf5e1..01ee6a5 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2543,8 +2543,13 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, /* r_symndx will be zero only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ - if (r_symndx == 0 - || (input_section->flags & SEC_ALLOC) == 0) + if (r_symndx == 0) + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + break; + } + + if ((input_section->flags & SEC_ALLOC) == 0) break; if ((info->shared diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 85f3d8f..8e53056 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3557,6 +3557,15 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_SH_IMM_MEDHI16_PCREL: case R_SH_IMM_HI16_PCREL: #endif + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == 0) + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + continue; + } + if (info->shared && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 34f7f47..59ed4ba 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -2270,6 +2270,16 @@ elf_xtensa_relocate_section (bfd *output_bfd, return FALSE; } + if (r_symndx == 0) + { + /* r_symndx will be zero only for relocs against symbols from + removed linkonce sections, or sections discarded by a linker + script. For these relocs, we just want the section contents + zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + continue; + } + /* There's no point in calling bfd_perform_relocation here. Just go directly to our "special function". */ r = elf_xtensa_do_reloc (howto, input_bfd, input_section, diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 886f987..52b3e62 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -10728,7 +10728,11 @@ ppc64_elf_relocate_section (bfd *output_bfd, a linker script. */ dodyn: if (r_symndx == 0) - break; + { + _bfd_clear_contents (ppc64_elf_howto_table[r_type], input_bfd, + contents + rel->r_offset); + break; + } /* Fall thru. */ dodyn2: diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 1d86820..443f325 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2522,8 +2522,13 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, /* r_symndx will be zero only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ - if (r_symndx == 0 - || (input_section->flags & SEC_ALLOC) == 0) + if (r_symndx == 0) + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + break; + } + + if ((input_section->flags & SEC_ALLOC) == 0) break; if ((info->shared diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 2556fdc..b6c973f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2370,8 +2370,13 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, /* r_symndx will be zero only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ - if (r_symndx == 0 - || (input_section->flags & SEC_ALLOC) == 0) + if (r_symndx == 0) + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + break; + } + + if ((input_section->flags & SEC_ALLOC) == 0) break; if ((info->shared diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index dbea35b..2fc5550 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -4751,6 +4751,12 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, case R_IA64_LTV32LSB: case R_IA64_LTV64MSB: case R_IA64_LTV64LSB: + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == 0) + value = 0; + r = elfNN_ia64_install_value (hit_addr, value, r_type); break; diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 747c91c..8f1fb6d 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -4323,6 +4323,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, input_section)) return bfd_reloc_undefined; } + else if (r_symndx == 0) + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + value = 0; else { if (r_type != R_MIPS_REL32) diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 77ffbfe..3b64aca 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2755,8 +2755,13 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, /* r_symndx will be zero only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ - if (r_symndx == 0 - || (input_section->flags & SEC_ALLOC) == 0) + if (r_symndx == 0) + { + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + break; + } + + if ((input_section->flags & SEC_ALLOC) == 0) break; if ((info->shared diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index a9c96db..3de9ed4 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -547,6 +547,10 @@ extern bfd_reloc_status_type _bfd_final_link_relocate extern bfd_reloc_status_type _bfd_relocate_contents (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *); +/* Clear a given location using a given howto. */ +extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd, + bfd_byte *location); + /* Link stabs in sections in the first pass. */ extern bfd_boolean _bfd_link_section_stabs diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 92dfc15..8c55264 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -552,6 +552,10 @@ extern bfd_reloc_status_type _bfd_final_link_relocate extern bfd_reloc_status_type _bfd_relocate_contents (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *); +/* Clear a given location using a given howto. */ +extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd, + bfd_byte *location); + /* Link stabs in sections in the first pass. */ extern bfd_boolean _bfd_link_section_stabs diff --git a/bfd/reloc.c b/bfd/reloc.c index 09b888f..1b8c8d7 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -1544,6 +1544,72 @@ _bfd_relocate_contents (reloc_howto_type *howto, return flag; } +/* Clear a given location using a given howto, by applying a relocation value + of zero and discarding any in-place addend. This is used for fixed-up + relocations against discarded symbols, to make ignorable debug or unwind + information more obvious. */ + +void +_bfd_clear_contents (reloc_howto_type *howto, + bfd *input_bfd, + bfd_byte *location) +{ + int size; + bfd_vma x = 0; + + /* Get the value we are going to relocate. */ + size = bfd_get_reloc_size (howto); + switch (size) + { + default: + case 0: + abort (); + case 1: + x = bfd_get_8 (input_bfd, location); + break; + case 2: + x = bfd_get_16 (input_bfd, location); + break; + case 4: + x = bfd_get_32 (input_bfd, location); + break; + case 8: +#ifdef BFD64 + x = bfd_get_64 (input_bfd, location); +#else + abort (); +#endif + break; + } + + /* Zero out the unwanted bits of X. */ + x &= ~howto->dst_mask; + + /* Put the relocated value back in the object file. */ + switch (size) + { + default: + case 0: + abort (); + case 1: + bfd_put_8 (input_bfd, x, location); + break; + case 2: + bfd_put_16 (input_bfd, x, location); + break; + case 4: + bfd_put_32 (input_bfd, x, location); + break; + case 8: +#ifdef BFD64 + bfd_put_64 (input_bfd, x, location); +#else + abort (); +#endif + break; + } +} + /* DOCDD INODE diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 42fd441..e222933 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-11-02 Daniel Jacobowitz + + * ld-discard/zero-rel.d, ld-discard/zero-rel.s: New files. + 2006-11-01 Thiemo Seufer * ld-mips-elf/mips16-intermix-1.s, ld-mips-elf/mips16-intermix-2.s, diff --git a/ld/testsuite/ld-discard/zero-rel.d b/ld/testsuite/ld-discard/zero-rel.d new file mode 100644 index 0000000..1f73775 --- /dev/null +++ b/ld/testsuite/ld-discard/zero-rel.d @@ -0,0 +1,8 @@ +#source: zero-rel.s +#ld: -T discard.ld +#objdump: -s -j .debug_info + +.*: file format .*elf.* + +Contents of section .debug_info: + 0000 0+( 0+)? +(\.+) .* diff --git a/ld/testsuite/ld-discard/zero-rel.s b/ld/testsuite/ld-discard/zero-rel.s new file mode 100644 index 0000000..f3f0b3c --- /dev/null +++ b/ld/testsuite/ld-discard/zero-rel.s @@ -0,0 +1,11 @@ + .text + .globl _start +_start: + + .section .debug_info + .long .Ltext + .long .Ltext + 2 + + .section .text.exit,"ax" +.Ltext: + .long 0 -- 2.7.4