Skip to content

Commit

Permalink
Support partial reading of string tables.
Browse files Browse the repository at this point in the history
  • Loading branch information
mstange committed Jun 15, 2021
1 parent 7554dc7 commit 1b4647d
Show file tree
Hide file tree
Showing 17 changed files with 316 additions and 191 deletions.
2 changes: 1 addition & 1 deletion examples/readobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ mod elf {
let mut dynstr = object::StringTable::default();
for s in segments {
if let Ok(Some(data)) = s.data_range(endian, data, strtab, strsz) {
dynstr = object::StringTable::new(data);
dynstr = object::StringTable::new(data, 0, data.len() as u64);
break;
}
}
Expand Down
60 changes: 45 additions & 15 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,11 +890,21 @@ where
R: ReadRef<'data>,
{
#[cfg(feature = "coff")]
Coff((coff::CoffSymbolTable<'data, 'file>, PhantomData<R>)),
Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "elf")]
Elf32((elf::ElfSymbolTable32<'data, 'file>, PhantomData<R>)),
Elf32(
(
elf::ElfSymbolTable32<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "elf")]
Elf64((elf::ElfSymbolTable64<'data, 'file>, PhantomData<R>)),
Elf64(
(
elf::ElfSymbolTable64<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "macho")]
MachO32(
(
Expand All @@ -910,9 +920,9 @@ where
),
),
#[cfg(feature = "pe")]
Pe32((coff::CoffSymbolTable<'data, 'file>, PhantomData<R>)),
Pe32((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "pe")]
Pe64((coff::CoffSymbolTable<'data, 'file>, PhantomData<R>)),
Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)),
}
Expand Down Expand Up @@ -960,11 +970,21 @@ where
R: ReadRef<'data>,
{
#[cfg(feature = "coff")]
Coff((coff::CoffSymbolIterator<'data, 'file>, PhantomData<R>)),
Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "elf")]
Elf32((elf::ElfSymbolIterator32<'data, 'file>, PhantomData<R>)),
Elf32(
(
elf::ElfSymbolIterator32<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "elf")]
Elf64((elf::ElfSymbolIterator64<'data, 'file>, PhantomData<R>)),
Elf64(
(
elf::ElfSymbolIterator64<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "macho")]
MachO32(
(
Expand All @@ -980,9 +1000,9 @@ where
),
),
#[cfg(feature = "pe")]
Pe32((coff::CoffSymbolIterator<'data, 'file>, PhantomData<R>)),
Pe32((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "pe")]
Pe64((coff::CoffSymbolIterator<'data, 'file>, PhantomData<R>)),
Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)),
}
Expand Down Expand Up @@ -1013,11 +1033,21 @@ where
R: ReadRef<'data>,
{
#[cfg(feature = "coff")]
Coff((coff::CoffSymbol<'data, 'file>, PhantomData<R>)),
Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "elf")]
Elf32((elf::ElfSymbol32<'data, 'file>, PhantomData<R>)),
Elf32(
(
elf::ElfSymbol32<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "elf")]
Elf64((elf::ElfSymbol64<'data, 'file>, PhantomData<R>)),
Elf64(
(
elf::ElfSymbol64<'data, 'file, Endianness, R>,
PhantomData<R>,
),
),
#[cfg(feature = "macho")]
MachO32(
(
Expand All @@ -1033,9 +1063,9 @@ where
),
),
#[cfg(feature = "pe")]
Pe32((coff::CoffSymbol<'data, 'file>, PhantomData<R>)),
Pe32((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "pe")]
Pe64((coff::CoffSymbol<'data, 'file>, PhantomData<R>)),
Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)),
}
Expand Down
27 changes: 15 additions & 12 deletions src/read/coff/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ use super::{

/// The common parts of `PeFile` and `CoffFile`.
#[derive(Debug)]
pub(crate) struct CoffCommon<'data> {
pub(crate) struct CoffCommon<'data, R: ReadRef<'data>> {
pub(crate) sections: SectionTable<'data>,
// TODO: ImageSymbolExBytes
pub(crate) symbols: SymbolTable<'data>,
pub(crate) symbols: SymbolTable<'data, R>,
pub(crate) image_base: u64,
}

/// A COFF object file.
#[derive(Debug)]
pub struct CoffFile<'data, R: ReadRef<'data> = &'data [u8]> {
pub(super) header: &'data pe::ImageFileHeader,
pub(super) common: CoffCommon<'data>,
pub(super) common: CoffCommon<'data, R>,
pub(super) data: R,
}

Expand Down Expand Up @@ -63,9 +63,9 @@ where
type SectionIterator = CoffSectionIterator<'data, 'file, R>;
type Comdat = CoffComdat<'data, 'file, R>;
type ComdatIterator = CoffComdatIterator<'data, 'file, R>;
type Symbol = CoffSymbol<'data, 'file>;
type SymbolIterator = CoffSymbolIterator<'data, 'file>;
type SymbolTable = CoffSymbolTable<'data, 'file>;
type Symbol = CoffSymbol<'data, 'file, R>;
type SymbolIterator = CoffSymbolIterator<'data, 'file, R>;
type SymbolTable = CoffSymbolTable<'data, 'file, R>;
type DynamicRelocationIterator = NoDynamicRelocationIterator;

fn architecture(&self) -> Architecture {
Expand Down Expand Up @@ -124,7 +124,7 @@ where
}
}

fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<CoffSymbol<'data, 'file>> {
fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<CoffSymbol<'data, 'file, R>> {
let symbol = self.common.symbols.symbol(index.0)?;
Ok(CoffSymbol {
file: &self.common,
Expand All @@ -133,19 +133,19 @@ where
})
}

fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file> {
fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> {
CoffSymbolIterator {
file: &self.common,
index: 0,
}
}

#[inline]
fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file>> {
fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> {
Some(CoffSymbolTable { file: &self.common })
}

fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file> {
fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> {
CoffSymbolIterator {
file: &self.common,
// Hack: don't return any.
Expand All @@ -154,7 +154,7 @@ where
}

#[inline]
fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file>> {
fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> {
None
}

Expand Down Expand Up @@ -232,7 +232,10 @@ impl pe::ImageFileHeader {
///
/// `data` must be the entire file data.
#[inline]
pub fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<SymbolTable<'data>> {
pub fn symbols<'data, R: ReadRef<'data>>(
&self,
data: R,
) -> read::Result<SymbolTable<'data, R>> {
SymbolTable::parse(self, data)
}
}
9 changes: 6 additions & 3 deletions src/read/coff/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ impl<'data> SectionTable<'data> {
/// The returned index is 1-based.
///
/// Ignores sections with invalid names.
pub fn section_by_name(
pub fn section_by_name<R: ReadRef<'data>>(
&self,
strings: StringTable<'data>,
strings: StringTable<'data, R>,
name: &[u8],
) -> Option<(usize, &'data pe::ImageSectionHeader)> {
self.sections
Expand Down Expand Up @@ -310,7 +310,10 @@ impl pe::ImageSectionHeader {
/// Return the section name.
///
/// This handles decoding names that are offsets into the symbol string table.
pub fn name<'data>(&'data self, strings: StringTable<'data>) -> Result<&'data [u8]> {
pub fn name<'data, R: ReadRef<'data>>(
&'data self,
strings: StringTable<'data, R>,
) -> Result<&'data [u8]> {
let bytes = &self.name;
Ok(if bytes[0] == b'/' {
let mut offset = 0;
Expand Down
Loading

0 comments on commit 1b4647d

Please sign in to comment.