diff options
author | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-06-30 16:39:53 +0300 |
---|---|---|
committer | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-06-30 16:39:53 +0300 |
commit | 267c872f04da28790acfd0dd19185c5d1632e3c1 (patch) | |
tree | 508dccbb9c4849323ba10bf071f8ad9619ef9873 | |
parent | be41071033f9a235c2efbc727b8f943cc3490f8c (diff) | |
download | abi-dumper-267c872f04da28790acfd0dd19185c5d1632e3c1.tar.gz |
Fixed detection of public data types in header files. Improved -use-tu-dump option. Added -mixed-headers and -debug options.
-rw-r--r-- | abi-dumper.pl | 284 |
1 files changed, 225 insertions, 59 deletions
diff --git a/abi-dumper.pl b/abi-dumper.pl index dd0fc65..7a906fb 100644 --- a/abi-dumper.pl +++ b/abi-dumper.pl @@ -66,7 +66,7 @@ $TargetVersion, $ExtraInfo, $FullDump, $AllTypes, $AllSymbols, $BinOnly, $SkipCxx, $Loud, $AddrToName, $DumpStatic, $Compare, $AltDebugInfo, $AddDirs, $VTDumperPath, $SymbolsListPath, $PublicHeadersPath, $IgnoreTagsPath, $KernelExport, $UseTU, $ReimplementStd, -$IncludePreamble, $IncludePaths, $CacheHeaders); +$IncludePreamble, $IncludePaths, $CacheHeaders, $MixedHeaders, $Debug); my $CmdName = getFilename($0); @@ -127,7 +127,9 @@ GetOptions("h|help!" => \$Help, "public-headers=s" => \$PublicHeadersPath, "ignore-tags=s" => \$IgnoreTagsPath, "reimplement-std!" => \$ReimplementStd, + "mixed-headers!" => \$MixedHeaders, "kernel-export!" => \$KernelExport, + "debug!" => \$Debug, # extra options "use-tu-dump!" => \$UseTU, "include-preamble=s" => \$IncludePreamble, @@ -246,10 +248,18 @@ GENERAL OPTIONS: -public-headers option and the library reimplements some standard symbols (e.g. malloc). + -mixed-headers + This option should be specified if you are using + -public-headers option and the names of public headers + intersect with the internal headers. + -kernel-export Dump symbols exported by the Linux kernel and modules, i.e. symbols declared in the ksymtab section of the object and system calls. + + -debug + Enable debug messages. EXTRA OPTIONS: -use-tu-dump @@ -266,7 +276,9 @@ EXTRA OPTIONS: -include-paths DIRS Specify include directories (separated by semicolon) that should be passed to the compiler by -I option - in order to compile headers without errors. + in order to compile headers without errors. If this + option is not set then the tool will try to generate + include paths automatically. -cache-headers DIR Cache headers analysis results to reuse later. @@ -2131,19 +2143,6 @@ sub read_ABI() } } } - - if(defined $PublicHeadersPath) - { - if(not $TypeInfo{$Tid}{"Header"}) - { - my $TName = $TypeInfo{$Tid}{"Name"}; - $TName=~s/\A(struct|class|union|enum) //g; - - if(defined $TypeToHeader{$TName}) { - $TypeInfo{$Tid}{"Header"} = $TypeToHeader{$TName}; - } - } - } } } @@ -2277,7 +2276,7 @@ sub complete_ABI() { if(defined $TypeInfo{$BTid} and $TypeInfo{$BTid}{"Name"}=~/\Aanon\-(\w+)\-/ - and $TypeInfo{$BTid}{"Type"} eq "Enum") + and $TypeInfo{$BTid}{"Type"}=~/Enum|Struct|Union/) { %{$TypeInfo{$Tid}} = %{$TypeInfo{$BTid}}; $TypeInfo{$Tid}{"Name"} = $1." ".$TN; @@ -2319,17 +2318,6 @@ sub complete_ABI() } } - foreach my $Tid (sort {int($a) <=> int($b)} keys(%TypeInfo)) - { - if(defined $PublicHeadersPath) - { - if(not selectPublicType($Tid)) - { - $TypeInfo{$Tid}{"PrivateABI"} = 1; - } - } - } - foreach my $Tid (keys(%Delete)) { my $TN = $TypeInfo{$Tid}{"Name"}; @@ -2496,6 +2484,35 @@ sub complete_ABI() } } +sub warnPrivateType($$) +{ + my ($Name, $Note) = @_; + + if($Name=~/Private|Opaque/i) + { # _GstClockPrivate + # _Eo_Opaque + return; + } + + if($Name=~/(\A| )_/i) + { # _GstBufferList + return; + } + + if($Name=~/_\Z/i) + { # FT_RasterRec_ + return; + } + + printMsg("WARNING", "Private data type \'".$Name."\' ($Note)"); +} + +sub warnPrivateSymbol($$) +{ + my ($Name, $Note) = @_; + printMsg("WARNING", "Private symbol \'".$Name."\' ($Note)"); +} + sub selectPublicType($) { my $Tid = $_[0]; @@ -2507,24 +2524,49 @@ sub selectPublicType($) my $TName = $TypeInfo{$Tid}{"Name"}; $TName=~s/\A(struct|class|union|enum) //g; - my $Header = $TypeInfo{$Tid}{"Header"}; + my $Header = getFilename($TypeInfo{$Tid}{"Header"}); + + if($OBJ_LANG eq "C++" + or index($TName, "anon-")==0) { + return ($Header and defined $PublicHeader{$Header}); + } - if(not defined $Header - or not defined $PublicHeader{getFilename($Header)}) + if($Header) { - if($OBJ_LANG eq "C") + if(not defined $PublicHeader{$Header}) + { + if(not defined $TypeToHeader{$TName}) { + return 0; + } + elsif($Header ne $TypeToHeader{$TName}) { + return 0; + } + } + elsif($MixedHeaders) { if(not defined $TypeToHeader{$TName}) { + if(defined $Debug) { + warnPrivateType($TypeInfo{$Tid}{"Name"}, "NOT_FOUND"); + } return 0; } - elsif(defined $Header - and $Header ne $TypeToHeader{$TName}) + elsif($Header ne $TypeToHeader{$TName}) { + if(defined $Debug) { + warnPrivateType($TypeInfo{$Tid}{"Name"}, "OTHER_HEADER"); + } return 0; } } - else { + } + else + { + if(not defined $TypeToHeader{$TName}) + { + # if(defined $Debug) { + # warnPrivateType($TypeInfo{$Tid}{"Name"}, "NO_HEADER"); + # } return 0; } } @@ -2536,25 +2578,56 @@ sub selectPublic($$) { my ($Symbol, $ID) = @_; - if(not defined $SymbolInfo{$ID}{"Header"} - or not defined $PublicHeader{getFilename($SymbolInfo{$ID}{"Header"})}) + my $Header = getFilename($SymbolInfo{$ID}{"Header"}); + + if($OBJ_LANG eq "C++") { + return ($Header and defined $PublicHeader{$Header}); + } + + if($Header) { - if($OBJ_LANG eq "C") + if(not defined $PublicHeader{$Header}) + { + if(not defined $SymbolToHeader{$Symbol}) { + return 0; + } + elsif($Header ne $SymbolToHeader{$Symbol} + and not defined $SymbolInfo{$ID}{"Alias"}) + { + if(not $ReimplementStd) { + return 0; + } + } + } + elsif($MixedHeaders) { if(not defined $SymbolToHeader{$Symbol}) { + if(defined $Debug) { + warnPrivateSymbol($Symbol, "NOT_FOUND"); + } return 0; } - elsif(defined $SymbolInfo{$ID}{"Header"} - and $SymbolInfo{$ID}{"Header"} ne $SymbolToHeader{$Symbol} + elsif($Header ne $SymbolToHeader{$Symbol} and not defined $SymbolInfo{$ID}{"Alias"}) { - if(not $ReimplementStd) { + if(not $ReimplementStd) + { + if(defined $Debug) { + warnPrivateSymbol($Symbol, "OTHER_HEADER"); + } return 0; } } } - else { + } + else + { + if(not defined $SymbolToHeader{$Symbol}) + { + # if(defined $Debug) { + # warnPrivateSymbol($Symbol, "NO_HEADER"); + # } return 0; } } @@ -4976,7 +5049,7 @@ sub findFiles(@) sub isHeader($) { my $Path = $_[0]; - return ($Path=~/\.(h|hh|hp|hxx|hpp|h\+\+|tcc)\Z/i); + return ($Path=~/\.(h|hh|hp|hxx|hpp|h\+\+|tcc|x|inl)\Z/i); } sub detectPublicSymbols($) @@ -5083,8 +5156,14 @@ sub detectPublicSymbols($) my $TmpContent = ""; if($IncludePreamble) { - foreach my $P (split(/;/, $IncludePreamble)) { - $TmpContent = "#include \"".$P."\"\n"; + foreach my $P (split(/;/, $IncludePreamble)) + { + if($P=~/\A\//) { + $TmpContent = "#include \"".$P."\"\n"; + } + else { + $TmpContent = "#include <".$P.">\n"; + } } } $TmpContent .= "#include \"$File_A\"\n"; @@ -5092,7 +5171,7 @@ sub detectPublicSymbols($) my $Cmd = $GPP." -w -fpermissive -fdump-translation-unit -fkeep-inline-functions -c \"$TmpInc\""; - if($IncludePaths) + if(defined $IncludePaths) { foreach my $P (split(/;/, $IncludePaths)) { @@ -5103,11 +5182,14 @@ sub detectPublicSymbols($) $Cmd .= " -I\"".$P."\""; } } + else + { # automatic + $Cmd .= " -I\"$IncDir\" -I\"$IncDir_O\""; + } foreach my $P (@DefaultInc) { $Cmd .= " -I\"$P\""; } - $Cmd .= " -I\"$IncDir\" -I\"$IncDir_O\""; $Cmd .= " -o ./a.out >OUT 2>&1"; @@ -5125,15 +5207,27 @@ sub detectPublicSymbols($) } else { - my (%Fdecl, %Tdecl, %Ident) = (); - foreach my $Line (split(/\n/, readFile($TuDump))) + my (%Fdecl, %Tdecl, %Tname, %Ident, %NotDecl) = (); + my $Content = readFile($TuDump); + $Content=~s/\n[ ]+/ /g; + + my @Lines = split(/\n/, $Content); + foreach my $N (0 .. $#Lines) { + my $Line = $Lines[$N]; if(index($Line, "function_decl")!=-1 or index($Line, "var_decl")!=-1) { if($Line=~/name: \@(\d+)/) { - $Fdecl{$1} = 1; + my $Id = $1; + + if($Line=~/srcp: ([^:]+)\:\d/) + { + if(defined $PublicHeader{$1}) { + $Fdecl{$Id} = $1; + } + } } } elsif($Line=~/\@(\d+)\s+identifier_node\s+strg:\s+(\w+)/) @@ -5144,9 +5238,50 @@ sub detectPublicSymbols($) { if(index($Line, "type_decl")!=-1) { + if($Line=~/\A\@(\d+)/) + { + my $Id = $1; + if($Line=~/name: \@(\d+)/) + { + my $NId = $1; + + if($Line=~/srcp: ([^:]+)\:\d/) + { + if(defined $PublicHeader{$1}) + { + $Tdecl{$Id} = $1; + $Tname{$Id} = $NId; + } + } + } + } + } + elsif(index($Line, "record_type")!=-1 + or index($Line, "union_type")!=-1) + { + if($Line!~/ flds:/) + { + if($Line=~/name: \@(\d+)/) + { + $NotDecl{$1} = 1; + } + } + } + elsif(index($Line, "enumeral_type")!=-1) + { + if($Line!~/ csts:/) + { + if($Line=~/name: \@(\d+)/) + { + $NotDecl{$1} = 1; + } + } + } + elsif(index($Line, "integer_type")!=-1) + { if($Line=~/name: \@(\d+)/) { - $Tdecl{$1} = 1; + $NotDecl{$1} = 1; } } } @@ -5154,9 +5289,8 @@ sub detectPublicSymbols($) foreach my $Id (keys(%Fdecl)) { - if(my $Name = $Ident{$Id}) - { - $SymbolToHeader{$Name} = $HName; + if(my $Name = $Ident{$Id}) { + $SymbolToHeader{$Name} = $Fdecl{$Id}; } } @@ -5164,9 +5298,12 @@ sub detectPublicSymbols($) { foreach my $Id (keys(%Tdecl)) { - if(my $Name = $Ident{$Id}) - { - $TypeToHeader{$Name} = $HName; + if(defined $NotDecl{$Id}) { + next; + } + + if(my $Name = $Ident{$Tname{$Id}}) { + $TypeToHeader{$Name} = $Tdecl{$Id}; } } } @@ -5192,11 +5329,16 @@ sub detectPublicSymbols($) if($Is_C) { - my $List_T = `$CTAGS -x --c-kinds=cgsu $IgnoreTags \"$File\"`; + my $List_T = `$CTAGS -x --c-kinds=gstu --language-force=c $IgnoreTags \"$File\"`; foreach my $Line (split(/\n/, $List_T)) { - if($Line=~/\A(\w+)/) { - $TypeToHeader{$1} = $HName; + if($Line=~/\A(\w+)/) + { + my $N = $1; + + if($Line!~/\b$N\s+$N\b/) { + $TypeToHeader{$1} = $HName; + } } } } @@ -5453,6 +5595,30 @@ sub scenario() complete_ABI(); remove_Unused(); + if(defined $PublicHeadersPath) + { + foreach my $Tid (sort {lc($TypeInfo{$a}{"Name"}) cmp lc($TypeInfo{$b}{"Name"})} keys(%TypeInfo)) + { + if(not $TypeInfo{$Tid}{"Header"}) + { + if($TypeInfo{$Tid}{"Type"}=~/Struct|Union|Enum|Typedef/) + { + my $TName = $TypeInfo{$Tid}{"Name"}; + $TName=~s/\A(struct|class|union|enum) //g; + + if(defined $TypeToHeader{$TName}) { + $TypeInfo{$Tid}{"Header"} = $TypeToHeader{$TName}; + } + } + } + + if(not selectPublicType($Tid)) + { + $TypeInfo{$Tid}{"PrivateABI"} = 1; + } + } + } + %Mangled_ID = (); %Checked_Spec = (); %SelectedSymbols = (); |