Skip to content

Commit 81767fd

Browse files
authored
read: add more helpers for SymbolIndex and SectionIndex (#689)
1 parent 7b897db commit 81767fd

File tree

6 files changed

+66
-42
lines changed

6 files changed

+66
-42
lines changed

crates/examples/src/readobj/pe.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use object::pe::*;
33
use object::read::coff::ImageSymbol as _;
44
use object::read::coff::*;
55
use object::read::pe::*;
6-
use object::read::{SectionIndex, SymbolIndex};
76
use object::LittleEndian as LE;
87
use object::{Bytes, U32Bytes, U64Bytes};
98

@@ -641,14 +640,14 @@ fn print_relocations<'data, Coff: CoffHeader>(
641640
for relocation in relocations {
642641
p.group("ImageRelocation", |p| {
643642
p.field_hex("VirtualAddress", relocation.virtual_address.get(LE));
644-
let index = relocation.symbol_table_index.get(LE);
643+
let index = relocation.symbol();
645644
let name = symbols.and_then(|symbols| {
646645
symbols
647-
.symbol(SymbolIndex(index as usize))
646+
.symbol(index)
648647
.and_then(|symbol| symbol.name(symbols.strings()))
649648
.print_err(p)
650649
});
651-
p.field_string_option("Symbol", index, name);
650+
p.field_string_option("Symbol", index.0, name);
652651
let proc = match machine {
653652
IMAGE_FILE_MACHINE_I386 => FLAGS_IMAGE_REL_I386,
654653
IMAGE_FILE_MACHINE_MIPS16
@@ -709,17 +708,16 @@ fn print_symbols<'data, Coff: CoffHeader>(
709708
p.field("Name", format!("{:X?}", symbol.raw_name()));
710709
}
711710
p.field_hex("Value", symbol.value());
712-
let section = symbol.section_number();
713-
if section <= 0 {
714-
p.field_enum_display("Section", section, FLAGS_IMAGE_SYM);
715-
} else {
711+
if let Some(section_index) = symbol.section() {
716712
let section_name = sections.and_then(|sections| {
717713
sections
718-
.section(SectionIndex(section as usize))
714+
.section(section_index)
719715
.and_then(|section| section.name(symbols.strings()))
720716
.print_err(p)
721717
});
722-
p.field_string_option("Section", section, section_name);
718+
p.field_string_option("Section", section_index.0, section_name);
719+
} else {
720+
p.field_enum_display("Section", symbol.section_number(), FLAGS_IMAGE_SYM);
723721
}
724722
p.field_hex("Type", symbol.typ());
725723
p.field_enum("BaseType", symbol.base_type(), FLAGS_IMAGE_SYM_TYPE);

crates/examples/src/readobj/xcoff.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use super::*;
22
use object::read::xcoff::*;
3-
use object::read::{SectionIndex, SymbolIndex};
43
use object::xcoff::*;
54

65
pub(super) fn print_xcoff32(p: &mut Printer<'_>, data: &[u8]) {
@@ -126,14 +125,14 @@ fn print_sections<'data, Xcoff: FileHeader>(
126125
for relocation in relocations {
127126
p.group("Relocation", |p| {
128127
p.field_hex("VirtualAddress", relocation.r_vaddr().into());
129-
let index = relocation.r_symndx();
128+
let index = relocation.symbol();
130129
let name = symbols.and_then(|symbols| {
131130
symbols
132-
.symbol(SymbolIndex(index as usize))
131+
.symbol(index)
133132
.and_then(|symbol| symbol.name(symbols.strings()))
134133
.print_err(p)
135134
});
136-
p.field_string_option("Symbol", index, name);
135+
p.field_string_option("Symbol", index.0, name);
137136
p.field_hex("Size", relocation.r_rsize());
138137
p.field_enum("Type", relocation.r_rtype(), FLAGS_R);
139138
});
@@ -161,17 +160,16 @@ fn print_symbols<'data, Xcoff: FileHeader>(
161160
p.field_inline_string("Name", name);
162161
}
163162
p.field_hex("Value", symbol.n_value().into());
164-
let section = symbol.n_scnum();
165-
if section <= 0 {
166-
p.field_enum_display("Section", section, FLAGS_N);
167-
} else {
163+
if let Some(section_index) = symbol.section() {
168164
let section_name = sections.and_then(|sections| {
169165
sections
170-
.section(SectionIndex(section as usize))
166+
.section(section_index)
171167
.map(|section| section.name())
172168
.print_err(p)
173169
});
174-
p.field_string_option("Section", section, section_name);
170+
p.field_string_option("Section", section_index.0, section_name);
171+
} else {
172+
p.field_enum_display("Section", symbol.n_scnum(), FLAGS_N);
175173
}
176174
if symbol.n_sclass() == C_FILE {
177175
p.field_hex("SourceLanguage", symbol.n_type() >> 8);

src/read/coff/relocation.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
8080
},
8181
_ => (RelocationKind::Unknown, 0, 0),
8282
};
83-
let target = RelocationTarget::Symbol(SymbolIndex(
84-
relocation.symbol_table_index.get(LE) as usize,
85-
));
83+
let target = RelocationTarget::Symbol(relocation.symbol());
8684
(
8785
u64::from(relocation.virtual_address.get(LE)),
8886
Relocation {
@@ -106,3 +104,10 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug
106104
f.debug_struct("CoffRelocationIterator").finish()
107105
}
108106
}
107+
108+
impl pe::ImageRelocation {
109+
/// Get the index of the symbol referenced by this relocation.
110+
pub fn symbol(&self) -> SymbolIndex {
111+
SymbolIndex(self.symbol_table_index.get(LE) as usize)
112+
}
113+
}

src/read/coff/symbol.rs

+27-18
Original file line numberDiff line numberDiff line change
@@ -357,21 +357,9 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbol<'data>
357357
}
358358

359359
fn address(&self) -> u64 {
360-
// Only return an address for storage classes that we know use an address.
361-
match self.symbol.storage_class() {
362-
pe::IMAGE_SYM_CLASS_STATIC
363-
| pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL
364-
| pe::IMAGE_SYM_CLASS_LABEL => {}
365-
pe::IMAGE_SYM_CLASS_EXTERNAL => {
366-
if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED {
367-
// Undefined or common data, neither of which have an address.
368-
return 0;
369-
}
370-
}
371-
_ => return 0,
372-
}
373360
self.symbol
374361
.address(self.file.image_base, &self.file.sections)
362+
.unwrap_or(None)
375363
.unwrap_or(0)
376364
}
377365

@@ -565,13 +553,34 @@ pub trait ImageSymbol: Debug + Pod {
565553

566554
/// Return the symbol address.
567555
///
568-
/// This takes into account the image base and the section address.
569-
fn address(&self, image_base: u64, sections: &SectionTable<'_>) -> Result<u64> {
570-
let section_number = SectionIndex(self.section_number() as usize);
571-
let section = sections.section(section_number)?;
556+
/// This takes into account the image base and the section address,
557+
/// and only returns an address for symbols that have an address.
558+
fn address(&self, image_base: u64, sections: &SectionTable<'_>) -> Result<Option<u64>> {
559+
// Only return an address for storage classes that we know use an address.
560+
match self.storage_class() {
561+
pe::IMAGE_SYM_CLASS_STATIC
562+
| pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL
563+
| pe::IMAGE_SYM_CLASS_LABEL
564+
| pe::IMAGE_SYM_CLASS_EXTERNAL => {}
565+
_ => return Ok(None),
566+
}
567+
let Some(section_index) = self.section() else {
568+
return Ok(None);
569+
};
570+
let section = sections.section(section_index)?;
572571
let virtual_address = u64::from(section.virtual_address.get(LE));
573572
let value = u64::from(self.value());
574-
Ok(image_base + virtual_address + value)
573+
Ok(Some(image_base + virtual_address + value))
574+
}
575+
576+
/// Return the section index for the symbol.
577+
fn section(&self) -> Option<SectionIndex> {
578+
let section_number = self.section_number();
579+
if section_number > 0 {
580+
Some(SectionIndex(section_number as usize))
581+
} else {
582+
None
583+
}
575584
}
576585

577586
/// Return true if the symbol is a definition of a function or data object.

src/read/xcoff/relocation.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ where
5656
_ => (RelocationKind::Unknown, 0),
5757
};
5858
let size = (r_rsize & 0x3F) + 1;
59-
let target = RelocationTarget::Symbol(SymbolIndex(relocation.r_symndx() as usize));
59+
let target = RelocationTarget::Symbol(relocation.symbol());
6060
(
6161
relocation.r_vaddr().into(),
6262
Relocation {
@@ -91,6 +91,10 @@ pub trait Rel: Debug + Pod {
9191
fn r_symndx(&self) -> u32;
9292
fn r_rsize(&self) -> u8;
9393
fn r_rtype(&self) -> u8;
94+
95+
fn symbol(&self) -> SymbolIndex {
96+
SymbolIndex(self.r_symndx() as usize)
97+
}
9498
}
9599

96100
impl Rel for xcoff::Rel32 {

src/read/xcoff/symbol.rs

+10
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,16 @@ pub trait Symbol: Debug + Pod {
552552
strings: StringTable<'data, R>,
553553
) -> Result<&'data [u8]>;
554554

555+
/// Return the section index for the symbol.
556+
fn section(&self) -> Option<SectionIndex> {
557+
let index = self.n_scnum();
558+
if index > 0 {
559+
Some(SectionIndex(index as usize))
560+
} else {
561+
None
562+
}
563+
}
564+
555565
/// Return true if the symbol is a null placeholder.
556566
#[inline]
557567
fn is_null(&self) -> bool {

0 commit comments

Comments
 (0)