dyn-loader: relocs and entry for rv64

This commit is contained in:
Mark Poliakov 2025-02-26 18:30:43 +02:00
parent 3a5a693691
commit e3916868d2
4 changed files with 58 additions and 15 deletions

View File

@ -8,6 +8,8 @@ pub enum Error {
ElfParse(#[from] elf::ParseError),
#[error("Memory mapping error: {0:?}")]
MemoryMap(yggdrasil_rt::Error),
#[error("Unsupported object data")]
UnhandledObject,
#[error("Object not loaded yet")]
NotLoaded,
#[error("Unsupported ELF type: {0:#06x}")]

View File

@ -129,9 +129,8 @@ unsafe fn enter(entry: extern "C" fn(usize), argument: usize) -> ! {
}
#[cfg(any(target_arch = "riscv64", rust_analyzer))]
{
let _ = entry;
let _ = argument;
todo!()
entry(argument);
unreachable!()
}
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", rust_analyzer))]
{

View File

@ -12,10 +12,7 @@ use std::{
use elf::{
abi::{
DF_1_PIE, DT_FINI, DT_FINI_ARRAY, DT_FINI_ARRAYSZ, DT_FLAGS_1, DT_INIT, DT_INIT_ARRAY,
DT_INIT_ARRAYSZ, DT_NEEDED, DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, ET_DYN, ET_EXEC,
PT_DYNAMIC, PT_GNU_EH_FRAME, PT_GNU_RELRO, PT_GNU_STACK, PT_INTERP, PT_LOAD, PT_NOTE,
PT_NULL, PT_PHDR, PT_TLS, SHN_UNDEF, SHT_REL, SHT_RELA, STB_GLOBAL, STB_LOCAL, STB_WEAK,
DF_1_PIE, DT_FINI, DT_FINI_ARRAY, DT_FINI_ARRAYSZ, DT_FLAGS_1, DT_INIT, DT_INIT_ARRAY, DT_INIT_ARRAYSZ, DT_NEEDED, DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, ET_DYN, ET_EXEC, PT_DYNAMIC, PT_GNU_EH_FRAME, PT_GNU_RELRO, PT_GNU_STACK, PT_INTERP, PT_LOAD, PT_NOTE, PT_NULL, PT_PHDR, PT_RISCV_ATTRIBUTES, PT_TLS, SHN_UNDEF, SHT_REL, SHT_RELA, STB_GLOBAL, STB_LOCAL, STB_WEAK
},
endian::AnyEndian,
parse::ParsingIterator,
@ -289,10 +286,15 @@ impl Object {
}
// Handled separately
PT_TLS => (),
// TODO handle .riscv.attributes and extract float ABI
PT_RISCV_ATTRIBUTES => (),
// TODO handle GNU_STACK
PT_DYNAMIC | PT_GNU_RELRO | PT_GNU_STACK | PT_INTERP | PT_PHDR
| PT_GNU_EH_FRAME | PT_NOTE => (),
_ => todo!("Unhandled segment type"),
_ => {
log::error!("Unhandled segment type: {:#x}", segment.p_type);
return Err(Error::UnhandledObject);
},
}
}

View File

@ -1,4 +1,7 @@
use elf::relocation::{Rel, Rela};
use elf::{
abi::{R_RISCV_64, R_RISCV_JUMP_SLOT, R_RISCV_RELATIVE, R_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPREL64},
relocation::{Rel, Rela},
};
use crate::{error::Error, object::ResolvedSymbol, state::State};
@ -14,7 +17,7 @@ impl Relocation for Rel {
_symbol: &ResolvedSymbol,
_load_base: usize,
) -> Result<Option<Self::Value>, Error> {
todo!()
Err(Error::UnhandledObject)
}
}
@ -23,11 +26,48 @@ impl Relocation for Rela {
fn resolve(
&self,
_state: &State,
_name: &str,
_symbol: &ResolvedSymbol,
_load_base: usize,
state: &State,
name: &str,
symbol: &ResolvedSymbol,
load_base: usize,
) -> Result<Option<Self::Value>, Error> {
todo!()
match *symbol {
ResolvedSymbol::Tls(tls) => match self.r_type {
R_RISCV_TLS_DTPMOD64 => Ok(Some(RelaValue::QWord(tls.module_id as _))),
R_RISCV_TLS_DTPREL64 => Ok(Some(RelaValue::QWord(tls.offset as _))),
_ => {
log::error!(
"Unhandled riscv64 relocation against TLS symbol: {:#x}",
self.r_type
);
Err(Error::UnhandledObject)
}
},
ResolvedSymbol::Null(object_id) => match self.r_type {
R_RISCV_TLS_DTPMOD64 => Ok(Some(RelaValue::QWord((object_id + 1) as _))),
R_RISCV_RELATIVE => Ok(Some(RelaValue::QWord(load_base as i64 + self.r_addend))),
_ => {
log::error!(
"Unhandled riscv64 relocation against NULL: {:#x}",
self.r_type
);
Err(Error::UnhandledObject)
}
},
_ => {
let s = symbol.value();
if s == 0 {
todo!()
}
match self.r_type {
R_RISCV_64 => Ok(Some(RelaValue::QWord(s + self.r_addend))),
R_RISCV_JUMP_SLOT => Ok(Some(RelaValue::QWord(s))),
_ => {
log::error!("Unhandled riscv64 relocation: {:#x}", self.r_type);
Err(Error::UnhandledObject)
}
}
}
}
}
}