mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:17:35 +00:00
LibELF: Add riscv64 PLT trampoline
This code is based on the aarch64 implementation.
This commit is contained in:
parent
bf9240c7a9
commit
525555181e
2 changed files with 82 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023, Sönke Holz <sholz8530@gmail.com>
|
* Copyright (c) 2023-2024, Sönke Holz <sholz8530@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,77 @@
|
||||||
.hidden _plt_trampoline
|
.hidden _plt_trampoline
|
||||||
.type _plt_trampoline,@function
|
.type _plt_trampoline,@function
|
||||||
|
|
||||||
|
// This function is called by the PLT stub to resolve functions lazily at runtime.
|
||||||
|
// It saves off any argument registers that might be clobbered by the symbol
|
||||||
|
// resolution code, calls that, and then jumps to the resolved function.
|
||||||
|
//
|
||||||
|
// See section 8.4.6 "Program Linkage Table" of the RISC-V psABI.
|
||||||
|
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/v1.0/riscv-abi.pdf
|
||||||
|
//
|
||||||
|
// The calling convention is:
|
||||||
|
// t0 = .got.plt[1] (DynamicObject*)
|
||||||
|
// t1 = .got.plt offset
|
||||||
_plt_trampoline:
|
_plt_trampoline:
|
||||||
// FIXME: Implement the PLT trampoline.
|
// Save argument registers a0-a7, fa0-fa7 and ra.
|
||||||
unimp
|
addi sp, sp, -(18 * 8)
|
||||||
|
|
||||||
|
sd a0, 0*8(sp)
|
||||||
|
sd a1, 1*8(sp)
|
||||||
|
sd a2, 2*8(sp)
|
||||||
|
sd a3, 3*8(sp)
|
||||||
|
sd a4, 4*8(sp)
|
||||||
|
sd a5, 5*8(sp)
|
||||||
|
sd a6, 6*8(sp)
|
||||||
|
sd a7, 7*8(sp)
|
||||||
|
|
||||||
|
// NOTE: We only support ABI_FLEN=64 in LibELF/Validation.cpp,
|
||||||
|
// so we only save the lower 64 bits of the fa* registers.
|
||||||
|
fsd fa0, 8*8(sp)
|
||||||
|
fsd fa1, 9*8(sp)
|
||||||
|
fsd fa2, 10*8(sp)
|
||||||
|
fsd fa3, 11*8(sp)
|
||||||
|
fsd fa4, 12*8(sp)
|
||||||
|
fsd fa5, 13*8(sp)
|
||||||
|
fsd fa6, 14*8(sp)
|
||||||
|
fsd fa7, 15*8(sp)
|
||||||
|
|
||||||
|
sd ra, 16*8(sp)
|
||||||
|
|
||||||
|
// The DynamicObject* is in t0.
|
||||||
|
mv a0, t0
|
||||||
|
|
||||||
|
// GOT entries are 8 bytes, but sizeof(Elf64_Rela) == 24, so multiply
|
||||||
|
// t1 by 3 to get the relocation offset.
|
||||||
|
slli a1, t1, 1
|
||||||
|
add a1, a1, t1
|
||||||
|
|
||||||
|
call _fixup_plt_entry
|
||||||
|
|
||||||
|
// Save the resolved function's address.
|
||||||
|
mv t0, a0
|
||||||
|
|
||||||
|
// Restore argument registers and ra.
|
||||||
|
ld a0, 0*8(sp)
|
||||||
|
ld a1, 1*8(sp)
|
||||||
|
ld a2, 2*8(sp)
|
||||||
|
ld a3, 3*8(sp)
|
||||||
|
ld a4, 4*8(sp)
|
||||||
|
ld a5, 5*8(sp)
|
||||||
|
ld a6, 6*8(sp)
|
||||||
|
ld a7, 7*8(sp)
|
||||||
|
|
||||||
|
fld fa0, 8*8(sp)
|
||||||
|
fld fa1, 9*8(sp)
|
||||||
|
fld fa2, 10*8(sp)
|
||||||
|
fld fa3, 11*8(sp)
|
||||||
|
fld fa4, 12*8(sp)
|
||||||
|
fld fa5, 13*8(sp)
|
||||||
|
fld fa6, 14*8(sp)
|
||||||
|
fld fa7, 15*8(sp)
|
||||||
|
|
||||||
|
ld ra, 16*8(sp)
|
||||||
|
|
||||||
|
addi sp, sp, 18 * 8
|
||||||
|
|
||||||
|
// Jump to the resolved function.
|
||||||
|
jr t0
|
||||||
|
|
|
@ -790,8 +790,16 @@ void DynamicLoader::setup_plt_trampoline()
|
||||||
VirtualAddress got_address = m_dynamic_object->plt_got_base_address();
|
VirtualAddress got_address = m_dynamic_object->plt_got_base_address();
|
||||||
|
|
||||||
auto* got_ptr = (FlatPtr*)got_address.as_ptr();
|
auto* got_ptr = (FlatPtr*)got_address.as_ptr();
|
||||||
|
|
||||||
|
#if ARCH(AARCH64) || ARCH(X86_64)
|
||||||
got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
|
got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
|
||||||
got_ptr[2] = (FlatPtr)&_plt_trampoline;
|
got_ptr[2] = (FlatPtr)&_plt_trampoline;
|
||||||
|
#elif ARCH(RISCV64)
|
||||||
|
got_ptr[0] = (FlatPtr)&_plt_trampoline;
|
||||||
|
got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
|
||||||
|
#else
|
||||||
|
# error Unknown architecture
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from our ASM routine _plt_trampoline.
|
// Called from our ASM routine _plt_trampoline.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue