diff options
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index f8bb0d5..f864834 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3217,6 +3217,7 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec, { /* We have "call/jmp *foo@GOTPCREL(%rip)". */ unsigned int nop; + unsigned int disp; bfd_vma nop_offset; /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to @@ -3224,7 +3225,6 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec, modrm = bfd_get_8 (abfd, contents + roff - 1); if (modrm == 0x25) { - unsigned int disp; /* Convert to "jmp foo nop". */ modrm = 0xe9; nop = NOP_OPCODE; @@ -3238,8 +3238,16 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec, /* Convert to "nop call foo". ADDR_PREFIX_OPCODE is a nop prefix. */ modrm = 0xe8; - nop = ADDR_PREFIX_OPCODE; - nop_offset = irel->r_offset - 2; + nop = link_info->call_nop_byte; + if (link_info->call_nop_as_suffix) + { + nop_offset = irel->r_offset + 3; + disp = bfd_get_32 (abfd, contents + irel->r_offset); + irel->r_offset -= 1; + bfd_put_32 (abfd, disp, contents + irel->r_offset); + } + else + nop_offset = irel->r_offset - 2; } bfd_put_8 (abfd, nop, contents + nop_offset); bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1); |