Import Upstream version 0.99.7
Mathieu Malaterre
3 years ago
5 | 5 | RELEASE INFORMATION |
6 | 6 | |
7 | 7 | Project: ABI Dumper |
8 | Version: 0.99.6 | |
9 | Date: 2013-09-16 | |
8 | Version: 0.99.7 | |
9 | Date: 2013-10-25 | |
10 | 10 | |
11 | 11 | |
12 | 12 | This file explains how to install and setup environment |
0 | 0 | #!/usr/bin/perl |
1 | 1 | ########################################################################### |
2 | # ABI Dumper 0.99.6 | |
2 | # ABI Dumper 0.99.7 | |
3 | 3 | # Dump ABI of an ELF object containing DWARF debug info |
4 | 4 | # |
5 | 5 | # Copyright (C) 2013 ROSA Laboratory |
42 | 42 | use Storable qw(dclone); |
43 | 43 | use Data::Dumper; |
44 | 44 | |
45 | my $TOOL_VERSION = "0.99.6"; | |
45 | my $TOOL_VERSION = "0.99.7"; | |
46 | 46 | my $ABI_DUMP_VERSION = "3.2"; |
47 | 47 | my $ORIG_DIR = cwd(); |
48 | 48 | my $TMP_DIR = tempdir(CLEANUP=>1); |
243 | 243 | |
244 | 244 | my $STDCXX_TARGET = 0; |
245 | 245 | my $GLOBAL_ID = 0; |
246 | my %ANON_TYPE = (); | |
246 | 247 | |
247 | 248 | my %Mangled_ID; |
248 | 249 | my %Checked_Spec; |
270 | 271 | "Const"=>"const" |
271 | 272 | ); |
272 | 273 | |
273 | my $HEADER_EXT = "h|hh|hp|hxx|hpp|h\\+\\+"; | |
274 | my $HEADER_EXT = "h|hh|hp|hxx|hpp|h\\+\\+|tcc"; | |
274 | 275 | my $SRC_EXT = "c|cpp|cxx|c\\+\\+"; |
275 | 276 | |
276 | 277 | # Other |
892 | 893 | if(defined $DWARF_Info{$ID}{"decl_file"}) |
893 | 894 | { |
894 | 895 | my $File = $DWARF_Info{$ID}{"decl_file"}; |
895 | my $Unit = $DWARF_Info{$ID}{"CompUnit"}; | |
896 | my $Unit = $DWARF_Info{$ID}{"Unit"}; | |
896 | 897 | |
897 | 898 | my $Name = undef; |
898 | 899 | |
966 | 967 | "encoding" => 1 |
967 | 968 | ); |
968 | 969 | |
970 | my %MarkByUnit = ( | |
971 | "member" => 1, | |
972 | "subprogram" => 1, | |
973 | "variable" => 1 | |
974 | ); | |
975 | ||
969 | 976 | my %Excess_IDs; |
970 | my %Delete_IDs; | |
971 | 977 | my %Delete_Src; |
972 | 978 | |
973 | 979 | my $Lexical_Block = undef; |
980 | my $Inlined_Block = undef; | |
974 | 981 | my $Subprogram_Block = undef; |
982 | my $Skip_Block = undef; | |
975 | 983 | |
976 | 984 | while(($Import and $Line = $ImportedUnit{$Import}{$Import_Num}) or $Line = <$FH>) |
977 | 985 | { |
987 | 995 | } |
988 | 996 | if($ID and $Line=~/\A\s*(\w+)\s*(.+?)\s*\Z/) |
989 | 997 | { |
998 | ||
999 | if(defined $Skip_Block) { | |
1000 | next; | |
1001 | } | |
1002 | ||
990 | 1003 | my ($Attr, $Val) = ($1, $2); |
991 | 1004 | |
992 | 1005 | if($Kind eq "member" |
1010 | 1023 | $UsedUnit{$Import} = 1; |
1011 | 1024 | } |
1012 | 1025 | } |
1026 | } | |
1027 | } | |
1028 | ||
1029 | if($Kind eq "member") | |
1030 | { | |
1031 | if($Attr eq "data_member_location") | |
1032 | { | |
1033 | delete($DWARF_Info{$ID}{"Unit"}); | |
1013 | 1034 | } |
1014 | 1035 | } |
1015 | 1036 | |
1173 | 1194 | $NS = length($2); |
1174 | 1195 | $Kind = $3; |
1175 | 1196 | |
1197 | $Skip_Block = undef; | |
1198 | ||
1199 | if(defined $SkipNode{$Kind}) | |
1200 | { | |
1201 | $Skip_Block = 1; | |
1202 | next; | |
1203 | } | |
1204 | ||
1205 | if($Kind eq "lexical_block") | |
1206 | { | |
1207 | $Lexical_Block = $NS; | |
1208 | $Skip_Block = 1; | |
1209 | next; | |
1210 | } | |
1211 | else | |
1212 | { | |
1213 | if(defined $Lexical_Block) | |
1214 | { | |
1215 | if($NS>$Lexical_Block) | |
1216 | { | |
1217 | $Skip_Block = 1; | |
1218 | next; | |
1219 | } | |
1220 | else | |
1221 | { # end of lexical block | |
1222 | $Lexical_Block = undef; | |
1223 | } | |
1224 | } | |
1225 | } | |
1226 | ||
1227 | if($Kind eq "inlined_subroutine") | |
1228 | { | |
1229 | $Inlined_Block = $NS; | |
1230 | $Skip_Block = 1; | |
1231 | next; | |
1232 | } | |
1233 | else | |
1234 | { | |
1235 | if(defined $Inlined_Block) | |
1236 | { | |
1237 | if($NS>$Inlined_Block) | |
1238 | { | |
1239 | $Skip_Block = 1; | |
1240 | next; | |
1241 | } | |
1242 | else | |
1243 | { # end of inlined subroutine | |
1244 | $Inlined_Block = undef; | |
1245 | } | |
1246 | } | |
1247 | } | |
1248 | ||
1249 | if($Kind eq "subprogram") | |
1250 | { | |
1251 | $Subprogram_Block = $NS; | |
1252 | } | |
1253 | else | |
1254 | { | |
1255 | if(defined $Subprogram_Block) | |
1256 | { | |
1257 | if($NS>$Subprogram_Block) | |
1258 | { | |
1259 | if($Kind eq "variable") | |
1260 | { # temp variables | |
1261 | $Skip_Block = 1; | |
1262 | next; | |
1263 | } | |
1264 | } | |
1265 | else | |
1266 | { # end of subprogram block | |
1267 | $Subprogram_Block = undef; | |
1268 | } | |
1269 | } | |
1270 | } | |
1271 | ||
1176 | 1272 | if($Import or not $Primary) |
1177 | 1273 | { |
1178 | 1274 | $ID = -$ID; |
1211 | 1307 | } |
1212 | 1308 | } |
1213 | 1309 | |
1214 | if($Kind eq "lexical_block") | |
1215 | { | |
1216 | $Lexical_Block = $NS; | |
1217 | $Delete_IDs{$ID} = 1; | |
1218 | } | |
1219 | else | |
1220 | { | |
1221 | if(defined $Lexical_Block) | |
1222 | { | |
1223 | if($NS>$Lexical_Block) | |
1224 | { | |
1225 | $Delete_IDs{$ID} = 1; | |
1226 | } | |
1227 | else | |
1228 | { # end of lexical block | |
1229 | $Lexical_Block = undef; | |
1230 | } | |
1231 | } | |
1232 | } | |
1233 | ||
1234 | if($Kind eq "subprogram") | |
1235 | { | |
1236 | $Subprogram_Block = $NS; | |
1237 | } | |
1238 | else | |
1239 | { | |
1240 | if(defined $Subprogram_Block) | |
1241 | { | |
1242 | if($NS>$Subprogram_Block) | |
1243 | { | |
1244 | if($Kind eq "variable") | |
1245 | { # temp variables | |
1246 | $Delete_IDs{$ID} = 1; | |
1247 | } | |
1248 | } | |
1249 | else | |
1250 | { # end of subprogram block | |
1251 | $Subprogram_Block = undef; | |
1252 | } | |
1253 | } | |
1254 | } | |
1255 | ||
1256 | 1310 | if(defined $ID_Pre) |
1257 | 1311 | { |
1258 | 1312 | my $Kind_Pre = $DWARF_Info{$ID_Pre}{"Kind"}; |
1259 | ||
1260 | if(defined $SkipNode{$Kind_Pre}) { | |
1261 | $Delete_IDs{$ID_Pre} = 1; | |
1262 | } | |
1263 | 1313 | |
1264 | 1314 | if(my $Sp = $DWARF_Info{$ID_Pre}{"specification"}) |
1265 | 1315 | { |
1302 | 1352 | { |
1303 | 1353 | delete($Excess_IDs{$Orig}); |
1304 | 1354 | } |
1305 | ||
1306 | 1355 | } |
1307 | 1356 | } |
1308 | 1357 | elsif($NS==4) |
1345 | 1394 | |
1346 | 1395 | $ID_Pre = $ID; |
1347 | 1396 | |
1348 | if(defined $CUnit) { | |
1349 | $DWARF_Info{$ID}{"CompUnit"} = $CUnit; | |
1397 | if(defined $CUnit) | |
1398 | { | |
1399 | if(defined $MarkByUnit{$Kind} | |
1400 | or defined $TypeType{$Kind}) { | |
1401 | $DWARF_Info{$ID}{"Unit"} = $CUnit; | |
1402 | } | |
1350 | 1403 | } |
1351 | 1404 | |
1352 | 1405 | if(not defined $ID_Shift) { |
1458 | 1511 | %ImportedDecl = (); |
1459 | 1512 | %UsedUnit = (); |
1460 | 1513 | %UsedDecl = (); |
1461 | ||
1462 | foreach my $ID (keys(%Delete_IDs)) | |
1463 | { | |
1464 | delete($DWARF_Info{$ID}); | |
1465 | } | |
1466 | ||
1467 | %Delete_IDs = (); | |
1468 | 1514 | |
1469 | 1515 | foreach my $ID (keys(%Delete_Src)) |
1470 | 1516 | { |
1653 | 1699 | sub read_ABI() |
1654 | 1700 | { |
1655 | 1701 | printMsg("INFO", "Extracting ABI information"); |
1656 | ||
1702 | ||
1657 | 1703 | my %CurID = (); |
1658 | 1704 | |
1659 | 1705 | my @IDs = sort {int($a) <=> int($b)} keys(%DWARF_Info); |
1679 | 1725 | } |
1680 | 1726 | } |
1681 | 1727 | |
1728 | if($Kind ne "subprogram") { | |
1729 | delete($DWARF_Info{$ID}{"NS"}); | |
1730 | } | |
1731 | ||
1682 | 1732 | my $IsType = ($Kind=~/(struct|structure|class|union|enumeration|subroutine|array)_type/); |
1683 | 1733 | |
1684 | 1734 | if($IsType |
1685 | 1735 | or $Kind eq "typedef" |
1686 | 1736 | or $Kind eq "subprogram" |
1687 | or $Kind eq "inlined_subroutine" | |
1688 | or $Kind eq "lexical_block" | |
1689 | 1737 | or $Kind eq "variable" |
1690 | 1738 | or $Kind eq "namespace") |
1691 | 1739 | { |
1969 | 2017 | } |
1970 | 2018 | |
1971 | 2019 | # free memory |
2020 | # delete types info | |
1972 | 2021 | %Delete = (); |
1973 | 2022 | foreach (keys(%DWARF_Info)) |
1974 | 2023 | { |
2114 | 2163 | |
2115 | 2164 | delete($SymbolInfo{$ID}{"External"}); |
2116 | 2165 | } |
2117 | ||
2118 | #use Devel::Size qw(size total_size); | |
2119 | #print keys(%DWARF_Info)." ".(total_size(\%DWARF_Info)/(1024*1024))." Mb ".localtime(time)."\n"; | |
2120 | #print keys(%TypeInfo)." ".(total_size(\%TypeInfo)/(1024*1024))." Mb ".localtime(time)."\n"; | |
2121 | #print keys(%SymbolInfo)." ".(total_size(\%SymbolInfo)/(1024*1024))." Mb ".localtime(time)."\n"; | |
2122 | ||
2123 | #writeFile("out.txt", Dumper(\%DWARF_Info)); | |
2124 | 2166 | } |
2125 | 2167 | |
2126 | 2168 | sub cloneSymbol($$) |
2809 | 2851 | elsif($TInfo{"Source"}) { |
2810 | 2852 | $TInfo{"Name"} = "anon-".lc($TInfo{"Type"})."-".$TInfo{"Source"}."-".$TInfo{"SourceLine"}; |
2811 | 2853 | } |
2854 | else | |
2855 | { | |
2856 | if(not defined $TypeMember{$ID}) | |
2857 | { | |
2858 | if(not defined $ANON_TYPE{$TInfo{"Type"}}) | |
2859 | { | |
2860 | printMsg("WARNING", "a \"".$TInfo{"Type"}."\" type with no attributes detected in the DWARF dump ($ID)"); | |
2861 | $ANON_TYPE{$TInfo{"Type"}} = 1; | |
2862 | } | |
2863 | $TInfo{"Name"} = "anon-".lc($TInfo{"Type"}); | |
2864 | } | |
2865 | } | |
2812 | 2866 | |
2813 | 2867 | if($TInfo{"Name"} and $TInfo{"NameSpace"}) { |
2814 | 2868 | $TInfo{"Name"} = $TInfo{"NameSpace"}."::".$TInfo{"Name"}; |
2864 | 2918 | my $File = $DWARF_Info{$ID}{"decl_file"}; |
2865 | 2919 | my $Line = $DWARF_Info{$ID}{"decl_line"}; |
2866 | 2920 | |
2867 | my $Unit = $DWARF_Info{$ID}{"CompUnit"}; | |
2921 | my $Unit = $DWARF_Info{$ID}{"Unit"}; | |
2868 | 2922 | |
2869 | 2923 | if(defined $File) |
2870 | 2924 | { |
2879 | 2933 | } |
2880 | 2934 | |
2881 | 2935 | if($Name=~/\.($HEADER_EXT)\Z/) |
2882 | { | |
2936 | { # header | |
2883 | 2937 | $R->{"Header"} = $Name; |
2884 | 2938 | if(defined $Line) { |
2885 | 2939 | $R->{"Line"} = $Line; |
2886 | 2940 | } |
2887 | 2941 | } |
2888 | 2942 | elsif($Name ne "<built-in>") |
2889 | { | |
2943 | { # source | |
2890 | 2944 | $R->{"Source"} = $Name; |
2891 | 2945 | if(defined $Line) { |
2892 | 2946 | $R->{"SourceLine"} = $Line; |
3118 | 3172 | { |
3119 | 3173 | if(my $OLD_ID = $Mangled_ID{$MnglName}) |
3120 | 3174 | { # duplicates |
3121 | #print Dumper($DWARF_Info{$ID})." $OLD_ID $ID\n" if($MnglName eq "_ZSt22__uninitialized_move_aIPSsS0_SaISsEET0_T_S3_S2_RT1_"); | |
3175 | if(not defined $SymbolInfo{$OLD_ID}{"Header"} | |
3176 | or not defined $SymbolInfo{$OLD_ID}{"Source"}) | |
3177 | { | |
3178 | setSource($SymbolInfo{$OLD_ID}, $ID); | |
3179 | } | |
3180 | ||
3122 | 3181 | if(defined $Checked_Spec{$MnglName} |
3123 | 3182 | or not $DWARF_Info{$ID}{"specification"}) |
3124 | { # add spec info | |
3125 | if(not defined $SymbolInfo{$OLD_ID}{"Header"} | |
3126 | or not defined $SymbolInfo{$OLD_ID}{"Source"}) | |
3127 | { | |
3128 | if($DWARF_Info{$ID}{"decl_file"} ne $DWARF_Info{$OLD_ID}{"decl_file"}) | |
3129 | { | |
3130 | setSource($SymbolInfo{$OLD_ID}, $ID); | |
3131 | } | |
3132 | } | |
3133 | ||
3183 | { | |
3134 | 3184 | if(not defined $SpecElem{$ID} |
3135 | 3185 | and not defined $OrigElem{$ID}) { |
3136 | 3186 | delete($DWARF_Info{$ID}); |
3137 | 3187 | } |
3138 | ||
3139 | 3188 | return; |
3140 | 3189 | } |
3141 | 3190 | } |
3696 | 3745 | delete($TypeInfo{$Tid}); |
3697 | 3746 | } |
3698 | 3747 | } |
3748 | ||
3749 | # clean memory | |
3750 | %MergedTypes = (); | |
3751 | %LocalType = (); | |
3699 | 3752 | |
3700 | 3753 | # completeness |
3701 | 3754 | foreach my $Tid (keys(%TypeInfo)) { |