PATCH: PR ld/3958: ELF linker failed to handle relocation against STN_UNDEF
H. J. Lu
hjl@lucon.org
Sat Mar 3 23:04:00 GMT 2007
More information about the Binutils mailing list
Sat Mar 3 23:04:00 GMT 2007
- Previous message (by thread): Fix linking of .gpdword on MIPS
- Next message (by thread): PATCH: PR ld/3958: ELF linker failed to handle relocation against STN_UNDEF
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Fri, Mar 02, 2007 at 07:20:02PM -0800, H. J. Lu wrote: > On Wed, Feb 28, 2007 at 12:05:30PM +1030, Alan Modra wrote: > > On Tue, Feb 27, 2007 at 05:22:41PM -0800, H. J. Lu wrote: > > > There are no regressions with my patch. But I don't know if there > > > are testcases to check ld -r and ld -emit-relocs for this specific > > > case. > > > > I don't think there is a testcase for this case in the testsuite. > > I'll approve your patch if you implement what I suggested in my last > > email. > > > > Here is the updated patch with a testcase for -r and a testcase for > -emit-relocs. > This adds a bit field to Elf_Internal_Rela. This patch uses more memory. But we shouldn't use STN_UNDEF to indicate relocations against symbols from removed input sections since STN_UNDEF simply means 0 as the symbol value for relocation. H.J. --- bfd/ 2007-03-03 H.J. Lu <hongjiu.lu@intel.com> PR ld/3958 * elf32-arm.c (elf32_arm_final_link_relocate): Check r_discarded for relocations against symbols from removed input sections. * 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-score.c (score_elf_final_link_relocate): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise. * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_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-ia64.c (elfNN_ia64_relocate_section): Likewise. * elfxx-mips.c (mips_elf_calculate_relocation): Likewise. * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise. * elf32-xtensa.c (move_literal): Initialize r_discarded to 0. * elf64-mips.c (mips_elf64_be_swap_reloc_in): Likewise. (mips_elf64_be_swap_reloca_in): Likewise. * elfcode.h (elf_swap_reloc_in): Likewise. (elf_swap_reloca_in): Likewise. * elflink.c (elf_link_input_bfd): Set r_discarded to 1 for relocations against symbols from removed input sections. include/elf/ 2007-03-03 H.J. Lu <hongjiu.lu@intel.com> * internal.h (Elf_Internal_Rela): Add r_discarded. ld/testsuite/ 2007-03-03 H.J. Lu <hongjiu.lu@intel.com> PR ld/3958 * ld-elf/linkonce1.d: New file. * ld-elf/linkonce1a.s: Likewise. * ld-elf/linkonce1b.s: Likewise. * ld-elf/linkonce2.d: Likewise. * ld-i386/pcrel16abs.d: Likewise. * ld-i386/pcrel16abs.s: Likewise. * ld-i386/i386.exp: Run "pcrel16abs". --- binutils/bfd/elf32-arm.c.abs 2007-03-01 14:53:13.000000000 -0800 +++ binutils/bfd/elf32-arm.c 2007-03-03 14:48:39.000000000 -0800 @@ -4524,10 +4524,7 @@ elf32_arm_final_link_relocate (reloc_how case R_ARM_XPC25: case R_ARM_PREL31: case R_ARM_PLT32: - /* 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); return bfd_reloc_ok; --- binutils/bfd/elf32-d10v.c.abs 2006-11-02 19:36:06.000000000 -0800 +++ binutils/bfd/elf32-d10v.c 2007-03-03 14:25:46.000000000 -0800 @@ -469,12 +469,11 @@ elf32_d10v_relocate_section (bfd *output unresolved_reloc, warned); } - if (r_symndx == 0) + if (rel->r_discarded) { - /* 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. */ + /* 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); continue; } --- binutils/bfd/elf32-hppa.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elf32-hppa.c 2007-03-03 14:26:40.000000000 -0800 @@ -3939,10 +3939,7 @@ elf32_hppa_relocate_section (bfd *output case R_PARISC_DPREL14R: case R_PARISC_DPREL21L: case R_PARISC_DIR32: - /* 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) + if (rela->r_discarded) { _bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd, contents + rela->r_offset); --- binutils/bfd/elf32-i386.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elf32-i386.c 2007-03-03 14:26:54.000000000 -0800 @@ -2414,12 +2414,11 @@ elf_i386_relocate_section (bfd *output_b unresolved_reloc, warned); } - if (r_symndx == 0) + if (rel->r_discarded) { - /* 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. */ + /* 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); continue; } --- binutils/bfd/elf32-ppc.c.abs 2007-02-01 12:42:10.000000000 -0800 +++ binutils/bfd/elf32-ppc.c 2007-03-03 14:27:17.000000000 -0800 @@ -6225,11 +6225,8 @@ ppc_elf_relocate_section (bfd *output_bf case R_PPC_ADDR14_BRNTAKEN: case R_PPC_UADDR32: case R_PPC_UADDR16: - /* r_symndx will be zero only for relocs against symbols - from removed linkonce sections, or sections discarded by - a linker script. */ dodyn: - if (r_symndx == 0) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); break; --- binutils/bfd/elf32-s390.c.abs 2006-11-02 19:36:07.000000000 -0800 +++ binutils/bfd/elf32-s390.c 2007-03-03 14:27:40.000000000 -0800 @@ -2540,10 +2540,7 @@ elf_s390_relocate_section (output_bfd, i case R_390_PC16DBL: case R_390_PC32DBL: case R_390_PC32: - /* 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); break; --- binutils/bfd/elf32-score.c.abs 2007-01-30 07:59:53.000000000 -0800 +++ binutils/bfd/elf32-score.c 2007-03-03 14:27:56.000000000 -0800 @@ -2006,10 +2006,7 @@ score_elf_final_link_relocate (reloc_how 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. */ + else if (rel->r_discarded) value = 0; else { --- binutils/bfd/elf32-sh.c.abs 2006-11-02 19:36:07.000000000 -0800 +++ binutils/bfd/elf32-sh.c 2007-03-03 14:28:16.000000000 -0800 @@ -3557,10 +3557,7 @@ sh_elf_relocate_section (bfd *output_bfd 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); continue; --- binutils/bfd/elf32-xtensa.c.abs 2007-03-02 11:46:35.000000000 -0800 +++ binutils/bfd/elf32-xtensa.c 2007-03-03 14:40:15.000000000 -0800 @@ -2241,12 +2241,11 @@ elf_xtensa_relocate_section (bfd *output return FALSE; } - if (r_symndx == 0) + if (rel->r_discarded) { - /* 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. */ + /* 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); continue; } @@ -8708,6 +8707,7 @@ move_literal (bfd *abfd, this_rela.r_info = ELF32_R_INFO (0, r_type); this_rela.r_addend = r_rel->target_offset - r_reloc_get_target_offset (r_rel); + this_rela.r_discarded = 0; bfd_put_32 (abfd, lit->value, contents + offset); /* Currently, we cannot move relocations during a relocatable link. */ --- binutils/bfd/elf64-alpha.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elf64-alpha.c 2007-03-03 14:38:42.000000000 -0800 @@ -4210,11 +4210,11 @@ elf64_alpha_relocate_section (bfd *outpu case R_ALPHA_GPREL32: /* If the target section was a removed linkonce section, - r_symndx will be zero. In this case, assume that the - switch will not be used, so don't fill it in. If we - do nothing here, we'll get relocation truncated messages, - due to the placement of the application above 4GB. */ - if (r_symndx == 0) + assume that the switch will not be used, so don't fill it + in. If we do nothing here, we'll get relocation truncated + messages, due to the placement of the application above + 4GB. */ + if (rel->r_discarded) { r = bfd_reloc_ok; break; @@ -4412,10 +4412,9 @@ elf64_alpha_relocate_section (bfd *outpu } - /* ??? .eh_frame references to discarded sections will be smashed - to relocations against SHN_UNDEF. The .eh_frame format allows - NULL to be encoded as 0 in any format, so this works here. */ - if (r_symndx == 0) + /* The .eh_frame format allows NULL to be encoded as 0 in any + format, so this works here. */ + if (rel->r_discarded) howto = (elf64_alpha_howto_table + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG)); goto default_reloc; --- binutils/bfd/elf64-mips.c.abs 2006-10-28 14:23:34.000000000 -0700 +++ binutils/bfd/elf64-mips.c 2007-03-03 14:18:50.000000000 -0800 @@ -1735,12 +1735,15 @@ mips_elf64_be_swap_reloc_in (bfd *abfd, dst[0].r_offset = mirel.r_offset; dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type); dst[0].r_addend = 0; + dst[0].r_discarded = 0; dst[1].r_offset = mirel.r_offset; dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2); dst[1].r_addend = 0; + dst[1].r_discarded = 0; dst[2].r_offset = mirel.r_offset; dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3); dst[2].r_addend = 0; + dst[2].r_discarded = 0; } /* Swap in a MIPS 64-bit Rela reloc. */ @@ -1758,12 +1761,15 @@ mips_elf64_be_swap_reloca_in (bfd *abfd, dst[0].r_offset = mirela.r_offset; dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type); dst[0].r_addend = mirela.r_addend; + dst[0].r_discarded = 0; dst[1].r_offset = mirela.r_offset; dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2); dst[1].r_addend = 0; + dst[1].r_discarded = 0; dst[2].r_offset = mirela.r_offset; dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3); dst[2].r_addend = 0; + dst[2].r_discarded = 0; } /* Swap out a MIPS 64-bit Rel reloc. */ --- binutils/bfd/elf64-ppc.c.abs 2007-03-01 14:53:13.000000000 -0800 +++ binutils/bfd/elf64-ppc.c 2007-03-03 14:39:00.000000000 -0800 @@ -10831,11 +10831,8 @@ ppc64_elf_relocate_section (bfd *output_ case R_PPC64_UADDR16: case R_PPC64_UADDR32: case R_PPC64_UADDR64: - /* r_symndx will be zero only for relocs against symbols - from removed linkonce sections, or sections discarded by - a linker script. */ dodyn: - if (r_symndx == 0) + if (rel->r_discarded) { _bfd_clear_contents (ppc64_elf_howto_table[r_type], input_bfd, contents + rel->r_offset); --- binutils/bfd/elf64-s390.c.abs 2006-11-02 19:36:09.000000000 -0800 +++ binutils/bfd/elf64-s390.c 2007-03-03 14:32:31.000000000 -0800 @@ -2519,10 +2519,7 @@ elf_s390_relocate_section (output_bfd, i case R_390_PC32: case R_390_PC32DBL: case R_390_PC64: - /* 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); break; --- binutils/bfd/elf64-x86-64.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elf64-x86-64.c 2007-03-03 14:32:53.000000000 -0800 @@ -2387,11 +2387,7 @@ elf64_x86_64_relocate_section (bfd *outp case R_X86_64_64: /* FIXME: The ABI says the linker should make sure the value is the same when it's zeroextended to 64 bit. */ - - /* 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); break; --- binutils/bfd/elfcode.h.abs 2007-02-05 17:27:15.000000000 -0800 +++ binutils/bfd/elfcode.h 2007-03-03 14:54:43.000000000 -0800 @@ -387,6 +387,7 @@ elf_swap_reloc_in (bfd *abfd, dst->r_offset = H_GET_WORD (abfd, src->r_offset); dst->r_info = H_GET_WORD (abfd, src->r_info); dst->r_addend = 0; + dst->r_discarded = 0; } void @@ -398,6 +399,7 @@ elf_swap_reloca_in (bfd *abfd, dst->r_offset = H_GET_WORD (abfd, src->r_offset); dst->r_info = H_GET_WORD (abfd, src->r_info); dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend); + dst->r_discarded = 0; } /* Translate an ELF reloc from internal format to external format. */ --- binutils/bfd/elflink.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elflink.c 2007-03-03 14:13:20.000000000 -0800 @@ -8488,6 +8488,7 @@ elf_link_input_bfd (struct elf_final_lin fde as bogus. */ rel->r_info &= r_type_mask; rel->r_addend = 0; + rel->r_discarded = 1; } } } --- binutils/bfd/elfxx-ia64.c.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/bfd/elfxx-ia64.c 2007-03-03 14:36:32.000000000 -0800 @@ -4752,10 +4752,7 @@ elfNN_ia64_relocate_section (output_bfd, 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) + if (rel->r_discarded) value = 0; r = elfNN_ia64_install_value (hit_addr, value, r_type); @@ -4998,7 +4995,7 @@ elfNN_ia64_relocate_section (output_bfd, case R_IA64_SEGREL32LSB: case R_IA64_SEGREL64MSB: case R_IA64_SEGREL64LSB: - if (r_symndx == 0) + if (rel->r_discarded) { /* If the input section was discarded from the output, then do nothing. */ --- binutils/bfd/elfxx-mips.c.abs 2007-03-01 14:53:14.000000000 -0800 +++ binutils/bfd/elfxx-mips.c 2007-03-03 14:36:18.000000000 -0800 @@ -4323,10 +4323,7 @@ mips_elf_calculate_relocation (bfd *abfd 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. */ + else if (relocation->r_discarded) value = 0; else { --- binutils/bfd/elfxx-sparc.c.abs 2006-11-02 19:36:09.000000000 -0800 +++ binutils/bfd/elfxx-sparc.c 2007-03-03 14:34:43.000000000 -0800 @@ -2752,10 +2752,7 @@ _bfd_sparc_elf_relocate_section (bfd *ou case R_SPARC_L44: case R_SPARC_UA64: r_sparc_plt32: - /* 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) + if (rel->r_discarded) { _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); break; --- binutils/include/elf/internal.h.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/include/elf/internal.h 2007-03-03 14:15:56.000000000 -0800 @@ -122,6 +122,9 @@ typedef struct elf_internal_rela { bfd_vma r_offset; /* Location at which to apply the action */ bfd_vma r_info; /* Index and Type of relocation */ bfd_vma r_addend; /* Constant addend used to compute value */ + /* Whether the reloation is against a symbol from discarded section + or removed link-once sections. */ + unsigned int r_discarded : 1; } Elf_Internal_Rela; /* dynamic section structure */ --- binutils/ld/testsuite/ld-elf/linkonce1.d.abs 2007-03-02 19:13:05.000000000 -0800 +++ binutils/ld/testsuite/ld-elf/linkonce1.d 2007-03-02 17:55:41.000000000 -0800 @@ -0,0 +1,12 @@ +#source: linkonce1a.s +#source: linkonce1b.s +#ld: -r +#objdump: -r + +.*: file format .* + +RELOCATION RECORDS FOR \[.debug_frame\]: +OFFSET[ ]+TYPE[ ]+VALUE[ ]* +0+[ ]+R_[0-9A-Z_]+[ ]+\*ABS\* + +#pass --- binutils/ld/testsuite/ld-elf/linkonce1a.s.abs 2007-03-02 19:13:01.000000000 -0800 +++ binutils/ld/testsuite/ld-elf/linkonce1a.s 2007-03-02 17:48:13.000000000 -0800 @@ -0,0 +1,3 @@ + .section .gnu.linkonce.d.dummy,"aw" +bar: + .long 0 --- binutils/ld/testsuite/ld-elf/linkonce1b.s.abs 2007-03-02 19:12:59.000000000 -0800 +++ binutils/ld/testsuite/ld-elf/linkonce1b.s 2007-03-02 17:48:02.000000000 -0800 @@ -0,0 +1,17 @@ + .globl main + .globl start + .globl _start + .globl __start + .text +main: +start: +_start: +__start: + .long 0 + + .section .gnu.linkonce.d.dummy,"aw" + .long 0 +foo: + .long 0 + .section .debug_frame,"",@progbits + .long foo --- binutils/ld/testsuite/ld-elf/linkonce2.d.abs 2007-03-02 19:13:09.000000000 -0800 +++ binutils/ld/testsuite/ld-elf/linkonce2.d 2007-03-02 17:56:26.000000000 -0800 @@ -0,0 +1,12 @@ +#source: linkonce1a.s +#source: linkonce1b.s +#ld: -emit-relocs +#objdump: -r + +.*: file format .* + +RELOCATION RECORDS FOR \[.debug_frame\]: +OFFSET[ ]+TYPE[ ]+VALUE[ ]* +0+[ ]+R_[0-9A-Z_]+[ ]+\*ABS\* + +#pass --- binutils/ld/testsuite/ld-i386/i386.exp.abs 2007-03-02 15:10:48.000000000 -0800 +++ binutils/ld/testsuite/ld-i386/i386.exp 2007-03-02 17:59:22.000000000 -0800 @@ -113,4 +113,5 @@ run_ld_link_tests $i386tests run_dump_test "abs" run_dump_test "pcrel8" run_dump_test "pcrel16" +run_dump_test "pcrel16abs" run_dump_test "alloc" --- binutils/ld/testsuite/ld-i386/pcrel16abs.d.abs 2007-03-02 15:10:49.000000000 -0800 +++ binutils/ld/testsuite/ld-i386/pcrel16abs.d 2007-03-02 17:59:22.000000000 -0800 @@ -0,0 +1,12 @@ +#name: PCREL16 absolute reloc +#as: --32 +#ld: -melf_i386 -Ttext 0xfffffff0 +#objdump: -drj.text -m i8086 + +.*: +file format elf32-i386 + +Disassembly of section .text: + +f+0 <_start>: +f+0: e9 0d e0[ ]+jmp[ ]+ffffe000 <SEGMENT_SIZE\+0xfffee000> +#pass --- binutils/ld/testsuite/ld-i386/pcrel16abs.s.abs 2007-03-02 15:10:49.000000000 -0800 +++ binutils/ld/testsuite/ld-i386/pcrel16abs.s 2007-03-02 17:59:22.000000000 -0800 @@ -0,0 +1,6 @@ +SEGMENT_SIZE = 0x10000 +RVECTOR = 0x00010 +.code16 + .globl _start +_start: + jmp SEGMENT_SIZE-(0x1f00 +0xf0 +RVECTOR)
- Previous message (by thread): Fix linking of .gpdword on MIPS
- Next message (by thread): PATCH: PR ld/3958: ELF linker failed to handle relocation against STN_UNDEF
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list