@@ -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 < ( ) >
516581where
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