Fix build for i686

This commit is contained in:
Jeremy Soller
2025-01-14 18:01:26 -07:00
parent b011dbe366
commit a3c12e27e4
2 changed files with 38 additions and 12 deletions
+37 -12
View File
@@ -32,6 +32,18 @@ use core::{
slice,
};
#[cfg(target_pointer_width = "32")]
mod shim {
use object::{elf::*, read::elf::ElfFile32, NativeEndian};
pub type Dyn = Dyn32<NativeEndian>;
pub type Rel = Rel32<NativeEndian>;
pub type Rela = Rela32<NativeEndian>;
pub type Sym = Sym32<NativeEndian>;
pub type FileHeader = FileHeader32<NativeEndian>;
pub type ProgramHeader = ProgramHeader32<NativeEndian>;
pub type ElfFile<'a> = ElfFile32<'a, NativeEndian>;
}
#[cfg(target_pointer_width = "64")]
mod shim {
use object::{elf::*, read::elf::ElfFile64, NativeEndian};
@@ -44,12 +56,8 @@ mod shim {
pub type ElfFile<'a> = ElfFile64<'a, NativeEndian>;
}
#[cfg(target_pointer_width = "64")]
pub use shim::*;
#[cfg(target_pointer_width = "32")]
type Dyn = Dyn32<NativeEndian>;
enum HashTable<'a> {
Gnu(GnuHashTable<'a, FileHeader>),
Sysv(SysVHashTable<'a, FileHeader>),
@@ -159,6 +167,19 @@ struct Relocation {
kind: u32,
}
#[cfg(target_pointer_width = "32")]
impl From<&Rela> for Relocation {
fn from(reloc: &Rela) -> Self {
Self {
offset: reloc.r_offset(NativeEndian) as usize,
addend: reloc.r_addend(NativeEndian) as usize,
sym: SymbolIndex(reloc.r_sym(NativeEndian) as usize),
kind: reloc.r_type(NativeEndian),
}
}
}
#[cfg(target_pointer_width = "64")]
impl From<&Rela> for Relocation {
fn from(reloc: &Rela) -> Self {
let is_mips64el = cfg!(all(target_arch = "mips64", target_endian = "little"));
@@ -542,8 +563,8 @@ impl DSO {
for (i, entry) in entries.iter().enumerate() {
let val = entry.d_val(NativeEndian);
let relative_idx = val - if is_pie { 0 } else { mmap.as_ptr() as u64 };
let ptr = (val + if is_pie { mmap.as_ptr() as u64 } else { 0 }) as *const u8;
let relative_idx = val as usize - if is_pie { 0 } else { mmap.as_ptr() as usize };
let ptr = (val as usize + if is_pie { mmap.as_ptr() as usize } else { 0 }) as *const u8;
let tag = entry.d_tag(NativeEndian) as u32;
match tag {
@@ -555,14 +576,14 @@ impl DSO {
// > `data` will be used as the hash table values. It does not
// > matter if this is longer than needed...
elf::DT_GNU_HASH => {
let value = GnuHashTable::parse(NativeEndian, &mmap[relative_idx as usize..])?;
let value = GnuHashTable::parse(NativeEndian, &mmap[relative_idx..])?;
hash_table = Some(HashTable::Gnu(value));
}
// XXX: Both GNU_HASH and HASH may be present, we give priority
// to GNU_HASH as it is significantly faster.
elf::DT_HASH if hash_table.is_none() => {
let value = SysVHashTable::parse(NativeEndian, &mmap[relative_idx as usize..])?;
let value = SysVHashTable::parse(NativeEndian, &mmap[relative_idx..])?;
hash_table = Some(HashTable::Sysv(value));
}
@@ -580,13 +601,13 @@ impl DSO {
elf::DT_RELA => rela_offset = Some(ptr.cast::<Rela>()),
elf::DT_RELASZ => rela_size = Some(val as usize / size_of::<Rela>()),
elf::DT_RELAENT => {
assert_eq!(val, size_of::<elf::Rela64<Endianness>>() as u64)
assert_eq!(val as usize, size_of::<elf::Rela64<Endianness>>())
}
elf::DT_REL => rel_ptr = Some(ptr.cast::<Rel>()),
elf::DT_RELSZ => rel_size = Some(val as usize / size_of::<Rel>()),
elf::DT_RELENT => {
assert_eq!(val, size_of::<elf::Rel64<Endianness>>() as u64)
assert_eq!(val as usize, size_of::<elf::Rel64<Endianness>>())
}
elf::DT_PLTREL => {
@@ -608,7 +629,7 @@ impl DSO {
elf::DT_SYMTAB => symtab_ptr = Some(ptr as *const Sym),
elf::DT_SYMENT => {
assert_eq!(val, size_of::<Sym64<NativeEndian>>() as u64);
assert_eq!(val as usize, size_of::<Sym64<NativeEndian>>());
}
_ => {}
@@ -618,7 +639,11 @@ impl DSO {
let strtab_offset = strtab_offset.expect("mandatory DT_STRTAB not present");
let strtab_size = strtab_size.expect("mandatory DT_STRSZ not present");
let dynstrtab = StringTable::new(&*mmap, strtab_offset, strtab_offset + strtab_size);
let dynstrtab = StringTable::new(
&*mmap,
strtab_offset as u64,
strtab_offset as u64 + strtab_size as u64,
);
let get_str = |entry: &Dyn| {
entry
+1
View File
@@ -878,6 +878,7 @@ impl Linker {
// The trampoline will then jump to the resolved symbol.
//
// FIXME(andypython): 32-bit
#[cfg(target_pointer_width = "64")]
extern "C" fn __plt_resolve_inner(obj: *const DSO, relocation_index: c_uint) -> *mut c_void {
let obj = unsafe { &*obj };
let obj_base = obj.mmap.as_ptr() as usize;