Skip to content

Commit

Permalink
read: add helpers to unified API for accessing lower level API (#678)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc committed May 5, 2024
1 parent b9154d0 commit 2d2fc7e
Show file tree
Hide file tree
Showing 16 changed files with 330 additions and 10 deletions.
15 changes: 15 additions & 0 deletions src/read/coff/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ impl<'data, R: ReadRef<'data>, Coff: CoffHeader> CoffFile<'data, R, Coff> {
data,
})
}

/// Get the raw COFF file header.
pub fn coff_header(&self) -> &'data Coff {
self.header
}

/// Get the COFF section table.
pub fn coff_section_table(&self) -> SectionTable<'data> {
self.common.sections
}

/// Get the COFF symbol table.
pub fn coff_symbol_table(&self) -> &SymbolTable<'data, R, Coff> {
&self.common.symbols
}
}

impl<'data, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
Expand Down
27 changes: 26 additions & 1 deletion src/read/coff/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@ pub struct CoffSegment<
}

impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSegment<'data, 'file, R, Coff> {
/// Get the COFF file containing this segment.
pub fn coff_file(&self) -> &'file CoffFile<'data, R, Coff> {
self.file
}

/// Get the raw COFF section header.
pub fn coff_section(&self) -> &'data pe::ImageSectionHeader {
self.section
}

fn bytes(&self) -> Result<&'data [u8]> {
self.section
.coff_data(self.file.data)
Expand Down Expand Up @@ -281,6 +291,21 @@ pub struct CoffSection<
}

impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSection<'data, 'file, R, Coff> {
/// Get the COFF file containing this section.
pub fn coff_file(&self) -> &'file CoffFile<'data, R, Coff> {
self.file
}

/// Get the raw COFF section header.
pub fn coff_section(&self) -> &'data pe::ImageSectionHeader {
self.section
}

/// Get the raw COFF relocations for this section.
pub fn coff_relocations(&self) -> Result<&'data [pe::ImageRelocation]> {
self.section.coff_relocations(self.file.data)
}

fn bytes(&self) -> Result<&'data [u8]> {
self.section
.coff_data(self.file.data)
Expand Down Expand Up @@ -377,7 +402,7 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSection<'data>
}

fn relocations(&self) -> CoffRelocationIterator<'data, 'file, R, Coff> {
let relocations = self.section.coff_relocations(self.file.data).unwrap_or(&[]);
let relocations = self.coff_relocations().unwrap_or(&[]);
CoffRelocationIterator {
file: self.file,
iter: relocations.iter(),
Expand Down
6 changes: 6 additions & 0 deletions src/read/coff/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,15 @@ where
impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSymbol<'data, 'file, R, Coff> {
#[inline]
/// Get the raw `ImageSymbol` struct.
#[deprecated(note = "Use `coff_symbol` instead")]
pub fn raw_symbol(&self) -> &'data Coff::ImageSymbol {
self.symbol
}

/// Get the raw `ImageSymbol` struct.
pub fn coff_symbol(&self) -> &'data Coff::ImageSymbol {
self.symbol
}
}

impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
Expand Down
10 changes: 10 additions & 0 deletions src/read/elf/comdat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ where
sections,
})
}

/// Get the ELF file containing this COMDAT section group.
pub fn elf_file(&self) -> &'file ElfFile<'data, Elf, R> {
self.file
}

/// Get the raw ELF section header for the COMDAT section group.
pub fn elf_section_header(&self) -> &'data Elf::SectionHeader {
self.section
}
}

impl<'data, 'file, Elf, R> read::private::Sealed for ElfComdat<'data, 'file, Elf, R>
Expand Down
40 changes: 40 additions & 0 deletions src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,55 @@ where
}

/// Returns the raw ELF file header.
#[deprecated(note = "Use `elf_header` instead")]
pub fn raw_header(&self) -> &'data Elf {
self.header
}

/// Returns the raw ELF segments.
#[deprecated(note = "Use `elf_program_headers` instead")]
pub fn raw_segments(&self) -> &'data [Elf::ProgramHeader] {
self.segments
}

/// Get the raw ELF file header.
pub fn elf_header(&self) -> &'data Elf {
self.header
}

/// Get the raw ELF program headers.
///
/// Returns an empty slice if the file has no program headers.
pub fn elf_program_headers(&self) -> &'data [Elf::ProgramHeader] {
self.segments
}

/// Get the ELF section table.
///
/// Returns an empty section table if the file has no section headers.
pub fn elf_section_table(&self) -> &SectionTable<'data, Elf, R> {
&self.sections
}

/// Get the ELF symbol table.
///
/// Returns an empty symbol table if the file has no symbol table.
pub fn elf_symbol_table(&self) -> &SymbolTable<'data, Elf, R> {
&self.symbols
}

/// Get the ELF dynamic symbol table.
///
/// Returns an empty symbol table if the file has no dynamic symbol table.
pub fn elf_dynamic_symbol_table(&self) -> &SymbolTable<'data, Elf, R> {
&self.dynamic_symbols
}

/// Get a mapping for linked relocation sections.
pub fn elf_relocation_sections(&self) -> &RelocationSections {
&self.relocations
}

fn raw_section_by_name<'file>(
&'file self,
section_name: &[u8],
Expand Down
65 changes: 65 additions & 0 deletions src/read/elf/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,71 @@ where
}

impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSection<'data, 'file, Elf, R> {
/// Get the ELF file containing this section.
pub fn elf_file(&self) -> &'file ElfFile<'data, Elf, R> {
self.file
}

/// Get the raw ELF section header.
pub fn elf_section_header(&self) -> &'data Elf::SectionHeader {
self.section
}

/// Get the index of the relocation section that references this section.
///
/// Returns `None` if there are no relocations.
/// Returns an error if there are multiple relocation sections that reference this section.
pub fn elf_relocation_section_index(&self) -> read::Result<Option<SectionIndex>> {
let Some(relocation_index) = self.file.relocations.get(self.index) else {
return Ok(None);
};
if self.file.relocations.get(relocation_index).is_some() {
return Err(Error(
"Unsupported ELF section with multiple relocation sections",
));
}
Ok(Some(relocation_index))
}

/// Get the relocation section that references this section.
///
/// Returns `None` if there are no relocations.
/// Returns an error if there are multiple relocation sections that reference this section.
pub fn elf_relocation_section(&self) -> read::Result<Option<&'data Elf::SectionHeader>> {
let Some(relocation_index) = self.elf_relocation_section_index()? else {
return Ok(None);
};
self.file.sections.section(relocation_index).map(Some)
}

/// Get the `Elf::Rel` entries that apply to this section.
///
/// Returns an empty slice if there are no relocations.
/// Returns an error if there are multiple relocation sections that reference this section.
pub fn elf_linked_rel(&self) -> read::Result<&'data [Elf::Rel]> {
let Some(relocation_section) = self.elf_relocation_section()? else {
return Ok(&[]);
};
let Some((rel, _)) = relocation_section.rel(self.file.endian, self.file.data)? else {
return Ok(&[]);
};
Ok(rel)
}

/// Get the `Elf::Rela` entries that apply to this section.
///
/// Returns an empty slice if there are no relocations.
/// Returns an error if there are multiple relocation sections that reference this section.
pub fn elf_linked_rela(&self) -> read::Result<&'data [Elf::Rela]> {
let Some(relocation_section) = self.elf_relocation_section()? else {
return Ok(&[]);
};
let Some((rela, _)) = relocation_section.rela(self.file.endian, self.file.data)? else {
return Ok(&[]);
};
Ok(rela)
}

fn bytes(&self) -> read::Result<&'data [u8]> {
self.section
.data(self.file.endian, self.file.data)
Expand Down
10 changes: 10 additions & 0 deletions src/read/elf/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ where
}

impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSegment<'data, 'file, Elf, R> {
/// Get the ELF file containing this segment.
pub fn elf_file(&self) -> &'file ElfFile<'data, Elf, R> {
self.file
}

/// Get the raw ELF program header for the segment.
pub fn elf_program_header(&self) -> &'data Elf::ProgramHeader {
self.segment
}

fn bytes(&self) -> read::Result<&'data [u8]> {
self.segment
.data(self.file.endian, self.file.data)
Expand Down
11 changes: 11 additions & 0 deletions src/read/elf/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,22 @@ where
}

impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSymbol<'data, 'file, Elf, R> {
/// Get the endianness of the ELF file.
pub fn endian(&self) -> Elf::Endian {
self.endian
}

/// Return a reference to the raw symbol structure.
#[inline]
#[deprecated(note = "Use `elf_symbol` instead")]
pub fn raw_symbol(&self) -> &'data Elf::Sym {
self.symbol
}

/// Get the raw ELF symbol structure.
pub fn elf_symbol(&self) -> &'data Elf::Sym {
self.symbol
}
}

impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed
Expand Down
19 changes: 19 additions & 0 deletions src/read/macho/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,29 @@ where
}

/// Returns the raw Mach-O file header.
#[deprecated(note = "Use `macho_header` instead")]
pub fn raw_header(&self) -> &'data Mach {
self.header
}

/// Get the raw Mach-O file header.
pub fn macho_header(&self) -> &'data Mach {
self.header
}

/// Get the Mach-O load commands.
pub fn macho_load_commands(&self) -> Result<LoadCommandIterator<'data, Mach::Endian>> {
self.header
.load_commands(self.endian, self.data, self.header_offset)
}

/// Get the Mach-O symbol table.
///
/// Returns an empty symbol table if the file has no symbol table.
pub fn macho_symbol_table(&self) -> &SymbolTable<'data, Mach, R> {
&self.symbols
}

/// Return the `LC_BUILD_VERSION` load command if present.
pub fn build_version(&self) -> Result<Option<&'data macho::BuildVersionCommand<Mach::Endian>>> {
let mut commands = self
Expand Down
24 changes: 18 additions & 6 deletions src/read/macho/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ where
Mach: MachHeader,
R: ReadRef<'data>,
{
/// Get the Mach-O file containing this section.
pub fn macho_file(&self) -> &'file MachOFile<'data, Mach, R> {
self.file
}

/// Get the raw Mach-O section structure.
pub fn macho_section(&self) -> &'data Mach::Section {
self.internal.section
}

/// Get the raw Mach-O relocation entries.
pub fn macho_relocations(&self) -> Result<&'data [macho::Relocation<Mach::Endian>]> {
self.internal
.section
.relocations(self.file.endian, self.internal.data)
}

fn bytes(&self) -> Result<&'data [u8]> {
self.internal
.section
Expand Down Expand Up @@ -188,12 +205,7 @@ where
fn relocations(&self) -> MachORelocationIterator<'data, 'file, Mach, R> {
MachORelocationIterator {
file: self.file,
relocations: self
.internal
.section
.relocations(self.file.endian, self.internal.data)
.unwrap_or(&[])
.iter(),
relocations: self.macho_relocations().unwrap_or(&[]).iter(),
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/read/macho/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ where
Mach: MachHeader,
R: ReadRef<'data>,
{
/// Get the Mach-O file containing this segment.
pub fn macho_file(&self) -> &'file MachOFile<'data, Mach, R> {
self.file
}

/// Get the raw Mach-O segment structure.
pub fn macho_segment(&self) -> &'data Mach::Segment {
self.internal.segment
}

fn bytes(&self) -> Result<&'data [u8]> {
self.internal
.segment
Expand Down
10 changes: 10 additions & 0 deletions src/read/macho/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@ where
}
Some(MachOSymbol { file, index, nlist })
}

/// Get the Mach-O file containing this symbol.
pub fn macho_file(&self) -> &'file MachOFile<'data, Mach, R> {
self.file
}

/// Get the raw Mach-O symbol structure.
pub fn macho_symbol(&self) -> &'data Mach::Nlist {
self.nlist
}
}

impl<'data, 'file, Mach, R> read::private::Sealed for MachOSymbol<'data, 'file, Mach, R>
Expand Down

0 comments on commit 2d2fc7e

Please sign in to comment.