[PATCH v2] x86: Restore PC16 relocation overflow check
Michael Matz
matz@suse.de
Fri May 28 15:52:16 GMT 2021
Hello,
On Fri, 28 May 2021, Jan Beulich via Binutils wrote:
> On 28.05.2021 14:22, H.J. Lu wrote:
> > The x86-64 psABI has
> >
> > ---
> > A program or object file using R_X86_64_8, R_X86_64_16, R_X86_64_PC16
> > or R_X86_64_PC8 relocations is not conformant to this ABI, these
> > relocations are only added for documentation purposes.
> > ---
> >
> > Since x86 PC16 relocations were intended for 16-bit programs in an ELF32
> > or ELF64 container, PC16 relocation should wrap-around in 16-bit address
> > space.
>
> At the risk of stating the obvious - this wrapping around is not
> expressed correctly by complain_overflow_bitfield. I simply can't
> see how, in a 32- or 64-bit container, 16-bit code could ever be
> linked correctly, suitably detecting overflow where it would
> cause a problem at runtime. This is only possible when the linker
> knows 16-bit segment boundaries.
>
> Therefore I see only two reasonable modes of operation for the
> linker:
> 1) Treat PC16 analogously to PC8/PC32/PC64.
I think this is the right course of action. PC16 should check that the
signed 16bit value is the same as the computed 64 bit (or 32bit on ELF32)
value that's supposed to go in there.
The PC16 (or any of the other relocations named PC*) is not the place to
check for the funny truncation of rIP that some instructions are doing.
PC* has uses outside of instructions, and even within instructions the
"normal" meaning makes sense and reflects reality the most (i.e. no rIP
truncation).
If we _really_ wanted that linkers be able to check that rIP truncations
is correct then that would need a new relocation. I will remark that
checking such truncation would require the linker to know where the final
linked runtime address is, and that in the wild, for loaders and BIOSes
writing into ELF files for merely containing byte blobs to be later
extracted by objcopy with the assumption that that blob then is magically
loaded at "the right address", these final load addresses are often _not_
written into the linker scripts correctly. So, in the end, even if we
were to introduce such new relocation with the rIP truncation checking, it
often would have to be disabled anyway in practice because the checks then
would trigger.
> 2) Don't check PC16 (and then also PC8, 8, and 16) for overflow
> at all.
> The default ought to be 1, while 2 ought to be enabled explicitly
> (and at the programmer's own risk) for code caring to link sizable
> amounts of 16-bit code (i.e. when the overflow checking gets in
> the way).
> This said, with the psABI saying what it says, I could see one
> taking the position of taking "don't check overflows at all" as
> a legitimate mode to always operate in. But then again this
> ought to apply to all four non-conformant reloc types at the
> same time.
We can change the psABI. But changes should make sense in the abstract as
well as being demanded by reality. I think we have good cause to make
PC16 conforming now, but I don't think we have good cause to make its
semantic anything else from the obvious. FWIW, my patch would be
https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/22
Do you also want _8 and _16 (zero-extended I guess)? _PC8
(sign-extended)?
Ciao,
Michael.
More information about the Binutils
mailing list