dyn-loader: relocs and entry for rv64
This commit is contained in:
parent
3a5a693691
commit
e3916868d2
@ -8,6 +8,8 @@ pub enum Error {
|
|||||||
ElfParse(#[from] elf::ParseError),
|
ElfParse(#[from] elf::ParseError),
|
||||||
#[error("Memory mapping error: {0:?}")]
|
#[error("Memory mapping error: {0:?}")]
|
||||||
MemoryMap(yggdrasil_rt::Error),
|
MemoryMap(yggdrasil_rt::Error),
|
||||||
|
#[error("Unsupported object data")]
|
||||||
|
UnhandledObject,
|
||||||
#[error("Object not loaded yet")]
|
#[error("Object not loaded yet")]
|
||||||
NotLoaded,
|
NotLoaded,
|
||||||
#[error("Unsupported ELF type: {0:#06x}")]
|
#[error("Unsupported ELF type: {0:#06x}")]
|
||||||
|
@ -129,9 +129,8 @@ unsafe fn enter(entry: extern "C" fn(usize), argument: usize) -> ! {
|
|||||||
}
|
}
|
||||||
#[cfg(any(target_arch = "riscv64", rust_analyzer))]
|
#[cfg(any(target_arch = "riscv64", rust_analyzer))]
|
||||||
{
|
{
|
||||||
let _ = entry;
|
entry(argument);
|
||||||
let _ = argument;
|
unreachable!()
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", rust_analyzer))]
|
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", rust_analyzer))]
|
||||||
{
|
{
|
||||||
|
@ -12,10 +12,7 @@ use std::{
|
|||||||
|
|
||||||
use elf::{
|
use elf::{
|
||||||
abi::{
|
abi::{
|
||||||
DF_1_PIE, DT_FINI, DT_FINI_ARRAY, DT_FINI_ARRAYSZ, DT_FLAGS_1, DT_INIT, DT_INIT_ARRAY,
|
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
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
endian::AnyEndian,
|
endian::AnyEndian,
|
||||||
parse::ParsingIterator,
|
parse::ParsingIterator,
|
||||||
@ -289,10 +286,15 @@ impl Object {
|
|||||||
}
|
}
|
||||||
// Handled separately
|
// Handled separately
|
||||||
PT_TLS => (),
|
PT_TLS => (),
|
||||||
|
// TODO handle .riscv.attributes and extract float ABI
|
||||||
|
PT_RISCV_ATTRIBUTES => (),
|
||||||
// TODO handle GNU_STACK
|
// TODO handle GNU_STACK
|
||||||
PT_DYNAMIC | PT_GNU_RELRO | PT_GNU_STACK | PT_INTERP | PT_PHDR
|
PT_DYNAMIC | PT_GNU_RELRO | PT_GNU_STACK | PT_INTERP | PT_PHDR
|
||||||
| PT_GNU_EH_FRAME | PT_NOTE => (),
|
| PT_GNU_EH_FRAME | PT_NOTE => (),
|
||||||
_ => todo!("Unhandled segment type"),
|
_ => {
|
||||||
|
log::error!("Unhandled segment type: {:#x}", segment.p_type);
|
||||||
|
return Err(Error::UnhandledObject);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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};
|
use crate::{error::Error, object::ResolvedSymbol, state::State};
|
||||||
|
|
||||||
@ -14,7 +17,7 @@ impl Relocation for Rel {
|
|||||||
_symbol: &ResolvedSymbol,
|
_symbol: &ResolvedSymbol,
|
||||||
_load_base: usize,
|
_load_base: usize,
|
||||||
) -> Result<Option<Self::Value>, Error> {
|
) -> Result<Option<Self::Value>, Error> {
|
||||||
todo!()
|
Err(Error::UnhandledObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,11 +26,48 @@ impl Relocation for Rela {
|
|||||||
|
|
||||||
fn resolve(
|
fn resolve(
|
||||||
&self,
|
&self,
|
||||||
_state: &State,
|
state: &State,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_symbol: &ResolvedSymbol,
|
symbol: &ResolvedSymbol,
|
||||||
_load_base: usize,
|
load_base: usize,
|
||||||
) -> Result<Option<Self::Value>, Error> {
|
) -> 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user