[PATCH] x86: Properly handle relocation against hidden ABS symbol

Jan Beulich jbeulich@suse.com
Thu May 15 06:22:02 GMT 2025
On 15.05.2025 04:00, H.J. Lu wrote:
> With PIC on x86-64,
> 
> movq symbol@GOTPCREL(%rip), %rax
> 
> is used to get the symbol address via GOT.  If the symbol turns out to
> be a hidden symbol, linker normally converts it into
> 
> leaq symbol(%rip), %rax
> 
> But if the symbol is an ABS symbol, RAX won't have the correct value at
> run-time and it will have the symbol value + load address.  If the symbol
> is declared as hidden, compiler will generate
> 
> leaq symbol(%rip), %rax
> 
> to get the symbol address.  If the hidden symbol is an ABS symbol, RAX
> will have the same incorrect value at run-time.  On i386,
> 
> movl symbol@GOT(%reg1), %reg2
> 
> is used to get the symbol address via GOT.  If the symbol turns out to
> be a hidden symbol, linker normally converts it into
> 
> leal symbol@GOTOFF(%reg1), %reg2
> 
> If the symbol is declared as hidden, compiler will generate
> 
> leal symbol@GOTOFF(%reg1), %reg2
> 
> In both cases, if the hidden symbol is an ABS symbol, REG2 will have the
> same incorrect value at run-time.  This patch changes the x86-64 linker
> to convert
> 
> movq symbol@GOTPCREL(%rip), %rax
> and
> leaq symbol(%rip), %rax
> to
> movq $symbol, %rax
> 
> and changes the i386 linker to convert
> 
> movl symbol@GOT(%reg1), %reg2
> and
> leal symbol@GOTOFF(%reg1), %reg2
> to
> movl $symbol, %reg2
> 
> for hidden ABS symbols.
> 
> bfd/
> 
> PR ld/32443
> * elf32-i386.c (elf_i386_convert_load_reloc): Skip relocation
> against linker-script hidden absolute symbol in PIC.
> (elf_i386_finish_dynamic_symbol): Don't generate dynamic
> relocation against inker-script hidden absolute symbol.

You're again checking opcode bytes without considering prefixes, in
particular (but not limited to) VEX/XOP/EVEX ones. I understand this is
a pre-existing issue, but I'd prefer if the problem wasn't widened.

Also why is it that this is done only for STV_HIDDEN, but not also for
STV_PROTECTED?

Further, why is the conversion to MOV only done for PIC? The MOV
(immediate) is more efficient even outside of PIC/PIE, isn't it?

> * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Skip
> relocation against linker-script hidden absolute symbol in PIC.
> (elf_x86_64_finish_dynamic_symbol): Don't generate dynamic
> relocation against inker-script hidden absolute symbol.

Here afaics you only check the opcode byte, but not ModR/M (to limit
to the %rip-relative form only).

You convert "if (opcode != 0x8b)" to "else if (opcode != 0x8b)" in
one of the rearrangements - is that, strictly speaking, correct? The
original code included the 0xff case, when that's now excluded. If it's
correct, the earlier

+  else
+    {
+      if (opcode == 0xff)

would want to become just

+  else if (opcode == 0xff)

limiting code churn quite a bit.

Like you have done in the 32-bit code, can you indent the lea_to_mov
label some, please?

> * elfxx-x86.c (elf_x86_allocate_dynrelocs): Don't allocate
> dynamic relocation against inker-script hidden absolute symbol.
> * elfxx-x86.h (HIDDEN_ABS_SYMBOL_P): New.

Why is it that HIDDEN_ABS_SYMBOL_P() doesn't use ABS_SYMBOL_P()? IOW why
is ->root.ldscript_def relevant to check for the latter, but not for the
new predicate?

Jan


More information about the Binutils mailing list