1*1971aeeeSLoGin use core::{ffi::c_void, hint::spin_loop, ptr};
2*1971aeeeSLoGin
3*1971aeeeSLoGin #[derive(Debug, Clone, PartialEq, Eq)]
4*1971aeeeSLoGin struct Dyn {
5*1971aeeeSLoGin pub d_tag: i64,
6*1971aeeeSLoGin pub(super) d_un: u64,
7*1971aeeeSLoGin }
8*1971aeeeSLoGin
9*1971aeeeSLoGin impl Dyn {
d_val(&self) -> u6410*1971aeeeSLoGin pub fn d_val(&self) -> u64 {
11*1971aeeeSLoGin self.d_un
12*1971aeeeSLoGin }
13*1971aeeeSLoGin
d_ptr(&self) -> u6414*1971aeeeSLoGin pub fn d_ptr(&self) -> u64 {
15*1971aeeeSLoGin self.d_un
16*1971aeeeSLoGin }
17*1971aeeeSLoGin }
18*1971aeeeSLoGin
19*1971aeeeSLoGin #[no_mangle]
efi_relocate(ldbase: u64, elf_dyn: *mut c_void) -> usize20*1971aeeeSLoGin unsafe extern "C" fn efi_relocate(ldbase: u64, elf_dyn: *mut c_void) -> usize {
21*1971aeeeSLoGin let elf_dyn = elf_dyn as *mut Dyn;
22*1971aeeeSLoGin return do_relocate(ldbase, elf_dyn).0 as usize;
23*1971aeeeSLoGin }
24*1971aeeeSLoGin
do_relocate(ldbase: u64, elf_dyn: *mut Dyn) -> uefi::Status25*1971aeeeSLoGin unsafe fn do_relocate(ldbase: u64, elf_dyn: *mut Dyn) -> uefi::Status {
26*1971aeeeSLoGin let mut relsz = 0;
27*1971aeeeSLoGin let mut relent = 0;
28*1971aeeeSLoGin let mut rel: *mut elf::relocation::Elf64_Rela = ptr::null_mut();
29*1971aeeeSLoGin
30*1971aeeeSLoGin let mut item = elf_dyn;
31*1971aeeeSLoGin
32*1971aeeeSLoGin while (*item).d_tag != elf::abi::DT_NULL {
33*1971aeeeSLoGin match (*item).d_tag {
34*1971aeeeSLoGin elf::abi::DT_RELA => {
35*1971aeeeSLoGin rel = (*item).d_ptr() as *mut elf::relocation::Elf64_Rela;
36*1971aeeeSLoGin }
37*1971aeeeSLoGin elf::abi::DT_RELASZ => {
38*1971aeeeSLoGin relsz = (*item).d_val();
39*1971aeeeSLoGin }
40*1971aeeeSLoGin elf::abi::DT_RELAENT => {
41*1971aeeeSLoGin relent = (*item).d_val();
42*1971aeeeSLoGin }
43*1971aeeeSLoGin _ => {}
44*1971aeeeSLoGin }
45*1971aeeeSLoGin item = (item as usize + core::mem::size_of::<Dyn>()) as *mut Dyn;
46*1971aeeeSLoGin }
47*1971aeeeSLoGin
48*1971aeeeSLoGin if rel.is_null() && (relent == 0) {
49*1971aeeeSLoGin return uefi::Status::SUCCESS;
50*1971aeeeSLoGin }
51*1971aeeeSLoGin
52*1971aeeeSLoGin if rel.is_null() || relent == 0 {
53*1971aeeeSLoGin return uefi::Status::LOAD_ERROR;
54*1971aeeeSLoGin }
55*1971aeeeSLoGin
56*1971aeeeSLoGin while relsz > 0 {
57*1971aeeeSLoGin match ((*rel).r_info & 0xFF) as u32 {
58*1971aeeeSLoGin elf::abi::R_RISCV_RELATIVE => {
59*1971aeeeSLoGin let addr = ldbase + (*rel).r_offset as u64;
60*1971aeeeSLoGin let sym_addr = ldbase + (*rel).r_addend as u64;
61*1971aeeeSLoGin let addr_ptr = addr as *mut u64;
62*1971aeeeSLoGin *addr_ptr = sym_addr;
63*1971aeeeSLoGin }
64*1971aeeeSLoGin _ => {
65*1971aeeeSLoGin /* Panic */
66*1971aeeeSLoGin loop {
67*1971aeeeSLoGin spin_loop();
68*1971aeeeSLoGin }
69*1971aeeeSLoGin }
70*1971aeeeSLoGin }
71*1971aeeeSLoGin rel = (rel as usize + relent as usize) as *mut elf::relocation::Elf64_Rela;
72*1971aeeeSLoGin relsz -= relent;
73*1971aeeeSLoGin }
74*1971aeeeSLoGin
75*1971aeeeSLoGin return uefi::Status::SUCCESS;
76*1971aeeeSLoGin }
77