Skip to content

Commit 017624a

Browse files
authored
read: use SectionIndex/SymbolIndex in low level API (#684)
Note that many APIs returned unvalidated indices. Validation is performed when they are used to access a table entry. For cases where a 0 index is normal, an Option may be returned.
1 parent a739147 commit 017624a

23 files changed

+358
-219
lines changed

crates/examples/src/bin/pecopy.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ fn copy_file<Pe: ImageNtHeaders>(in_data: &[u8]) -> Result<Vec<u8>, Box<dyn Erro
9898
// Determine which sections to copy.
9999
// We ignore any existing ".reloc" section since we recreate it ourselves.
100100
let mut in_sections_index = Vec::new();
101-
for (index, in_section) in in_sections.iter().enumerate() {
101+
for (index, in_section) in in_sections.enumerate() {
102102
if reloc_dir == Some(in_section.pe_address_range()) {
103103
continue;
104104
}
105-
in_sections_index.push(index + 1);
105+
in_sections_index.push(index);
106106
}
107107

108108
let mut out_sections_len = in_sections_index.len();

crates/examples/src/objdump.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,21 @@ fn dump_parsed_object<W: Write, E: Write>(w: &mut W, e: &mut E, file: &object::F
183183
}
184184

185185
for section in file.sections() {
186-
writeln!(w, "{}: {:x?}", section.index().0, section)?;
186+
writeln!(w, "{}: {:x?}", section.index(), section)?;
187187
}
188188

189189
for comdat in file.comdats() {
190190
write!(w, "{:?} Sections:", comdat)?;
191191
for section in comdat.sections() {
192-
write!(w, " {}", section.0)?;
192+
write!(w, " {}", section)?;
193193
}
194194
writeln!(w)?;
195195
}
196196

197197
writeln!(w)?;
198198
writeln!(w, "Symbols")?;
199199
for symbol in file.symbols() {
200-
writeln!(w, "{}: {:x?}", symbol.index().0, symbol)?;
200+
writeln!(w, "{}: {:x?}", symbol.index(), symbol)?;
201201
}
202202

203203
for section in file.sections() {
@@ -216,7 +216,7 @@ fn dump_parsed_object<W: Write, E: Write>(w: &mut W, e: &mut E, file: &object::F
216216
writeln!(w)?;
217217
writeln!(w, "Dynamic symbols")?;
218218
for symbol in file.dynamic_symbols() {
219-
writeln!(w, "{}: {:x?}", symbol.index().0, symbol)?;
219+
writeln!(w, "{}: {:x?}", symbol.index(), symbol)?;
220220
}
221221

222222
if let Some(relocations) = file.dynamic_relocations() {

crates/examples/src/readobj/elf.rs

+14-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use object::elf::*;
33
use object::read::elf::*;
4-
use object::read::{SectionIndex, StringTable};
4+
use object::read::{SectionIndex, StringTable, SymbolIndex};
55

66
pub(super) fn print_elf32(p: &mut Printer<'_>, data: &[u8]) {
77
if let Some(elf) = FileHeader32::<Endianness>::parse(data).print_err(p) {
@@ -239,7 +239,7 @@ fn print_section_headers<Elf: FileHeader>(
239239
elf: &Elf,
240240
sections: &SectionTable<Elf>,
241241
) {
242-
for (index, section) in sections.iter().enumerate() {
242+
for (index, section) in sections.enumerate() {
243243
let sh_type = section.sh_type(endian);
244244
if !p.options.sections
245245
&& !(p.options.symbols && sh_type == SHT_SYMTAB)
@@ -255,7 +255,6 @@ fn print_section_headers<Elf: FileHeader>(
255255
{
256256
continue;
257257
}
258-
let index = SectionIndex(index);
259258
p.group("SectionHeader", |p| {
260259
p.field("Index", index.0);
261260
p.field_string(
@@ -394,10 +393,10 @@ fn print_section_symbols<Elf: FileHeader>(
394393
EM_PARISC => FLAGS_SHN_PARISC,
395394
_ => &[],
396395
};
397-
for (index, symbol) in symbols.iter().enumerate() {
396+
for (index, symbol) in symbols.enumerate() {
398397
p.group("Symbol", |p| {
399-
p.field("Index", index);
400-
if index == 0 {
398+
p.field("Index", index.0);
399+
if index == SymbolIndex(0) {
401400
p.field_hex("Name", symbol.st_name(endian));
402401
} else {
403402
p.field_string(
@@ -466,7 +465,7 @@ fn print_section_rel<Elf: FileHeader>(
466465
p.group("Relocation", |p| {
467466
p.field_hex("Offset", relocation.r_offset(endian).into());
468467
p.field_enum("Type", relocation.r_type(endian), proc);
469-
let sym = relocation.r_sym(endian);
468+
let sym = relocation.symbol(endian);
470469
print_rel_symbol(p, endian, symbols, sym);
471470
});
472471
}
@@ -497,7 +496,7 @@ fn print_section_rela<Elf: FileHeader>(
497496
relocation.r_type(endian, elf.is_mips64el(endian)),
498497
proc,
499498
);
500-
let sym = relocation.r_sym(endian, elf.is_mips64el(endian));
499+
let sym = relocation.symbol(endian, elf.is_mips64el(endian));
501500
print_rel_symbol(p, endian, symbols, sym);
502501
let addend = relocation.r_addend(endian).into() as u64;
503502
if addend != 0 {
@@ -512,19 +511,19 @@ fn print_rel_symbol<Elf: FileHeader>(
512511
p: &mut Printer<'_>,
513512
endian: Elf::Endian,
514513
symbols: Option<SymbolTable<'_, Elf>>,
515-
sym: u32,
514+
index: Option<SymbolIndex>,
516515
) {
517-
if sym == 0 {
518-
p.field_hex("Symbol", sym);
516+
let Some(index) = index else {
517+
p.field_hex("Symbol", 0);
519518
return;
520-
}
519+
};
521520
let name = symbols.and_then(|symbols| {
522521
symbols
523-
.symbol(sym as usize)
522+
.symbol(index)
524523
.and_then(|symbol| symbol.name(endian, symbols.strings()))
525524
.print_err(p)
526525
});
527-
p.field_string_option("Symbol", sym, name);
526+
p.field_string_option("Symbol", index.0, name);
528527
}
529528

530529
fn rel_flag_type<Elf: FileHeader>(endian: Elf::Endian, elf: &Elf) -> &'static [Flag<u32>] {
@@ -760,7 +759,7 @@ fn print_hash<Elf: FileHeader>(
760759
if let Ok(Some((hash_table, link))) = section.hash(endian, data) {
761760
if let Ok(symbols) = _sections.symbol_table_by_index(endian, data, link) {
762761
if let Ok(versions) = _sections.versions(endian, data) {
763-
for (index, symbol) in symbols.symbols().iter().enumerate() {
762+
for (index, symbol) in symbols.symbols().enumerate() {
764763
let name = symbols.symbol_name(endian, symbol).unwrap();
765764
if name.is_empty() {
766765
continue;
@@ -802,7 +801,6 @@ fn print_gnu_hash<Elf: FileHeader>(
802801
if let Ok(versions) = _sections.versions(endian, data) {
803802
for (index, symbol) in symbols
804803
.symbols()
805-
.iter()
806804
.enumerate()
807805
.skip(hash_table.symbol_base() as usize)
808806
{

crates/examples/src/readobj/pe.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ 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};
67
use object::LittleEndian as LE;
78
use object::{Bytes, U32Bytes, U64Bytes};
89

@@ -643,7 +644,7 @@ fn print_relocations<'data, Coff: CoffHeader>(
643644
let index = relocation.symbol_table_index.get(LE);
644645
let name = symbols.and_then(|symbols| {
645646
symbols
646-
.symbol(index as usize)
647+
.symbol(SymbolIndex(index as usize))
647648
.and_then(|symbol| symbol.name(symbols.strings()))
648649
.print_err(p)
649650
});
@@ -714,7 +715,7 @@ fn print_symbols<'data, Coff: CoffHeader>(
714715
} else {
715716
let section_name = sections.and_then(|sections| {
716717
sections
717-
.section(section as usize)
718+
.section(SectionIndex(section as usize))
718719
.and_then(|section| section.name(symbols.strings()))
719720
.print_err(p)
720721
});

crates/examples/src/readobj/xcoff.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::*;
22
use object::read::xcoff::*;
3-
use object::read::SectionIndex;
3+
use object::read::{SectionIndex, SymbolIndex};
44
use object::xcoff::*;
55

66
pub(super) fn print_xcoff32(p: &mut Printer<'_>, data: &[u8]) {
@@ -129,7 +129,7 @@ fn print_sections<'data, Xcoff: FileHeader>(
129129
let index = relocation.r_symndx();
130130
let name = symbols.and_then(|symbols| {
131131
symbols
132-
.symbol(index as usize)
132+
.symbol(SymbolIndex(index as usize))
133133
.and_then(|symbol| symbol.name(symbols.strings()))
134134
.print_err(p)
135135
});
@@ -188,7 +188,7 @@ fn print_symbols<'data, Xcoff: FileHeader>(
188188
p.field("NumberOfAuxSymbols", numaux);
189189
if symbol.has_aux_file() {
190190
for i in 1..=numaux {
191-
if let Some(aux_file) = symbols.aux_file(index.0, i).print_err(p) {
191+
if let Some(aux_file) = symbols.aux_file(index, i).print_err(p) {
192192
p.group("FileAux", |p| {
193193
p.field("Index", index.0 + i);
194194
let name = aux_file.fname(symbols.strings());
@@ -206,7 +206,7 @@ fn print_symbols<'data, Xcoff: FileHeader>(
206206
}
207207
}
208208
if symbol.has_aux_csect() {
209-
if let Some(aux_csect) = symbols.aux_csect(index.0, numaux).print_err(p) {
209+
if let Some(aux_csect) = symbols.aux_csect(index, numaux).print_err(p) {
210210
p.group("CsectAux", |p| {
211211
p.field("Index", index.0 + numaux);
212212
p.field_hex("SectionLength", aux_csect.x_scnlen());

src/build/elf.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'data> Builder<'data> {
116116
let header = Elf::parse(data)?;
117117
let endian = header.endian()?;
118118
let is_mips64el = header.is_mips64el(endian);
119-
let shstrndx = header.shstrndx(endian, data)? as usize;
119+
let section_strings_index = header.section_strings_index(endian, data)?;
120120
let segments = header.program_headers(endian, data)?;
121121
let sections = header.sections(endian, data)?;
122122
let symbols = sections.symbols(endian, data, elf::SHT_SYMTAB)?;
@@ -179,8 +179,8 @@ impl<'data> Builder<'data> {
179179
builder.load_align = 1;
180180
}
181181

182-
for (index, section) in sections.iter().enumerate().skip(1) {
183-
let id = SectionId(index - 1);
182+
for (index, section) in sections.enumerate().skip(1) {
183+
let id = SectionId(index.0 - 1);
184184
let relocations = if let Some((rels, link)) = section.rel(endian, data)? {
185185
Self::read_relocations(
186186
index,
@@ -222,7 +222,7 @@ impl<'data> Builder<'data> {
222222
| elf::SHT_PREINIT_ARRAY => SectionData::Data(section.data(endian, data)?.into()),
223223
elf::SHT_REL | elf::SHT_RELA => relocations,
224224
elf::SHT_SYMTAB => {
225-
if index == symbols.section().0 {
225+
if index == symbols.section() {
226226
SectionData::Symbol
227227
} else {
228228
return Err(Error(format!(
@@ -232,7 +232,7 @@ impl<'data> Builder<'data> {
232232
}
233233
}
234234
elf::SHT_SYMTAB_SHNDX => {
235-
if index == symbols.shndx_section().0 {
235+
if index == symbols.shndx_section() {
236236
SectionData::SymbolSectionIndex
237237
} else {
238238
return Err(Error(format!(
@@ -242,7 +242,7 @@ impl<'data> Builder<'data> {
242242
}
243243
}
244244
elf::SHT_DYNSYM => {
245-
if index == dynamic_symbols.section().0 {
245+
if index == dynamic_symbols.section() {
246246
SectionData::DynamicSymbol
247247
} else {
248248
return Err(Error(format!(
@@ -252,11 +252,11 @@ impl<'data> Builder<'data> {
252252
}
253253
}
254254
elf::SHT_STRTAB => {
255-
if index == symbols.string_section().0 {
255+
if index == symbols.string_section() {
256256
SectionData::String
257-
} else if index == dynamic_symbols.string_section().0 {
257+
} else if index == dynamic_symbols.string_section() {
258258
SectionData::DynamicString
259-
} else if index == shstrndx {
259+
} else if index == section_strings_index {
260260
SectionData::SectionString
261261
} else {
262262
return Err(Error(format!(
@@ -372,7 +372,7 @@ impl<'data> Builder<'data> {
372372

373373
#[allow(clippy::too_many_arguments)]
374374
fn read_relocations<Elf, Rel, R>(
375-
index: usize,
375+
index: read::SectionIndex,
376376
endian: Elf::Endian,
377377
is_mips64el: bool,
378378
section: &'data Elf::SectionHeader,
@@ -427,7 +427,7 @@ impl<'data> Builder<'data> {
427427
}
428428

429429
fn read_relocations_impl<Elf, Rel, const DYNAMIC: bool>(
430-
index: usize,
430+
index: read::SectionIndex,
431431
endian: Elf::Endian,
432432
is_mips64el: bool,
433433
rels: &'data [Rel],
@@ -440,17 +440,16 @@ impl<'data> Builder<'data> {
440440
let mut relocations = Vec::new();
441441
for rel in rels {
442442
let rel = (*rel).into();
443-
let r_sym = rel.r_sym(endian, is_mips64el);
444-
let symbol = if r_sym == 0 {
445-
None
446-
} else {
447-
if r_sym as usize >= symbols_len {
443+
let symbol = if let Some(symbol) = rel.symbol(endian, is_mips64el) {
444+
if symbol.0 >= symbols_len {
448445
return Err(Error(format!(
449446
"Invalid symbol index {} in relocation section at index {}",
450-
r_sym, index,
447+
symbol, index,
451448
)));
452449
}
453-
Some(SymbolId(r_sym as usize - 1))
450+
Some(SymbolId(symbol.0 - 1))
451+
} else {
452+
None
454453
};
455454
relocations.push(Relocation {
456455
r_offset: rel.r_offset(endian).into(),
@@ -523,8 +522,8 @@ impl<'data> Builder<'data> {
523522
Elf: FileHeader<Endian = Endianness>,
524523
R: ReadRef<'data>,
525524
{
526-
for (index, symbol) in symbols.iter().enumerate().skip(1) {
527-
let id = SymbolId(index - 1);
525+
for (index, symbol) in symbols.enumerate().skip(1) {
526+
let id = SymbolId(index.0 - 1);
528527
let section =
529528
if let Some(section_index) = symbols.symbol_section(endian, symbol, index)? {
530529
let section_id = section_index.0.wrapping_sub(1);
@@ -553,7 +552,7 @@ impl<'data> Builder<'data> {
553552
}
554553

555554
fn read_attributes<Elf>(
556-
index: usize,
555+
index: read::SectionIndex,
557556
attributes: read::elf::AttributesSection<'data, Elf>,
558557
sections_len: usize,
559558
symbols_len: usize,

0 commit comments

Comments
 (0)