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) } } } } }