use elf::relocation::{Rel, Rela};
use crate::{error::Error, object::ResolvedSymbol, state::State};
use super::{RelValue, RelaValue, Relocation};
impl Relocation for Rela {
type Value = RelaValue;
fn resolve(
&self,
_state: &State,
_name: &str,
_symbol: &ResolvedSymbol,
_load_base: usize,
) -> Result, Error> {
unimplemented!("rela-type relocations are not implemented for i686")
}
}
impl Relocation for Rel {
type Value = RelValue;
fn resolve(
&self,
state: &State,
name: &str,
symbol: &ResolvedSymbol,
load_base: usize,
) -> Result , Error> {
match symbol {
ResolvedSymbol::Tls(tls) => match self.r_type {
// R_386_DTPMOD32: TLS module ID
35 => Ok(Some(RelValue::DWordNoAddend(tls.module_id as _))),
// R_386_DTPOFF32: TLS offset within a module
36 => Ok(Some(RelValue::DWordNoAddend(tls.offset as _))),
// R_386_TPOFF: tp-relative offset
14 => {
// Need to extract fixed global offset
let tls_layout = state.tls_layout.as_ref().unwrap();
// Offset from TLS start
let offset = tls_layout.offset(tls.module_id, tls.offset).unwrap();
let offset_from_tp = -((tls_layout.tp_offset - offset) as i32);
log::debug!("{}@tpoff -> {}", name, offset_from_tp);
Ok(Some(RelValue::DWordNoAddend(offset_from_tp)))
}
// 14 => Ok(Some(RelValue::DWordNoAddend()))
_ => todo!("Unsupported relocation against TLS symbol: {}", self.r_type)
},
&ResolvedSymbol::Null(object_id) => match self.r_type {
// R_386_RELATIVE: B + A
8 => Ok(Some(RelValue::DWord(load_base as _))),
// R_386_DTPMOD32: TLS module ID
35 => Ok(Some(RelValue::DWordNoAddend(object_id as _))),
_ => todo!("Unsupported relocation against NULL symbol: {}", self.r_type),
}
_ => {
let s: i32 = symbol.value().try_into().unwrap();
if s == 0 {
todo!("Relocation: r_type={}, name={name} is NULL", self.r_type)
}
match self.r_type {
// R_386_32: S + A
1 => Ok(Some(RelValue::DWord(s))),
// R_386_GLOB_DAT: S
// R_386_JMP_SLOT: S
6 | 7 => Ok(Some(RelValue::DWordNoAddend(s))),
_ => todo!("Unsupported relocation type: {}", self.r_type)
}
}
}
}
}