@@ -11,6 +11,7 @@ use std::{
11
11
use anyhow:: { anyhow, bail, Error , Result } ;
12
12
use cwdemangle:: { demangle, DemangleOptions } ;
13
13
use flagset:: FlagSet ;
14
+ use indexmap:: IndexMap ;
14
15
use itertools:: Itertools ;
15
16
use multimap:: MultiMap ;
16
17
use once_cell:: sync:: Lazy ;
@@ -128,7 +129,7 @@ pub struct MapInfo {
128
129
pub unit_references : MultiMap < SymbolRef , String > ,
129
130
pub sections : Vec < SectionInfo > ,
130
131
pub link_map_symbols : HashMap < SymbolRef , SymbolEntry > ,
131
- pub section_symbols : HashMap < String , BTreeMap < u32 , Vec < SymbolEntry > > > ,
132
+ pub section_symbols : IndexMap < String , BTreeMap < u32 , Vec < SymbolEntry > > > ,
132
133
pub section_units : HashMap < String , Vec < ( u32 , String ) > > ,
133
134
// For common BSS inflation correction
134
135
pub common_bss_start : Option < u32 > ,
@@ -723,13 +724,51 @@ where
723
724
{
724
725
let file = map_file ( & path) ?;
725
726
let info = process_map ( & mut file. as_reader ( ) , common_bss_start, mw_comment_version) ?;
726
- apply_map ( & info, obj)
727
+ apply_map ( info, obj)
727
728
}
728
729
729
- pub fn apply_map ( result : & MapInfo , obj : & mut ObjInfo ) -> Result < ( ) > {
730
+ const DEFAULT_REL_SECTIONS : & [ & str ] =
731
+ & [ ".init" , ".text" , ".ctors" , ".dtors" , ".rodata" , ".data" , ".bss" ] ;
732
+
733
+ fn normalize_section_name ( name : & str ) -> & str {
734
+ match name {
735
+ ".extabindex" => "extabindex" ,
736
+ ".extab" => "extab" ,
737
+ _ => name,
738
+ }
739
+ }
740
+
741
+ pub fn apply_map ( mut result : MapInfo , obj : & mut ObjInfo ) -> Result < ( ) > {
742
+ if result. sections . is_empty ( ) && obj. kind == ObjKind :: Executable {
743
+ log:: warn!( "Memory map section missing, attempting to recreate" ) ;
744
+ for ( section_name, symbol_map) in & result. section_symbols {
745
+ let mut address = u32:: MAX ;
746
+ let mut size = 0 ;
747
+ for symbol_entry in symbol_map. values ( ) . flatten ( ) {
748
+ if symbol_entry. address < address {
749
+ address = symbol_entry. address ;
750
+ }
751
+ if symbol_entry. address + symbol_entry. size > address + size {
752
+ size = symbol_entry. address + symbol_entry. size - address;
753
+ }
754
+ }
755
+ log:: info!( "Recreated section {} @ {:#010X} ({:#X})" , section_name, address, size) ;
756
+ result. sections . push ( SectionInfo {
757
+ name : normalize_section_name ( section_name) . to_string ( ) ,
758
+ address,
759
+ size,
760
+ file_offset : 0 ,
761
+ } ) ;
762
+ }
763
+ }
764
+
730
765
for ( section_index, section) in obj. sections . iter_mut ( ) {
731
766
let opt = if obj. kind == ObjKind :: Executable {
732
- result. sections . iter ( ) . find ( |s| s. address == section. address as u32 )
767
+ result. sections . iter ( ) . find ( |s| {
768
+ // Slightly fuzzy match for postprocess/broken maps (TP, SMG)
769
+ s. address >= section. address as u32
770
+ && ( s. address + s. size ) <= ( section. address + section. size ) as u32
771
+ } )
733
772
} else {
734
773
result. sections . iter ( ) . filter ( |s| s. size > 0 ) . nth ( section_index)
735
774
} ;
@@ -754,17 +793,61 @@ pub fn apply_map(result: &MapInfo, obj: &mut ObjInfo) -> Result<()> {
754
793
section. rename ( info. name . clone ( ) ) ?;
755
794
} else {
756
795
log:: warn!( "Section {} @ {:#010X} not found in map" , section. name, section. address) ;
796
+ if obj. kind == ObjKind :: Relocatable {
797
+ let new_name = match section. kind {
798
+ ObjSectionKind :: Code => {
799
+ if section. elf_index == 0 {
800
+ ".init"
801
+ } else {
802
+ ".text"
803
+ }
804
+ }
805
+ ObjSectionKind :: Data | ObjSectionKind :: ReadOnlyData => {
806
+ if section. elf_index == 4 {
807
+ if result
808
+ . section_symbols
809
+ . get ( ".rodata" )
810
+ . map_or ( false , |m| !m. is_empty ( ) )
811
+ {
812
+ ".rodata"
813
+ } else {
814
+ ".data"
815
+ }
816
+ } else if let Some ( section_name) =
817
+ DEFAULT_REL_SECTIONS . get ( section. elf_index )
818
+ {
819
+ section_name
820
+ } else {
821
+ ".data"
822
+ }
823
+ }
824
+ ObjSectionKind :: Bss => ".bss" ,
825
+ } ;
826
+ log:: warn!( "Defaulting to {}" , new_name) ;
827
+ section. rename ( new_name. to_string ( ) ) ?;
828
+ }
757
829
}
758
830
}
759
831
832
+ // If every symbol the map has alignment 4, it's likely bogus
833
+ let bogus_alignment =
834
+ result. section_symbols . values ( ) . flatten ( ) . flat_map ( |( _, m) | m) . all ( |s| s. align == Some ( 4 ) ) ;
835
+ if bogus_alignment {
836
+ log:: warn!( "Bogus alignment detected, ignoring" ) ;
837
+ }
838
+
760
839
// Add section symbols
761
840
for ( section_name, symbol_map) in & result. section_symbols {
841
+ if section_name == ".dead" {
842
+ continue ;
843
+ }
844
+ let section_name = normalize_section_name ( section_name) ;
762
845
let ( section_index, _) = obj
763
846
. sections
764
847
. by_name ( section_name) ?
765
848
. ok_or_else ( || anyhow ! ( "Failed to locate section {section_name} from map" ) ) ?;
766
849
for symbol_entry in symbol_map. values ( ) . flatten ( ) {
767
- add_symbol ( obj, symbol_entry, Some ( section_index) ) ?;
850
+ add_symbol ( obj, symbol_entry, Some ( section_index) , bogus_alignment ) ?;
768
851
}
769
852
}
770
853
@@ -776,6 +859,10 @@ pub fn apply_map(result: &MapInfo, obj: &mut ObjInfo) -> Result<()> {
776
859
777
860
// Add splits
778
861
for ( section_name, unit_order) in & result. section_units {
862
+ if section_name == ".dead" {
863
+ continue ;
864
+ }
865
+ let section_name = normalize_section_name ( section_name) ;
779
866
let ( _, section) = obj
780
867
. sections
781
868
. iter_mut ( )
@@ -865,14 +952,21 @@ pub fn create_obj(result: &MapInfo) -> Result<ObjInfo> {
865
952
unresolved_relocations : vec ! [ ] ,
866
953
} ;
867
954
955
+ // If every symbol the map has alignment 4, it's likely bogus
956
+ let bogus_alignment =
957
+ result. section_symbols . values ( ) . flatten ( ) . flat_map ( |( _, m) | m) . all ( |s| s. align == Some ( 4 ) ) ;
958
+ if bogus_alignment {
959
+ log:: warn!( "Bogus alignment detected, ignoring" ) ;
960
+ }
961
+
868
962
// Add section symbols
869
963
for ( section_name, symbol_map) in & result. section_symbols {
870
964
let ( section_index, _) = obj
871
965
. sections
872
966
. by_name ( section_name) ?
873
967
. ok_or_else ( || anyhow ! ( "Failed to locate section {section_name} from map" ) ) ?;
874
968
for symbol_entry in symbol_map. values ( ) . flatten ( ) {
875
- add_symbol ( & mut obj, symbol_entry, Some ( section_index) ) ?;
969
+ add_symbol ( & mut obj, symbol_entry, Some ( section_index) , bogus_alignment ) ?;
876
970
}
877
971
}
878
972
@@ -917,7 +1011,12 @@ pub fn create_obj(result: &MapInfo) -> Result<ObjInfo> {
917
1011
Ok ( obj)
918
1012
}
919
1013
920
- fn add_symbol ( obj : & mut ObjInfo , symbol_entry : & SymbolEntry , section : Option < usize > ) -> Result < ( ) > {
1014
+ fn add_symbol (
1015
+ obj : & mut ObjInfo ,
1016
+ symbol_entry : & SymbolEntry ,
1017
+ section : Option < usize > ,
1018
+ ignore_alignment : bool ,
1019
+ ) -> Result < ( ) > {
921
1020
let demangled_name = demangle ( & symbol_entry. name , & DemangleOptions :: default ( ) ) ;
922
1021
let mut flags: FlagSet < ObjSymbolFlags > = match symbol_entry. visibility {
923
1022
SymbolVisibility :: Unknown => Default :: default ( ) ,
@@ -947,7 +1046,7 @@ fn add_symbol(obj: &mut ObjInfo, symbol_entry: &SymbolEntry, section: Option<usi
947
1046
SymbolKind :: Section => ObjSymbolKind :: Section ,
948
1047
SymbolKind :: NoType => ObjSymbolKind :: Unknown ,
949
1048
} ,
950
- align : symbol_entry. align ,
1049
+ align : if ignore_alignment { None } else { symbol_entry. align } ,
951
1050
..Default :: default ( )
952
1051
} ,
953
1052
true ,
0 commit comments