mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:22:43 +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 | ||||
|  */ | ||||
|  | @ -9,6 +9,77 @@ | |||
| .hidden _plt_trampoline
 | ||||
| .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: | ||||
|     // FIXME: Implement the PLT trampoline. | ||||
|     unimp | ||||
|     // Save argument registers a0-a7, fa0-fa7 and ra. | ||||
|     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(); | ||||
| 
 | ||||
|     auto* got_ptr = (FlatPtr*)got_address.as_ptr(); | ||||
| 
 | ||||
| #if ARCH(AARCH64) || ARCH(X86_64) | ||||
|     got_ptr[1] = (FlatPtr)m_dynamic_object.ptr(); | ||||
|     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.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sönke Holz
						Sönke Holz