Skip to content

Commit b7dbd7c

Browse files
committed
dwarfdump: add --sup option
This allows strings in supplementary object files to be displayed.
1 parent 5bc1f4b commit b7dbd7c

File tree

1 file changed

+84
-28
lines changed

1 file changed

+84
-28
lines changed

examples/dwarfdump.rs

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ fn main() {
403403
"print compilation units whose output matches a regex",
404404
"REGEX",
405405
);
406+
opts.optopt("", "sup", "path to supplementary object file", "PATH");
406407

407408
let matches = match opts.parse(env::args().skip(1)) {
408409
Ok(m) => m,
@@ -471,6 +472,33 @@ fn main() {
471472
None
472473
};
473474

475+
let sup_mmap;
476+
let sup_file = if let Some(sup_path) = matches.opt_str("sup") {
477+
let file = match fs::File::open(&sup_path) {
478+
Ok(file) => file,
479+
Err(err) => {
480+
println!("Failed to open file '{}': {}", sup_path, err);
481+
process::exit(1);
482+
}
483+
};
484+
sup_mmap = match unsafe { memmap::Mmap::map(&file) } {
485+
Ok(mmap) => mmap,
486+
Err(err) => {
487+
println!("Failed to map file '{}': {}", sup_path, err);
488+
process::exit(1);
489+
}
490+
};
491+
match object::File::parse(&*sup_mmap) {
492+
Ok(file) => Some(file),
493+
Err(err) => {
494+
println!("Failed to parse file '{}': {}", sup_path, err);
495+
process::exit(1);
496+
}
497+
}
498+
} else {
499+
None
500+
};
501+
474502
for file_path in &matches.free {
475503
if matches.free.len() != 1 {
476504
println!("{}", file_path);
@@ -504,53 +532,77 @@ fn main() {
504532
} else {
505533
gimli::RunTimeEndian::Big
506534
};
507-
let ret = dump_file(&file, endian, &flags);
535+
let ret = dump_file(&file, sup_file.as_ref(), endian, &flags);
508536
match ret {
509537
Ok(_) => (),
510538
Err(err) => println!("Failed to dump '{}': {}", file_path, err,),
511539
}
512540
}
513541
}
514542

515-
fn dump_file<Endian>(file: &object::File, endian: Endian, flags: &Flags) -> Result<()>
543+
fn load_file_section<'input, 'arena, Endian: gimli::Endianity>(
544+
id: gimli::SectionId,
545+
file: &object::File<'input>,
546+
endian: Endian,
547+
flags: &Flags,
548+
arena_data: &'arena Arena<Cow<'input, [u8]>>,
549+
arena_relocations: &'arena Arena<RelocationMap>,
550+
) -> Result<Relocate<'arena, gimli::EndianSlice<'arena, Endian>>> {
551+
let mut relocations = RelocationMap::default();
552+
let name = flags.section_name(id);
553+
let data = match name.and_then(|name| file.section_by_name(&name)) {
554+
Some(ref section) => {
555+
// DWO sections never have relocations, so don't bother.
556+
if !flags.dwo {
557+
add_relocations(&mut relocations, file, section);
558+
}
559+
section.uncompressed_data()?
560+
}
561+
// Use a non-zero capacity so that `ReaderOffsetId`s are unique.
562+
None => Cow::Owned(Vec::with_capacity(1)),
563+
};
564+
let data_ref = (*arena_data.alloc(data)).borrow();
565+
let reader = gimli::EndianSlice::new(data_ref, endian);
566+
let section = reader;
567+
let relocations = (*arena_relocations.alloc(relocations)).borrow();
568+
Ok(Relocate {
569+
relocations,
570+
section,
571+
reader,
572+
})
573+
}
574+
575+
fn dump_file<Endian>(
576+
file: &object::File,
577+
sup_file: Option<&object::File>,
578+
endian: Endian,
579+
flags: &Flags,
580+
) -> Result<()>
516581
where
517582
Endian: gimli::Endianity + Send + Sync,
518583
{
519-
let arena = (Arena::new(), Arena::new());
584+
let arena_data = Arena::new();
585+
let arena_relocations = Arena::new();
520586

521587
let mut load_section = |id: gimli::SectionId| -> Result<_> {
522-
let mut relocations = RelocationMap::default();
523-
let name = flags.section_name(id);
524-
let data = match name.and_then(|name| file.section_by_name(&name)) {
525-
Some(ref section) => {
526-
// DWO sections never have relocations, so don't bother.
527-
if !flags.dwo {
528-
add_relocations(&mut relocations, file, section);
529-
}
530-
section.uncompressed_data()?
531-
}
532-
// Use a non-zero capacity so that `ReaderOffsetId`s are unique.
533-
None => Cow::Owned(Vec::with_capacity(1)),
534-
};
535-
let data_ref = (*arena.0.alloc(data)).borrow();
536-
let reader = gimli::EndianSlice::new(data_ref, endian);
537-
let section = reader;
538-
let relocations = (*arena.1.alloc(relocations)).borrow();
539-
Ok(Relocate {
540-
relocations,
541-
section,
542-
reader,
543-
})
588+
load_file_section(id, file, endian, flags, &arena_data, &arena_relocations)
544589
};
545590

546-
let no_relocations = (*arena.1.alloc(RelocationMap::default())).borrow();
591+
let no_relocations = (*arena_relocations.alloc(RelocationMap::default())).borrow();
547592
let no_reader = Relocate {
548593
relocations: no_relocations,
549594
section: Default::default(),
550595
reader: Default::default(),
551596
};
597+
let mut load_sup_section = |id: gimli::SectionId| -> Result<_> {
598+
sup_file
599+
.map(|sup_file| {
600+
load_file_section(id, sup_file, endian, flags, &arena_data, &arena_relocations)
601+
})
602+
.unwrap_or_else(|| Ok(no_reader.clone()))
603+
};
552604

553-
let mut dwarf = gimli::Dwarf::load(&mut load_section, |_| Ok(no_reader.clone())).unwrap();
605+
let mut dwarf = gimli::Dwarf::load(&mut load_section, &mut load_sup_section).unwrap();
554606
if flags.dwo {
555607
dwarf.file_type = gimli::DwarfFileType::Dwo;
556608
}
@@ -1252,7 +1304,11 @@ fn dump_attr_value<R: Reader, W: Write>(
12521304
}
12531305
}
12541306
gimli::AttributeValue::DebugStrRefSup(offset) => {
1255-
writeln!(w, "<.debug_str(sup)+0x{:08x}>", offset.0)?;
1307+
if let Ok(s) = dwarf.debug_str_sup.get_str(offset) {
1308+
writeln!(w, "{}", s.to_string_lossy()?)?;
1309+
} else {
1310+
writeln!(w, "<.debug_str(sup)+0x{:08x}>", offset.0)?;
1311+
}
12561312
}
12571313
gimli::AttributeValue::DebugStrOffsetsBase(base) => {
12581314
writeln!(w, "<.debug_str_offsets+0x{:08x}>", base.0)?;

0 commit comments

Comments
 (0)