LibELF: Implement PLT relocations for x86_64

This commit is contained in:
Gunnar Beutner 2021-06-29 17:43:08 +02:00 committed by Andreas Kling
parent 1d4ae9194e
commit d3127efc01
Notes: sideshowbarker 2024-07-18 11:19:53 +09:00
3 changed files with 44 additions and 3 deletions

View file

@ -8,5 +8,42 @@
.globl _plt_trampoline
.hidden _plt_trampoline
.type _plt_trampoline,@function
_plt_trampoline:
int3
_plt_trampoline: # (object, relocation_index)
# save flags/registers (https://stackoverflow.com/questions/18024672/what-registers-are-preserved-through-a-linux-x86-64-function-call)
pushfq
pushq %rax
pushq %rcx
pushq %rdx
pushq %rsi
pushq %rdi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
movq 80(%rsp), %rdi # object
movq 88(%rsp), %rsi # relocation_index
# offset = index * sizeof(Elf64_Rela)
shlq $3, %rsi
leaq (%rsi, %rsi, 2), %rsi
call _fixup_plt_entry@PLT
movq %rax, 88(%rsp) # replace object argument with symbol address
# restore flags/registers
popq %r11
popq %r10
popq %r9
popq %r8
popq %rdi
popq %rsi
popq %rdx
popq %rcx
popq %rax
popfq
addq $8, %rsp # remove relocation_index argument
retq

View file

@ -506,7 +506,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
u8* relocation_address = relocation.address().as_ptr();
if (m_elf_image.is_dynamic())
*(u32*)relocation_address += (FlatPtr)m_dynamic_object->base_address().as_ptr();
*(FlatPtr*)relocation_address += (FlatPtr)m_dynamic_object->base_address().as_ptr();
}
break;
}

View file

@ -449,7 +449,11 @@ NonnullRefPtr<DynamicObject> DynamicObject::create(const String& filename, Virtu
VirtualAddress DynamicObject::patch_plt_entry(u32 relocation_offset)
{
auto relocation = plt_relocation_section().relocation_at_offset(relocation_offset);
#if ARCH(I386)
VERIFY(relocation.type() == R_386_JMP_SLOT);
#else
VERIFY(relocation.type() == R_X86_64_JUMP_SLOT);
#endif
auto symbol = relocation.symbol();
u8* relocation_address = relocation.address().as_ptr();