From f1e5e5753d3d5320f8b83674447c3d9983ba79e7 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Wed, 30 Sep 2026 00:22:24 -0700 Subject: [PATCH] perf: decode RELA relocations into native integers up front --- libwild/src/elf.rs | 34 +++++++++++++++++++++++++++------- libwild/src/elf_writer.rs | 9 ++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index fc760476d..5d7c5009f 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -522,14 +522,34 @@ pub(crate) struct File<'data, C: ElfClass> { pub(crate) dynamic_tag_values: Option>, } +/// A RELA relocation, decoded from its on-disk form up front. Holding native integers rather +/// than the raw, byte-aligned `Rela` means each field is a plain load, instead of reassembling +/// it from a stack copy of the raw bytes. #[derive(Clone, Copy)] pub(crate) struct ElfRela { - raw: Rela, + offset: u64, + addend: i64, + sym: u32, + r_type: object::elf::RelocationType, + class: PhantomData, } impl ElfRela { + #[inline(always)] pub(crate) fn new(raw: Rela) -> Self { - Self { raw } + Self::from_raw(&raw) + } + + #[inline(always)] + pub(crate) fn from_raw(raw: &Rela) -> Self { + use object::read::elf::Rela as _; + Self { + offset: raw.r_offset(LittleEndian).into(), + addend: raw.r_addend(LittleEndian).into(), + sym: raw.r_sym(LittleEndian, false), + r_type: raw.r_type(LittleEndian, false), + class: PhantomData, + } } } @@ -538,19 +558,19 @@ impl Relocation for ElfRela { type Platform = Elf; fn symbol(&self) -> Option { - object::read::elf::Rela::symbol(&self.raw, LittleEndian, false) + (self.sym != 0).then_some(object::SymbolIndex(self.sym as usize)) } fn raw_type(&self) -> object::elf::RelocationType { - object::read::elf::Rela::r_type(&self.raw, LittleEndian, false) + self.r_type } fn offset(&self) -> u64 { - object::read::elf::Rela::r_offset(&self.raw, LittleEndian).into() + self.offset } fn addend(&self) -> i64 { - object::read::elf::Rela::r_addend(&self.raw, LittleEndian).into() + self.addend } } @@ -613,7 +633,7 @@ impl<'data, C: ElfClass> RelocationSequence<'data> for RelaSequence<'data, C> { type Rel = ElfRela; fn rel_iter(&self) -> impl Iterator> { - self.0.iter().copied().map(|raw| ElfRela { raw }) + self.0.iter().map(ElfRela::from_raw) } fn subsequence(&self, range: Range) -> Self { diff --git a/libwild/src/elf_writer.rs b/libwild/src/elf_writer.rs index 654c8ab19..9d6b95d64 100644 --- a/libwild/src/elf_writer.rs +++ b/libwild/src/elf_writer.rs @@ -2887,7 +2887,7 @@ fn apply_debug_rela_relocations<'data, C: ElfClass, A: Arch>>( table_writer, trace, eh_frame_section, - relocations.iter().copied().map(elf::ElfRela::new), + relocations.iter().map(elf::ElfRela::from_raw), ) } elf::RelocationList::Crel(relocations) => {