@@ -20,7 +20,6 @@ mod types;
2020
2121use std:: collections:: HashMap ;
2222use std:: path:: PathBuf ;
23- use std:: str:: FromStr ;
2423
2524use crate :: dwarfdebuginfo:: { DebugInfoBuilder , DebugInfoBuilderContext } ;
2625use crate :: functions:: parse_function_entry;
@@ -499,44 +498,6 @@ where
499498 }
500499}
501500
502- fn get_supplementary_build_id ( bv : & BinaryView ) -> Option < String > {
503- let raw_view = bv. raw_view ( ) ?;
504- if let Some ( section) = raw_view. section_by_name ( ".gnu_debugaltlink" ) {
505- let start = section. start ( ) ;
506- let len = section. len ( ) ;
507-
508- if len < 20 {
509- // Not large enough to hold a build id
510- return None ;
511- }
512-
513- raw_view
514- . read_vec ( start, len)
515- . splitn ( 2 , |x| * x == 0 )
516- . last ( )
517- . map ( |a| a. iter ( ) . map ( |b| format ! ( "{:02x}" , b) ) . collect ( ) )
518- } else {
519- None
520- }
521- }
522-
523- fn get_supplementary_file_path ( bv : & BinaryView ) -> Option < PathBuf > {
524- let raw_view = bv. raw_view ( ) ?;
525- if let Some ( section) = raw_view. section_by_name ( ".gnu_debugaltlink" ) {
526- let start = section. start ( ) ;
527- let len = section. len ( ) ;
528-
529- raw_view
530- . read_vec ( start, len)
531- . splitn ( 2 , |x| * x == 0 )
532- . next ( )
533- . and_then ( |a| String :: from_utf8 ( a. to_vec ( ) ) . ok ( ) )
534- . and_then ( |p| PathBuf :: from_str ( & p) . ok ( ) )
535- } else {
536- None
537- }
538- }
539-
540501fn parse_range_data_offsets ( file : & object:: File ) -> Result < IntervalMap < u64 , i64 > , String > {
541502 let dwo_file = file. section_by_name ( ".debug_info.dwo" ) . is_some ( ) ;
542503 let endian = match file. endianness ( ) {
@@ -697,7 +658,7 @@ impl CustomDebugInfoParser for DWARFParser {
697658 return true ;
698659 }
699660 if dwarfreader:: has_build_id_section ( view) {
700- if let Ok ( build_id) = get_build_id ( view) {
661+ if let Ok ( Some ( build_id) ) = get_build_id ( view) {
701662 if helpers:: find_local_debug_file_for_build_id ( & build_id, view) . is_some ( ) {
702663 return true ;
703664 }
@@ -713,30 +674,46 @@ impl CustomDebugInfoParser for DWARFParser {
713674 & self ,
714675 debug_info : & mut DebugInfo ,
715676 bv : & BinaryView ,
716- debug_file : & BinaryView ,
677+ debug_bv : & BinaryView ,
717678 progress : Box < dyn Fn ( usize , usize ) -> Result < ( ) , ( ) > > ,
718679 ) -> bool {
719- let ( external_file, close_external) = if !dwarfreader:: is_valid ( bv) {
720- if let ( Some ( debug_view) , x) = helpers:: load_sibling_debug_file ( bv) {
721- ( Some ( debug_view) , x)
722- } else if let Ok ( build_id) = get_build_id ( bv) {
723- load_debug_info_for_build_id ( & build_id, bv)
724- } else {
725- ( None , false )
726- }
727- } else {
728- ( None , false )
729- } ;
730-
731- let debug_bv = external_file. as_deref ( ) . unwrap_or ( debug_file) ;
732-
733- // Read the raw view to an object::File so relocations get handled for us
734- let Some ( raw_view) = debug_bv. raw_view ( ) else {
735- log:: error!( "Failed to get raw view for debug bv" ) ;
680+ let Some ( debug_data_vec) = dwarfreader:: is_valid ( debug_bv)
681+ . then ( || {
682+ // Load the raw view of the debug bv passed in if it has valid debug info
683+ let raw_view = debug_bv. raw_view ( ) . expect ( "Failed to get raw view" ) ;
684+ raw_view. read_vec ( 0 , raw_view. len ( ) as usize )
685+ } )
686+ . or_else ( || {
687+ // Try loading sibling debug files
688+ match helpers:: load_sibling_debug_file ( bv) {
689+ Ok ( x) => x,
690+ Err ( e) => {
691+ log:: error!( "Failed loading sibling debug file: {}" , e) ;
692+ None
693+ }
694+ }
695+ } )
696+ . or_else ( || {
697+ // Try loading from the file's build id
698+ if let Ok ( Some ( build_id) ) = get_build_id ( bv) {
699+ match load_debug_info_for_build_id ( & build_id, bv) {
700+ Ok ( x) => x,
701+ Err ( e) => {
702+ log:: error!( "Failed loading debug info from build id: {}" , e) ;
703+ None
704+ }
705+ }
706+ } else {
707+ // No build id found
708+ None
709+ }
710+ } )
711+ else {
712+ // There isn't any dwarf info available to load
736713 return false ;
737714 } ;
738- let raw_view_data = raw_view . read_vec ( 0 , raw_view . len ( ) as usize ) ;
739- let debug_file = match object:: File :: parse ( & * raw_view_data ) {
715+
716+ let debug_file = match object:: File :: parse ( debug_data_vec . as_slice ( ) ) {
740717 Ok ( x) => x,
741718 Err ( e) => {
742719 log:: error!( "Failed to parse bv: {}" , e) ;
@@ -746,31 +723,35 @@ impl CustomDebugInfoParser for DWARFParser {
746723
747724 // TODO: allow passing a supplementary file path as a setting?
748725 // Try to load supplementary file from build id, falling back to file path
749- let sup_view_data = get_supplementary_build_id ( debug_bv)
750- . and_then ( |build_id| {
751- load_debug_info_for_build_id ( & build_id, bv)
752- . 0
753- . map ( |x| x. raw_view ( ) . expect ( "Failed to get raw view" ) )
754- } )
755- . or_else ( || {
756- get_supplementary_file_path ( debug_bv) . and_then ( |sup_file_path_suggestion| {
757- find_local_debug_file_from_path ( & sup_file_path_suggestion, debug_bv) . and_then (
758- |sup_file_path| {
759- binaryninja:: load_with_options (
760- sup_file_path,
761- false ,
762- Some ( "{\" analysis.debugInfo.internal\" : false}" ) ,
763- )
726+ let sup_view_data = debug_file. gnu_debugaltlink ( ) . ok ( ) . flatten ( ) . and_then (
727+ |( sup_filename, sup_build_id) | {
728+ // Try loading from build id
729+ let sup_data = match load_debug_info_for_build_id ( sup_build_id, bv) {
730+ Ok ( x) => x,
731+ Err ( e) => {
732+ log:: error!( "Failed to load supplementary debug file: {}" , e) ;
733+ None
734+ }
735+ } ;
736+
737+ // Try loading from file path if build id loading didn't work
738+ sup_data. or_else ( || match std:: str:: from_utf8 ( sup_filename) {
739+ Ok ( x) => find_local_debug_file_from_path ( & PathBuf :: from ( x) , bv) . and_then (
740+ |sup_file_path| match std:: fs:: read ( sup_file_path) {
741+ Ok ( sup_data) => Some ( sup_data) ,
742+ Err ( e) => {
743+ log:: error!( "Failed reading supplementary file {}: {}" , x, e) ;
744+ None
745+ }
764746 } ,
765- )
747+ ) ,
748+ Err ( e) => {
749+ log:: error!( "Supplementary file path is invalid utf8: {}" , e) ;
750+ None
751+ }
766752 } )
767- } )
768- . and_then ( |sup_bv| {
769- let sup_raw_view = sup_bv. raw_view ( ) ?;
770- let sup_raw_data = sup_raw_view. read_vec ( 0 , sup_raw_view. len ( ) as usize ) ;
771- sup_raw_view. file ( ) . close ( ) ;
772- Some ( sup_raw_data)
773- } ) ;
753+ } ,
754+ ) ;
774755
775756 let sup_file =
776757 sup_view_data
@@ -815,10 +796,6 @@ impl CustomDebugInfoParser for DWARFParser {
815796 }
816797 } ;
817798
818- if let ( Some ( ext) , true ) = ( external_file, close_external) {
819- ext. file ( ) . close ( ) ;
820- }
821-
822799 result
823800 }
824801}
0 commit comments