[binutils-gdb] x86: Generate PLT32 relocation for ".long foo@PLT - .L4"
"H.J. Lu via Binutils-cvs" <[email protected]> Wed, 29 Jul 2026 21:44:35 +0000 (GMT)
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D53902b30c66a= d5edc95db93e8d5c1cb3c29d684d commit 53902b30c66ad5edc95db93e8d5c1cb3c29d684d Author: H.J. Lu <[email protected]> Date: Fri Jul 24 07:01:35 2026 +0800 x86: Generate PLT32 relocation for ".long foo@PLT - .L4" =20 LLVM assembler supports directives like ".long foo@PLT - .L4" for i386 and x86-64. Implement the same feature to generate PLT32 relocation for directives like ".long foo@PLT - .L4" so that PLT entries are used to resolve the PC32 relocation against function symbols. =20 bfd/ =20 PR gas/34423 * elf32-i386.c (elf_i386_reloc_type_lookup): Handle BFD_RELOC_386_PC32_TO_PLT32. * elf64-x86-64.c (x86_64_reloc_map): Add BFD_RELOC_X86_64_PC32_TO_PLT32. * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_386_PC32_TO_PLT32 and BFD_RELOC_X86_64_PC32_TO_PLT32. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. =20 gas/ =20 PR gas/34423 * config/tc-i386.c (x86_cons): Return BFD_RELOC_X86_64_PC32_TO_PLT32 or BFD_RELOC_386_PC32_TO_PLT32 for directives like ".long foo@PLT - .L4". (md_apply_fix): Compute addend for BFD_RELOC_386_PC32_TO_PLT32. (tc_gen_reloc): Handle BFD_RELOC_X86_64_PC32_TO_PLT32 and BFD_RELOC_386_PC32_TO_PLT32. Compute addend like BFD_RELOC_32_PCREL for BFD_RELOC_X86_64_PC32_TO_PLT32. * testsuite/gas/i386/i386.exp: Run plt test. * testsuite/gas/i386/ilp32/reloc64.l: Updated. * testsuite/gas/i386/ilp32/reloc64.s: Replace ".long xtrn@plt -= ." with ".long xtrn@plt - _start". * testsuite/gas/i386/ilp32/x86-64-jump-table.d: New file. * testsuite/gas/i386/plt.d: Likewise. * testsuite/gas/i386/plt.s: Likewise. * testsuite/gas/i386/reloc32.l: Updated. * testsuite/gas/i386/reloc32.s: Replace ".long xtrn@plt - ." with ".long xtrn@plt - _start". * testsuite/gas/i386/reloc64.l: Updated. * testsuite/gas/i386/reloc64.s: Replace ".long xtrn@plt - ." wi= th ".long xtrn@plt - ptr". * testsuite/gas/i386/x86-64-jump-table.d: New file. * testsuite/gas/i386/x86-64-jump-table.d: Likewise. * testsuite/gas/i386/x86-64-jump-table.s: Likewise. * testsuite/gas/i386/x86-64.exp: Run x86-64-jump-table. =20 ld/ =20 PR gas/34423 * testsuite/ld-x86-64/pr34423.c: New file. * testsuite/ld-x86-64/x86-64-jump-table.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run gas/34423 tests. =20 Signed-off-by: H.J. Lu <[email protected]> Diff: --- bfd/bfd-in2.h | 2 ++ bfd/elf32-i386.c | 4 +++ bfd/elf64-x86-64.c | 1 + bfd/libbfd.h | 2 ++ bfd/reloc.c | 4 +++ gas/config/tc-i386.c | 33 ++++++++++++++--- gas/testsuite/gas/i386/i386.exp | 2 ++ gas/testsuite/gas/i386/ilp32/reloc64.l | 3 +- gas/testsuite/gas/i386/ilp32/reloc64.s | 2 +- gas/testsuite/gas/i386/ilp32/x86-64-jump-table.d | 4 +++ gas/testsuite/gas/i386/plt.d | 14 ++++++++ gas/testsuite/gas/i386/plt.s | 7 ++++ gas/testsuite/gas/i386/reloc32.l | 4 +-- gas/testsuite/gas/i386/reloc32.s | 2 +- gas/testsuite/gas/i386/reloc64.l | 3 +- gas/testsuite/gas/i386/reloc64.s | 2 +- gas/testsuite/gas/i386/x86-64-jump-table.d | 29 +++++++++++++++ gas/testsuite/gas/i386/x86-64-jump-table.s | 31 ++++++++++++++++ gas/testsuite/gas/i386/x86-64.exp | 2 ++ ld/testsuite/ld-x86-64/pr34423.c | 46 ++++++++++++++++++++= ++++ ld/testsuite/ld-x86-64/x86-64-jump-table.s | 30 ++++++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 16 +++++++++ 22 files changed, 230 insertions(+), 13 deletions(-) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index e49d67316f3..e55bde7b129 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3899,6 +3899,7 @@ enum bfd_reloc_code_real /* i386/elf relocations. */ BFD_RELOC_386_GOT32, BFD_RELOC_386_PLT32, + BFD_RELOC_386_PC32_TO_PLT32, BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE, @@ -3937,6 +3938,7 @@ enum bfd_reloc_code_real BFD_RELOC_X86_64_TLSDESC, BFD_RELOC_X86_64_PC32_BND, BFD_RELOC_X86_64_PLT32_BND, + BFD_RELOC_X86_64_PC32_TO_PLT32, BFD_RELOC_X86_64_GOTPCRELX, BFD_RELOC_X86_64_REX_GOTPCRELX, BFD_RELOC_X86_64_CODE_4_GOTPCRELX, diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 954803fcc3f..ae9276cff06 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -331,6 +331,10 @@ elf_i386_reloc_type_lookup (bfd *abfd, TRACE ("BFD_RELOC_386_GOT32X"); return &elf_howto_table[R_386_GOT32X - R_386_tls_offset]; =20 + case BFD_RELOC_386_PC32_TO_PLT32: + TRACE ("BFD_RELOC_X86_PC32_TO_PLT32"); + return &elf_howto_table[R_386_PLT32]; + case BFD_RELOC_VTABLE_INHERIT: TRACE ("BFD_RELOC_VTABLE_INHERIT"); return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset]; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 575995d4957..ade6613b62a 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -281,6 +281,7 @@ static const struct elf_reloc_map x86_64_reloc_map[] =3D { BFD_RELOC_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTPCRELX, }, { BFD_RELOC_X86_64_CODE_6_GOTTPOFF, R_X86_64_CODE_6_GOTTPOFF, }, { BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPC32_TLSDE= SC, }, + { BFD_RELOC_X86_64_PC32_TO_PLT32, R_X86_64_PLT32, }, { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, }; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 27bc0875cf6..6e737e468df 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1430,6 +1430,7 @@ static const char *const bfd_reloc_code_real_names[] = =3D { "@@uninitialized@@", "BFD_RELOC_MN10300_TLS_TPOFF", "BFD_RELOC_386_GOT32", "BFD_RELOC_386_PLT32", + "BFD_RELOC_386_PC32_TO_PLT32", "BFD_RELOC_386_TLS_TPOFF", "BFD_RELOC_386_TLS_IE", "BFD_RELOC_386_TLS_GOTIE", @@ -1466,6 +1467,7 @@ static const char *const bfd_reloc_code_real_names[] = =3D { "@@uninitialized@@", "BFD_RELOC_X86_64_TLSDESC", "BFD_RELOC_X86_64_PC32_BND", "BFD_RELOC_X86_64_PLT32_BND", + "BFD_RELOC_X86_64_PC32_TO_PLT32", "BFD_RELOC_X86_64_GOTPCRELX", "BFD_RELOC_X86_64_REX_GOTPCRELX", "BFD_RELOC_X86_64_CODE_4_GOTPCRELX", diff --git a/bfd/reloc.c b/bfd/reloc.c index 6b9e00da5d6..29288f8099d 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2319,6 +2319,8 @@ ENUM BFD_RELOC_386_GOT32 ENUMX BFD_RELOC_386_PLT32 +ENUMX + BFD_RELOC_386_PC32_TO_PLT32 ENUMX BFD_RELOC_386_TLS_TPOFF ENUMX @@ -2394,6 +2396,8 @@ ENUMX BFD_RELOC_X86_64_PC32_BND ENUMX BFD_RELOC_X86_64_PLT32_BND +ENUMX + BFD_RELOC_X86_64_PC32_TO_PLT32 ENUMX BFD_RELOC_X86_64_GOTPCRELX ENUMX diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d1ef80ce6d1..67badd29298 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -13553,10 +13553,20 @@ x86_cons (expressionS *exp, int size) || got_reloc =3D=3D BFD_RELOC_32_PLT_PCREL) && exp->X_op !=3D O_symbol) { - char c =3D *input_line_pointer; - *input_line_pointer =3D 0; - as_bad (_("invalid PLT expression `%s'"), save); - *input_line_pointer =3D c; + /* Allow directives like ".long foo@PLT - .L4". + BFD_RELOC_X86_64_PC32_TO_PLT32 has an explicit addend and + BFD_RELOC_386_PC32_TO_PLT32 has an implicit addend. */ + if (size =3D=3D 4 && exp->X_op =3D=3D O_subtract) + got_reloc =3D (object_64bit + ? BFD_RELOC_X86_64_PC32_TO_PLT32 + : BFD_RELOC_386_PC32_TO_PLT32); + else + { + char c =3D *input_line_pointer; + *input_line_pointer =3D 0; + as_bad (_("invalid PLT expression `%s'"), save); + *input_line_pointer =3D c; + } } } } @@ -16781,6 +16791,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg A= TTRIBUTE_UNUSED) value =3D -4; break; =20 + case BFD_RELOC_386_PC32_TO_PLT32: + /* Set the implicit addend. */ + value =3D (seg->vma - fixP->fx_size + fixP->fx_addnumber + + md_pcrel_from (fixP)); + break; + case BFD_RELOC_386_TLS_GD: case BFD_RELOC_386_TLS_LDM: case BFD_RELOC_386_TLS_IE_32: @@ -18586,6 +18602,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, f= ixS *fixp) case BFD_RELOC_386_TLS_LE: case BFD_RELOC_386_TLS_GOTDESC: case BFD_RELOC_386_TLS_DESC_CALL: + case BFD_RELOC_386_PC32_TO_PLT32: case BFD_RELOC_X86_64_TLSGD: case BFD_RELOC_X86_64_TLSLD: case BFD_RELOC_X86_64_DTPOFF32: @@ -18608,6 +18625,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, f= ixS *fixp) case BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC: case BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC: case BFD_RELOC_X86_64_TLSDESC_CALL: + case BFD_RELOC_X86_64_PC32_TO_PLT32: case BFD_RELOC_RVA: case BFD_RELOC_VTABLE_ENTRY: case BFD_RELOC_VTABLE_INHERIT: @@ -18751,6 +18769,13 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, = fixS *fixp) case BFD_RELOC_X86_64_TLSDESC_CALL: rel->addend =3D fixp->fx_offset - fixp->fx_size; break; + case BFD_RELOC_X86_64_PC32_TO_PLT32: + /* This came from a directive like ".long foo@PLT - .L4". + Generate R_X86_64_PLT32 with addend computed like + R_X86_64_PC32 so that PLT entry is used to resolve + this PC32 relocation. */ + code =3D BFD_RELOC_32_PLT_PCREL; + /* Fall through. */ default: rel->addend =3D (section->vma - fixp->fx_size diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.= exp index e27bca0f69c..22fd3412d53 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -792,6 +792,8 @@ if [gas_32_check] then { =20 run_dump_test "no-got" =20 + run_dump_test "plt" + run_dump_test "gotx-default" run_dump_test "no-gotx-default" =20 diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.l b/gas/testsuite/gas/i38= 6/ilp32/reloc64.l index 14a111d763f..08c2702cdb7 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.l +++ b/gas/testsuite/gas/i386/ilp32/reloc64.l @@ -103,8 +103,6 @@ .*:176: Info: .* .*:3: Error: .* .*:177: Info: .* -.*:3: Error: .* -.*:190: Info: .* .*:193: Error: .* too large for field of 4 bytes at .* .*:194: Error: .* too large for field of 4 bytes at .* .*:195: Error: .* too large for field of 4 bytes at .* @@ -113,6 +111,7 @@ .*:197: Error: .* too large for field of 1 byte at .* .*:198: Error: .* too large for field of 2 bytes at .* .*:198: Error: .* too large for field of 1 byte at .* +.*:190: Error: can't resolve xtrn - _start .*:201: Error: .* too large for field of 4 bytes at .* .*:202: Error: .* too large for field of 2 bytes at .* .*:203: Error: .* too large for field of 2 bytes at .* diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i38= 6/ilp32/reloc64.s index db2d2acdf5d..a4ccdb29916 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.s +++ b/gas/testsuite/gas/i386/ilp32/reloc64.s @@ -187,7 +187,7 @@ bad .byte xtrn@tpoff .quad xtrn - 0x80000000 .long xtrn@got - 4 .long xtrn@got + 4 -bad .long xtrn@plt - . +bad .long xtrn@plt - _start =20 .text bad add $x+0x123456789, %rax diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-jump-table.d b/gas/testsui= te/gas/i386/ilp32/x86-64-jump-table.d new file mode 100644 index 00000000000..2cff87d4445 --- /dev/null +++ b/gas/testsuite/gas/i386/ilp32/x86-64-jump-table.d @@ -0,0 +1,4 @@ +#source: ../x86-64-jump-table.s +#readelf: -rsW +#name: x86-64 (ILP32) PIC jump table +#dump: ../x86-64-jump-table.d diff --git a/gas/testsuite/gas/i386/plt.d b/gas/testsuite/gas/i386/plt.d new file mode 100644 index 00000000000..e4af0d20c87 --- /dev/null +++ b/gas/testsuite/gas/i386/plt.d @@ -0,0 +1,14 @@ +#as: +#readelf: -x .rodata -r + +Relocation section '.rel.rodata' at offset 0xd4 contains 4 entries: + Offset Info Type Sym.Value Sym. Name +0+ 00000104 R_386_PLT32 00000000 foo1 +0+4 00000204 R_386_PLT32 00000000 foo2 +0+8 00000304 R_386_PLT32 00000000 foo3 +0+c 00000404 R_386_PLT32 00000000 foo4 + +Hex dump of section '.rodata': + NOTE: This section has relocations against it, but these have NOT been ap= plied to this dump. + 0x00000000 00000000 04000000 08000000 0c000000 ................ +#pass diff --git a/gas/testsuite/gas/i386/plt.s b/gas/testsuite/gas/i386/plt.s new file mode 100644 index 00000000000..c854c3fe739 --- /dev/null +++ b/gas/testsuite/gas/i386/plt.s @@ -0,0 +1,7 @@ + + .section .rodata +.L4: + .long foo1@PLT - .L4 + .long foo2@PLT - .L4 + .long foo3@PLT - .L4 + .long foo4@PLT - .L4 diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/relo= c32.l index 71c65212dc9..31c71a0be28 100644 --- a/gas/testsuite/gas/i386/reloc32.l +++ b/gas/testsuite/gas/i386/reloc32.l @@ -131,6 +131,6 @@ .*:160: Info: .* .*:3: Error: .* .*:161: Info: .* -.*:3: Error: .* -.*:164: Info: .* +.*:56: Error: .* +.*:164: Error: .* #pass diff --git a/gas/testsuite/gas/i386/reloc32.s b/gas/testsuite/gas/i386/relo= c32.s index 5616cd57e3f..0ba69eae4d0 100644 --- a/gas/testsuite/gas/i386/reloc32.s +++ b/gas/testsuite/gas/i386/reloc32.s @@ -161,7 +161,7 @@ bad .byte xtrn@ntpoff bad .byte xtrn@tpoff .long xtrn@got + 4 .long xtrn@got - 4 -bad .long xtrn@plt - . +bad .long xtrn@plt - _start =20 .text movl $ptr@PLT, %eax diff --git a/gas/testsuite/gas/i386/reloc64.l b/gas/testsuite/gas/i386/relo= c64.l index c60c45d139a..d84d9042958 100644 --- a/gas/testsuite/gas/i386/reloc64.l +++ b/gas/testsuite/gas/i386/reloc64.l @@ -163,5 +163,4 @@ .*:219: Info: .* .*:3: Error: .* .*:220: Info: .* -.*:3: Error: .* -.*:227: Info: .* +.*:227: Error: can't resolve xtrn - ptr diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/relo= c64.s index 5c0f4136a09..f248964813f 100644 --- a/gas/testsuite/gas/i386/reloc64.s +++ b/gas/testsuite/gas/i386/reloc64.s @@ -224,7 +224,7 @@ bad .byte xtrn@gotplt mov xtrn(,%ebx), %eax vgatherdps %xmm2, xtrn(,%xmm1), %xmm0 addr32 vgatherdps %xmm2, xtrn(,%xmm1), %xmm0 -bad .long xtrn@plt - . +bad .long xtrn@plt - ptr =20 .text movabs $ptr@GOT, %rax diff --git a/gas/testsuite/gas/i386/x86-64-jump-table.d b/gas/testsuite/gas= /i386/x86-64-jump-table.d new file mode 100644 index 00000000000..32c957b6ba6 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-jump-table.d @@ -0,0 +1,29 @@ +#as: +#readelf: -rsW +#name: x86-64 PIC jump table +#notarget: *-*-solaris* + +#... +Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +0+8 0+40+2 +R_X86_64_PC32 +0+ +bar0 - 4 +0+f 0+20+2 +R_X86_64_PC32 +0+ +.rodata - 4 +0+20 0+50+4 +R_X86_64_PLT32 +0+ +bar2 - 4 +#... +Relocation section '.rela.rodata' at offset 0x[0-9a-f]+ contains 5 entries: + +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend +0+ 0+40+4 +R_X86_64_PLT32 +0+ +bar0 \+ 0 +0+4 0+60+4 +R_X86_64_PLT32 +0+ +bar1 \+ 4 +0+8 0+10+2 +R_X86_64_PC32 +0+ +.text \+ 27 +0+c 0+70+4 +R_X86_64_PLT32 +0+ +bar3 \+ c +0+10+ 0+80+4 +R_X86_64_PLT32 +0+ +bar4 \+ 10 +#... + +[0-9]+: 0+ +0 SECTION LOCAL +DEFAULT +1 .text + +[0-9]+: 0+ +0 SECTION LOCAL +DEFAULT +5 .rodata + +[0-9]+: 0+ +36 FUNC +GLOBAL +DEFAULT +1 foo + +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND bar0 + +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND bar2 + +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND bar1 + +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND bar3 + +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND bar4 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-jump-table.s b/gas/testsuite/gas= /i386/x86-64-jump-table.s new file mode 100644 index 00000000000..aefffad8f65 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-jump-table.s @@ -0,0 +1,31 @@ +# Check R_X86_64_PLT32 relocation in jump table. + + .text + .p2align 4 + .globl foo + .type foo, @function +foo: + .cfi_startproc + cmpl $4, %edi + ja .L1 + leaq bar0(%rip), %rdx + leaq .L4(%rip), %rdx + movl %edi, %edi + movslq (%rdx,%rdi,4), %rax + addq %rdx, %rax + jmp *%rax +.L1: + ret +.Lbar2: + jmp bar2 + .cfi_endproc + .size foo, .-foo + .section .rodata + .p2align 2 +.L4: + .long [email protected] + .long [email protected] + .long .Lbar2-.L4 + .long [email protected] + .long [email protected] + .section .note.GNU-stack,"",@progbits diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86= -64.exp index 58382b55e31..710f749a8dc 100644 --- a/gas/testsuite/gas/i386/x86-64.exp +++ b/gas/testsuite/gas/i386/x86-64.exp @@ -778,6 +778,8 @@ if [is_elf_format] then { run_dump_test "reloc-section-sym-all" run_dump_test "reloc-section-sym-internal" run_dump_test "reloc-section-sym-none" + + run_dump_test "x86-64-jump-table" } run_dump_test pr27198 run_dump_test pr29483 diff --git a/ld/testsuite/ld-x86-64/pr34423.c b/ld/testsuite/ld-x86-64/pr34= 423.c new file mode 100644 index 00000000000..fc5a943a54a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr34423.c @@ -0,0 +1,46 @@ +#include <stdio.h> + +int +bar0 (void) +{ + return 0; +} + +int +bar1 (void) +{ + return 1; +} + +int +bar2 (void) +{ + return 2; +} + +int +bar3 (void) +{ + return 3; +} + +int +bar4 (void) +{ + return 4; +} + +extern int foo (int); + +int +main () +{ + if (foo (1) =3D=3D 1 + && foo (3) =3D=3D 3 + && foo (4) =3D=3D 4 + && foo (2) =3D=3D 2 + && foo (0) =3D=3D 0) + printf ("PASS\n"); + + return 0; +} diff --git a/ld/testsuite/ld-x86-64/x86-64-jump-table.s b/ld/testsuite/ld-x= 86-64/x86-64-jump-table.s new file mode 100644 index 00000000000..bd06f714469 --- /dev/null +++ b/ld/testsuite/ld-x86-64/x86-64-jump-table.s @@ -0,0 +1,30 @@ +# Check R_X86_64_PLT32 relocation in jump table. + + .text + .p2align 4 + .globl foo + .type foo, @function +foo: + .cfi_startproc + cmpl $4, %edi + ja .L1 + leaq .L4(%rip), %rdx + movl %edi, %edi + movslq (%rdx,%rdi,4), %rax + addq %rdx, %rax + jmp *%rax +.L1: + ret +.Lbar2: + jmp bar2@PLT + .cfi_endproc + .size foo, .-foo + .section .rodata + .p2align 2 +.L4: + .long [email protected] + .long [email protected] + .long .Lbar2-.L4 + .long [email protected] + .long [email protected] + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86= -64.exp index 07607810d15..985d96dcfba 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -1523,6 +1523,14 @@ if { [isnative] && [check_compiler_available] } { {} \ "pr32067" \ ] \ + [list \ + "Build libjump-table.so" \ + "-shared" \ + "" \ + { x86-64-jump-table.s } \ + {} \ + "libjump-table.so" \ + ] \ ] =20 if {[istarget "x86_64-*-linux*-gnux32"]} { @@ -2046,6 +2054,14 @@ if { [isnative] && [check_compiler_available] } { "plt3" \ "pass.out" \ ] \ + [list \ + "Run pr34423" \ + "-Wl,--no-as-needed tmpdir/libjump-table.so" \ + "" \ + { pr34423.c } \ + "pr34423" \ + "pass.out" \ + ] \ ] =20 # Run-time tests which require working ifunc attribute support.