From a7664973b24a242cd9ea17deb5eaf503065fc0bd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 26 Apr 2021 10:41:35 +0200 Subject: x86: correct overflow checking for 16-bit PC-relative relocs The only insn requiring a truly 16-bit PC-relative relocation outside of 16-bit mode is XBEGIN (with an operand size override). For it, the relocation generated should behave similar to 8- and (for 64-bit) 32-bit PC-relatives ones, i.e. be checked for a signed value to fit the field. This same mode is also correct for 16-bit code. Outside of 16-bit code, branches with operand size overrides act in a truly PC-relative way only when living in the low 32k of address space, as they truncate rIP to 16 bits. This can't be expressed by a PC-relative relocation. Putting in place a new testcase, I'd like to note that the two existing ones (pcrel16 and pcrel16abs) appear to be pretty pointless: They don't expect any error despite supposedly checking for overflow, and in fact there can't possibly be any error for the - former since gas doesn't emit any relocation in the first place there, - latter because the way the relocation gets expressed by gas doesn't allow the linker to notice the overflow; it should be detected by gas if at all, but see above (an error would be reported here for x86-64 afaict, but this test doesn't get re-used there). --- ld/testsuite/ld-i386/i386.exp | 1 + ld/testsuite/ld-i386/pcrel16-2.d | 5 +++++ ld/testsuite/ld-i386/pcrel16-2.s | 12 ++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 ld/testsuite/ld-i386/pcrel16-2.d create mode 100644 ld/testsuite/ld-i386/pcrel16-2.s (limited to 'ld/testsuite/ld-i386') diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 6ad69a8..d0b3f69 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -297,6 +297,7 @@ run_dump_test "abs" run_dump_test "pcrel8" run_dump_test "pcrel16" run_dump_test "pcrel16abs" +run_dump_test "pcrel16-2" run_dump_test "alloc" run_dump_test "warn1" run_dump_test "tlsgd2" diff --git a/ld/testsuite/ld-i386/pcrel16-2.d b/ld/testsuite/ld-i386/pcrel16-2.d new file mode 100644 index 0000000..c1c340f --- /dev/null +++ b/ld/testsuite/ld-i386/pcrel16-2.d @@ -0,0 +1,5 @@ +#name: PCREL16 overflow (2) +#as: --32 +#ld: -melf_i386 +#error: .*relocation truncated to fit: R_386_PC16 .*t16.* +#error: .*relocation truncated to fit: R_386_PC16 .*_start.* diff --git a/ld/testsuite/ld-i386/pcrel16-2.s b/ld/testsuite/ld-i386/pcrel16-2.s new file mode 100644 index 0000000..2e97417 --- /dev/null +++ b/ld/testsuite/ld-i386/pcrel16-2.s @@ -0,0 +1,12 @@ + .text + .global _start +_start: + data16 xbegin t16 + ret + + .fill 0x8000,1,0xcc + + .global t16 +t16: + data16 xbegin _start + ret -- cgit v1.1