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).
This commit is contained in:
Jan Beulich 2021-04-26 10:41:35 +02:00
parent 8fb8824599
commit a7664973b2
9 changed files with 40 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2021-04-26 Jan Beulich <jbeulich@suse.com>
* elf32-i386.c (elf_howto_table): Switch R_386_PC16 to
complain_overflow_signed.
* elf64-x86-64.c (x86_64_elf_howto_table): Switch R_X86_64_PC16
to complain_overflow_signed.
2021-04-23 Eric Botcazou <ebotcazou@adacore.com> 2021-04-23 Eric Botcazou <ebotcazou@adacore.com>
* elf.c (special_sections_p): Add .persistent.bss. * elf.c (special_sections_p): Add .persistent.bss.

View file

@ -93,7 +93,7 @@ static reloc_howto_type elf_howto_table[]=
HOWTO(R_386_16, 0, 1, 16, false, 0, complain_overflow_bitfield, HOWTO(R_386_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_16", bfd_elf_generic_reloc, "R_386_16",
true, 0xffff, 0xffff, false), true, 0xffff, 0xffff, false),
HOWTO(R_386_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield, HOWTO(R_386_PC16, 0, 1, 16, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_386_PC16", bfd_elf_generic_reloc, "R_386_PC16",
true, 0xffff, 0xffff, true), true, 0xffff, 0xffff, true),
HOWTO(R_386_8, 0, 0, 8, false, 0, complain_overflow_bitfield, HOWTO(R_386_8, 0, 0, 8, false, 0, complain_overflow_bitfield,

View file

@ -82,7 +82,7 @@ static reloc_howto_type x86_64_elf_howto_table[] =
false), false),
HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield, HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false), bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false),
HOWTO(R_X86_64_PC16,0, 1, 16, true, 0, complain_overflow_bitfield, HOWTO(R_X86_64_PC16, 0, 1, 16, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true), bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true),
HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_bitfield, HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false), bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false),

View file

@ -1,3 +1,10 @@
2021-04-26 Jan Beulich <jbeulich@suse.com>
* testsuite/ld-i386/pcrel16-2.s, testsuite/ld-i386/pcrel16-2.d,
testsuite/ld-x86-64/pcrel16-2.d: New.
* testsuite/ld-i386/i386.exp: Run new test.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
2021-04-23 H.J. Lu <hongjiu.lu@intel.com> 2021-04-23 H.J. Lu <hongjiu.lu@intel.com>
PR ld/27771 PR ld/27771

View file

@ -297,6 +297,7 @@ run_dump_test "abs"
run_dump_test "pcrel8" run_dump_test "pcrel8"
run_dump_test "pcrel16" run_dump_test "pcrel16"
run_dump_test "pcrel16abs" run_dump_test "pcrel16abs"
run_dump_test "pcrel16-2"
run_dump_test "alloc" run_dump_test "alloc"
run_dump_test "warn1" run_dump_test "warn1"
run_dump_test "tlsgd2" run_dump_test "tlsgd2"

View file

@ -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.*

View file

@ -0,0 +1,12 @@
.text
.global _start
_start:
data16 xbegin t16
ret
.fill 0x8000,1,0xcc
.global t16
t16:
data16 xbegin _start
ret

View file

@ -0,0 +1,5 @@
#name: PCREL16 overflow (2)
#source: ../ld-i386/pcrel16-2.s
#ld:
#error: .*relocation truncated to fit: R_X86_64_PC16 .*t16.*
#error: .*relocation truncated to fit: R_X86_64_PC16 .*_start.*

View file

@ -261,6 +261,7 @@ run_dump_test "abs-l1om"
run_dump_test "apic" run_dump_test "apic"
run_dump_test "pcrel8" run_dump_test "pcrel8"
run_dump_test "pcrel16" run_dump_test "pcrel16"
run_dump_test "pcrel16-2"
run_dump_test "tlsgd2" run_dump_test "tlsgd2"
run_dump_test "tlsgd3" run_dump_test "tlsgd3"
run_dump_test "tlsgd12" run_dump_test "tlsgd12"