[PATCH 8/8] x86: correct overflow checking for 16-bit PC-relative relocs

H.J. Lu hjl.tools@gmail.com
Fri Apr 23 13:36:33 GMT 2021


On Fri, Apr 23, 2021 at 1:38 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> 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).
>
> bfd/
> 2021-04-XX  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.
>
> ld/
> 2021-04-XX  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.
>
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -93,7 +93,7 @@ static reloc_howto_type elf_howto_table[
>    HOWTO(R_386_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
>         bfd_elf_generic_reloc, "R_386_16",
>         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",
>         true, 0xffff, 0xffff, true),
>    HOWTO(R_386_8, 0, 0, 8, false, 0, complain_overflow_bitfield,
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -82,7 +82,7 @@ static reloc_howto_type x86_64_elf_howto
>         false),
>    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),
> -  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),
>    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),
> --- 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"
> --- /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.*
> --- /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
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/pcrel16-2.d
> @@ -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.*
> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> @@ -261,6 +261,7 @@ run_dump_test "abs-l1om"
>  run_dump_test "apic"
>  run_dump_test "pcrel8"
>  run_dump_test "pcrel16"
> +run_dump_test "pcrel16-2"
>  run_dump_test "tlsgd2"
>  run_dump_test "tlsgd3"
>  run_dump_test "tlsgd12"
>

OK.

Thanks.

-- 
H.J.


More information about the Binutils mailing list