Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read: add helpers to unified API for accessing lower level API #678

Merged
merged 4 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading
Loading