@@ -47,6 +47,7 @@ use binaryninja::logger::Logger;
4747use helpers:: { get_build_id, load_debug_info_for_build_id} ;
4848use iset:: IntervalMap ;
4949use log:: { debug, error, warn} ;
50+ use object:: read:: macho:: FatArch ;
5051use object:: { Object , ObjectSection } ;
5152
5253trait ReaderType : Reader < Offset = usize > { }
@@ -650,6 +651,60 @@ fn parse_dwarf(
650651 Ok ( debug_info_builder)
651652}
652653
654+ fn parse_data_to_object < ' a > (
655+ data : & ' a [ u8 ] ,
656+ target_bv : & BinaryView ,
657+ ) -> Result < object:: File < ' a > , String > {
658+ // Try to parse as normal file, fall back to parsing as fat macho and selecting the right arch from the target bv
659+ if let Ok ( o) = object:: File :: parse ( data) {
660+ return Ok ( o) ;
661+ }
662+
663+ if let Some ( bv_arch) = target_bv. default_arch ( ) {
664+ let target_obj_arch = match bv_arch. name ( ) . as_str ( ) {
665+ "x86" => object:: Architecture :: I386 ,
666+ "x86_64" => object:: Architecture :: X86_64 ,
667+ "aarch64" => object:: Architecture :: Aarch64 ,
668+ "armv7" | "thumb2" => object:: Architecture :: Arm ,
669+ "mips32" => object:: Architecture :: Mips ,
670+ "mips64" => object:: Architecture :: Mips64 ,
671+ "ppc" => object:: Architecture :: PowerPc ,
672+ "ppc64" => object:: Architecture :: PowerPc64 ,
673+ _ => {
674+ return Err ( format ! (
675+ "Unable to determine architecture to load from \" {}\" " ,
676+ bv_arch. name( )
677+ ) ) ;
678+ }
679+ } ;
680+ if let Ok ( o) = object:: read:: macho:: MachOFatFile32 :: parse ( data) {
681+ for arch in o. arches ( ) {
682+ if arch. architecture ( ) == target_obj_arch {
683+ let arch_data = arch
684+ . data ( data)
685+ . map_err ( |e| format ! ( "Failed to read FatArch32: {}" , e) ) ?;
686+ return object:: File :: parse ( arch_data)
687+ . map_err ( |e| format ! ( "Failed to parse object from FatArch32 data: {}" , e) ) ;
688+ }
689+ }
690+ }
691+
692+ if let Ok ( o) = object:: read:: macho:: MachOFatFile64 :: parse ( data) {
693+ for arch in o. arches ( ) {
694+ if arch. architecture ( ) == target_obj_arch {
695+ let arch_data = arch
696+ . data ( data)
697+ . map_err ( |e| format ! ( "Failed to read FatArch64: {}" , e) ) ?;
698+ return object:: File :: parse ( arch_data)
699+ . map_err ( |e| format ! ( "Failed to parse object from FatArch64 data: {}" , e) ) ;
700+ }
701+ }
702+ }
703+ }
704+
705+ Err ( "Unable to load object from data" . to_string ( ) )
706+ }
707+
653708struct DWARFParser ;
654709
655710impl CustomDebugInfoParser for DWARFParser {
@@ -713,10 +768,10 @@ impl CustomDebugInfoParser for DWARFParser {
713768 return false ;
714769 } ;
715770
716- let debug_file = match object :: File :: parse ( debug_data_vec. as_slice ( ) ) {
771+ let debug_file = match parse_data_to_object ( debug_data_vec. as_slice ( ) , bv ) {
717772 Ok ( x) => x,
718773 Err ( e) => {
719- log:: error!( "Failed to parse bv : {}" , e) ;
774+ log:: error!( "Failed to parse debug data : {}" , e) ;
720775 return false ;
721776 }
722777 } ;
@@ -753,16 +808,15 @@ impl CustomDebugInfoParser for DWARFParser {
753808 } ,
754809 ) ;
755810
756- let sup_file =
757- sup_view_data
758- . as_ref ( )
759- . and_then ( |data| match object:: File :: parse ( data. as_slice ( ) ) {
760- Ok ( x) => Some ( x) ,
761- Err ( e) => {
762- log:: error!( "Failed to parse supplementary bv: {}" , e) ;
763- None
764- }
765- } ) ;
811+ let sup_file = sup_view_data. as_ref ( ) . and_then ( |data| {
812+ match parse_data_to_object ( data. as_slice ( ) , bv) {
813+ Ok ( x) => Some ( x) ,
814+ Err ( e) => {
815+ log:: error!( "Failed to parse supplementary debug data: {}" , e) ;
816+ None
817+ }
818+ }
819+ } ) ;
766820
767821 // If we have a sup file, verify its build id with the expected build id, else warn
768822 if let Some ( sup_file) = & sup_file {
0 commit comments