On 10/3/24 04:13, Ard Biesheuvel wrote:
That said, doing changes like changing "mov $sym" to "lea sym(%rip)" I
feel are a complete no-brainer and should be done regardless of any
other code generation issues.
Yes, this is the primary reason I ended up looking into this in the
first place. Earlier this year, we ended up having to introduce
RIP_REL_REF() to emit those RIP-relative references explicitly, in
order to prevent the C code that is called via the early 1:1 mapping
from exploding. The amount of C code called in that manner has been
growing steadily over time with the introduction of 5-level paging and
SEV-SNP and TDX support, which need to play all kinds of tricks before
the normal kernel mappings are created.
movq $sym to leaq sym(%rip) which you said ought to be smaller (and in
reality appears to be the same size, 7 bytes) seems like a no-brainer
and can be treated as a code quality issue -- in other words, file bug
reports against gcc and clang.
Compiling with -fpie and linking with --pie -z text produces an
executable that is guaranteed to have only RIP-relative references in
the .text segment, removing the need for RIP_REL_REF entirely (it
already does nothing when __pic__ is #define'd).
But -fpie has a considerable cost; specifically when we have indexed
references, as in that case the base pointer needs to be manifest in a
register, *and* it takes up a register slot in the EA, which may end
converting one instruction into three.
Now, the "kernel" memory model is defined in the ABI document, but there
is nothing that prevents us from making updates to it if we need to;
e.g. the statement that movq $sym can be used is undesirable, of course.
-hpa