mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
x86: Check MODRM for call and jmp in binutils older than 2.45
When i386 glibc was assembled with commit:
commit 11c2852449 (HEAD)
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri Feb 21 10:24:50 2025 +0100
x86: widen @got{,pcrel} support to PUSH and APX IMUL
With us doing the transformation to an immediate operand for MOV and
various ALU insns, there's little reason to then not support the same
conversion for the other two insns which have respective immediate
operand forms. Unfortunately for IMUL (due to the 0F opcode prefix)
there's no suitable relocation, so the pre-APX forms cannot be marked
for relaxation in the assembler.
"pushl main@GOT(%ebx)" in sysdeps/i386/start.S was assembled to
1c: ff b3 00 00 00 00 push 0x0(%ebx) 1e: R_386_GOT32X main
Linkers in binutils versions older than 2.45 treated it as jmp and relaxed
it to
22c: e9 cf ff ff ff jmp 200 <main>
231: 90 nop
Update elf_i386_convert_load_reloc in binutils versions older than 2.45
to check MODRM for call and jmp to work with i386 glibc assembled with
binutils 2.45 or newer. Do the same in elf_x86_64_convert_load_reloc.
PR ld/32991
* elf32-i386.c (elf_i386_convert_load_reloc): Check MODRM for
call and jmp.
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
@@ -1345,6 +1345,15 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
|
||||
|
||||
if (opcode == 0xff)
|
||||
{
|
||||
switch (modrm & 0x38)
|
||||
{
|
||||
case 0x10: /* CALL */
|
||||
case 0x20: /* JMP */
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We have "call/jmp *foo@GOT[(%reg)]". */
|
||||
if ((h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
|
||||
@@ -1930,6 +1930,15 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
|
||||
/* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
|
||||
R_X86_64_PC32. */
|
||||
modrm = bfd_get_8 (abfd, contents + roff - 1);
|
||||
switch (modrm & 0x38)
|
||||
{
|
||||
case 0x10: /* CALL */
|
||||
case 0x20: /* JMP */
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (modrm == 0x25)
|
||||
{
|
||||
/* Convert to "jmp foo nop". */
|
||||
|
||||
Reference in New Issue
Block a user