From: Jan Beulich Date: Mon, 2 Dec 2024 08:37:34 +0000 (+0100) Subject: x86/COFF: support RVA (image-relative) relocations in insn operands X-Git-Tag: gdb-16-branchpoint~256 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8cd1d971e71b67767dfe21b53489c59749bfba8c;p=thirdparty%2Fbinutils-gdb.git x86/COFF: support RVA (image-relative) relocations in insn operands As was pointed out in [1] compilers produce code using such constructs, and hence we'd better support this. In analogy to the .rva directive permit @rva to be used for this, and in analogy with other architectures (plus to not diverge from e.g. Clang's integrated assembler, albeit I haven't been able myself to confirm it knows this form) also permit @imgrel. While there also adjust the operand type specifier for the adjacent @secrel32 - 64-bit fields cannot be used with a 32-bit relocation. Further while there also deal with *-*-pe* in x86-64.exp, even if (right now) perhaps only for completeness. [1] https://sourceware.org/pipermail/binutils/2024-November/137548.html --- diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index e3a7c972e84..c1c0d0fdd91 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1410,7 +1410,13 @@ gotrel[] = #else /* TE_PE */ { STRING_COMMA_LEN ("SECREL32"), { BFD_RELOC_32_SECREL, BFD_RELOC_32_SECREL }, - OPERAND_TYPE_IMM32_32S_64_DISP32_64, false }, + OPERAND_TYPE_IMM32_32S_DISP32, false }, + { STRING_COMMA_LEN ("RVA"), { BFD_RELOC_RVA, + BFD_RELOC_RVA }, + OPERAND_TYPE_IMM32_32S_DISP32, false }, + { STRING_COMMA_LEN ("IMGREL"), { BFD_RELOC_RVA, + BFD_RELOC_RVA }, + OPERAND_TYPE_IMM32_32S_DISP32, false }, #endif #undef OPERAND_TYPE_IMM32_32S_DISP32 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 9276a4368f3..0a48b4eb0f1 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -795,6 +795,7 @@ if [gas_32_check] then { } then { run_dump_test "secrel" run_dump_test "secidx" + run_dump_test "imgrel" } # Miscellaneous tests. diff --git a/gas/testsuite/gas/i386/imgrel.d b/gas/testsuite/gas/i386/imgrel.d new file mode 100644 index 00000000000..52ab82252da --- /dev/null +++ b/gas/testsuite/gas/i386/imgrel.d @@ -0,0 +1,40 @@ +#objdump: -rs +#name: i386 imgrel (RVA) reloc + +.*: +file format pe-i386 + +RELOCATION RECORDS FOR \[\.text\]: +OFFSET[ ]+TYPE[ ]+VALUE +0+01 rva32 \.text +0+06 rva32 \.text +0+0c rva32 \.data +0+12 rva32 \.data +0+17 rva32 \.text +0+1d rva32 \.text +0+23 rva32 Xtrn +0+29 rva32 Xtrn + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET[ ]+TYPE[ ]+VALUE +0+00 rva32 \.text +0+04 rva32 \.text +0+08 rva32 \.text +0+0c rva32 \.data +0+10 rva32 \.data +0+14 rva32 \.data +0+18 rva32 \.data +0+1c rva32 \.data +0+20 rva32 \.data +0+24 rva32 Xtrn +0+28 rva32 Xtrn +0+2c rva32 Xtrn + +Contents of section \.text: + 0000 b8000000 00b90000 00000305 00000000 .* + 0010 030d0000 00002d16 00000081 e91b0000 .* + 0020 00338300 00000033 8b000000 00.* + +Contents of section \.data: + 0000 00000000 00000000 00000000 00000000 .* + 0010 00000000 00000000 18000000 1c000000 .* + 0020 20000000 00000000 00000000 00000000 .* diff --git a/gas/testsuite/gas/i386/imgrel.s b/gas/testsuite/gas/i386/imgrel.s new file mode 100644 index 00000000000..6bdf91dca57 --- /dev/null +++ b/gas/testsuite/gas/i386/imgrel.s @@ -0,0 +1,31 @@ + .text +Text: + mov $Text@rva, %eax + mov $Text@imgrel, %ecx + + add Data@rva, %eax + add Data@imgrel, %ecx + + sub $.@rva, %eax + sub $.@imgrel, %ecx + + xor Xtrn@rva(%ebx), %eax + xor Xtrn@imgrel(%ebx), %ecx + + .data +Data: + .rva Text + .long Text@rva + .long Text@imgrel + + .rva Data + .long Data@rva + .long Data@imgrel + + .rva . + .long .@rva + .long .@imgrel + + .rva Xtrn + .long Xtrn@rva + .long Xtrn@imgrel diff --git a/gas/testsuite/gas/i386/x86-64-imgrel.d b/gas/testsuite/gas/i386/x86-64-imgrel.d new file mode 100644 index 00000000000..cb18284340d --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-imgrel.d @@ -0,0 +1,40 @@ +#objdump: -rs +#name: x86-64 imgrel (RVA) reloc + +.*: +file format pe-x86-64 + +RELOCATION RECORDS FOR \[\.text\]: +OFFSET[ ]+TYPE[ ]+VALUE +0+01 IMAGE_REL_AMD64_ADDR32NB \.text +0+06 IMAGE_REL_AMD64_ADDR32NB \.text +0+0d IMAGE_REL_AMD64_ADDR32NB \.data +0+14 IMAGE_REL_AMD64_ADDR32NB \.data +0+19 IMAGE_REL_AMD64_ADDR32NB \.text +0+1f IMAGE_REL_AMD64_ADDR32NB \.text +0+25 IMAGE_REL_AMD64_ADDR32NB Xtrn +0+2b IMAGE_REL_AMD64_ADDR32NB Xtrn + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET[ ]+TYPE[ ]+VALUE +0+00 IMAGE_REL_AMD64_ADDR32NB \.text +0+04 IMAGE_REL_AMD64_ADDR32NB \.text +0+08 IMAGE_REL_AMD64_ADDR32NB \.text +0+0c IMAGE_REL_AMD64_ADDR32NB \.data +0+10 IMAGE_REL_AMD64_ADDR32NB \.data +0+14 IMAGE_REL_AMD64_ADDR32NB \.data +0+18 IMAGE_REL_AMD64_ADDR32NB \.data +0+1c IMAGE_REL_AMD64_ADDR32NB \.data +0+20 IMAGE_REL_AMD64_ADDR32NB \.data +0+24 IMAGE_REL_AMD64_ADDR32NB Xtrn +0+28 IMAGE_REL_AMD64_ADDR32NB Xtrn +0+2c IMAGE_REL_AMD64_ADDR32NB Xtrn + +Contents of section \.text: + 0000 b8000000 00b90000 00000304 25000000 .* + 0010 00030c25 00000000 2d180000 0081e91d .* + 0020 00000033 83000000 00338b00 000000.* + +Contents of section \.data: + 0000 00000000 00000000 00000000 00000000 .* + 0010 00000000 00000000 18000000 1c000000 .* + 0020 20000000 00000000 00000000 00000000 .* diff --git a/gas/testsuite/gas/i386/x86-64-imgrel.s b/gas/testsuite/gas/i386/x86-64-imgrel.s new file mode 100644 index 00000000000..62ea26f4443 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-imgrel.s @@ -0,0 +1,31 @@ + .text +Text: + mov $Text@rva, %eax + mov $Text@imgrel, %ecx + + add Data@rva, %eax + add Data@imgrel, %ecx + + sub $.@rva, %eax + sub $.@imgrel, %ecx + + xor Xtrn@rva(%rbx), %eax + xor Xtrn@imgrel(%rbx), %ecx + + .data +Data: + .rva Text + .long Text@rva + .long Text@imgrel + + .rva Data + .long Data@rva + .long Data@imgrel + + .rva . + .long .@rva + .long .@imgrel + + .rva Xtrn + .long Xtrn@rva + .long Xtrn@imgrel diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp index 936ae0022ca..cbeef6ea223 100644 --- a/gas/testsuite/gas/i386/x86-64.exp +++ b/gas/testsuite/gas/i386/x86-64.exp @@ -52,11 +52,14 @@ run_dump_test "x86-64-addr32-intel" run_list_test "x86-64-addr32-bad" "-al" run_dump_test "x86-64-opcode" run_dump_test "x86-64-intel64" -if { ! [istarget "*-*-*cygwin*"] && ![istarget "*-*-mingw*"] } then { +if { ![istarget "*-*-*cygwin*"] + && ![istarget "*-*-mingw*"] + && ![istarget "*-*-pe*"] } then { run_dump_test "x86-64-pcrel" run_dump_test "x86-64-disassem" } else { run_dump_test "x86-64-w64-pcrel" + run_dump_test "x86-64-imgrel" } run_list_test "pcrel64" "-al" run_dump_test "x86-64-rip"