diff options
author | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-02-21 03:45:16 +0300 |
---|---|---|
committer | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-02-21 03:45:16 +0300 |
commit | 8a4c3f8b1d2f4488f10fecb372880d3b78cc3497 (patch) | |
tree | a9f3fe15ee843d0d5f82138476c14db760ce0568 | |
parent | 109e3ae1c919dfe9a6b4cedbb3c45ba70659ea8a (diff) | |
download | abi-compliance-checker-8a4c3f8b1d2f4488f10fecb372880d3b78cc3497.tar.gz |
Verify changes in parameters of function pointers. Fixed comparison of virtual table entries. Do not show time stamp in the report. Fixed detection of the GCC version number. Fixed -skip-symbols option.
-rw-r--r-- | INSTALL | 48 | ||||
-rw-r--r-- | README | 30 | ||||
-rw-r--r-- | abi-compliance-checker.pl | 152 | ||||
-rw-r--r-- | doc/index.html | 2 |
4 files changed, 168 insertions, 64 deletions
@@ -9,8 +9,8 @@ All rights reserved. RELEASE INFORMATION Project: ABI Compliance Checker (ACC) -Version: 1.99.16 -Date: 2016-01-28 +Version: 1.99.17 +Date: 2016-02-21 This file explains how to install and setup environment @@ -23,8 +23,8 @@ Content: 2. Requirements for Mac OS X 3. Requirements for MS Windows 4. Configure and Install - 5. Usage (Original) - 6. Usage with ABI Dumper + 5. Usage (with ABI Dumper) + 6. Usage (Original) 1. REQUIREMENTS FOR LINUX AND FREEBSD @@ -34,7 +34,7 @@ Content: 2. GNU Binutils (c++filt, readelf, objdump) 3. Perl 5 (5.8 or newer) 4. Ctags (5.8 or newer) - 5. ABI Dumper (0.99.14 or newer) + 5. ABI Dumper (0.99.15 or newer) @@ -77,7 +77,25 @@ Content: -5. USAGE (ORIGINAL) +5. USAGE (WITH ABI DUMPER) +========================== + + Library should be compiled with -g -Og + options to contain DWARF debug info. + + Create ABI dumps for both library versions + using the ABI Dumper tool (https://github.com/lvc/abi-dumper): + + abi-dumper OLD.so -o ABI-0.dump -lver 0 + abi-dumper NEW.so -o ABI-1.dump -lver 1 + + Compare ABI dumps to create report: + + abi-compliance-checker -l NAME -old ABI-0.dump -new ABI-1.dump + + + +6. USAGE (ORIGINAL) =================== Create XML-descriptors for two versions @@ -106,22 +124,4 @@ Content: For advanced usage, see doc/index.html or -help option. - -6. USAGE WITH ABI DUMPER -======================== - - Library should be compiled with -g -Og - options to contain DWARF debug info. - - Create ABI dumps for both library versions - using the ABI Dumper tool (https://github.com/lvc/abi-dumper): - - abi-dumper OLD.so -o ABI-0.dump -lver 0 - abi-dumper NEW.so -o ABI-1.dump -lver 1 - - Compare ABI dumps to create report: - - abi-compliance-checker -l NAME -old ABI-0.dump -new ABI-1.dump - - Enjoy! @@ -17,6 +17,21 @@ REQUIRES: Ctags ABI Dumper (0.99.14 or newer) +USAGE (WITH ABI DUMPER): + + 1. Library should be compiled with "-g -Og" GCC options + to contain DWARF debug info + + 2. Create ABI dumps for both library versions + using the ABI Dumper (https://github.com/lvc/abi-dumper) tool: + + abi-dumper OLD.so -o ABI-0.dump -lver 0 + abi-dumper NEW.so -o ABI-1.dump -lver 1 + + 3. Compare ABI dumps to create report: + + abi-compliance-checker -l NAME -old ABI-0.dump -new ABI-1.dump + USAGE (ORIGINAL): abi-compliance-checker -lib NAME -old OLD.xml -new NEW.xml @@ -34,20 +49,5 @@ USAGE (ORIGINAL): /path/to/libraries/ </libs> -USAGE WITH ABI DUMPER: - - 1. Library should be compiled with "-g -Og" GCC options - to contain DWARF debug info - - 2. Create ABI dumps for both library versions - using the ABI Dumper (https://github.com/lvc/abi-dumper) tool: - - abi-dumper OLD.so -o ABI-0.dump -lver 0 - abi-dumper NEW.so -o ABI-1.dump -lver 1 - - 3. Compare ABI dumps to create report: - - abi-compliance-checker -l NAME -old ABI-0.dump -new ABI-1.dump - ADV. USAGE: For advanced usage, see doc/index.html or output of -help option. diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl index 6f14454..650f3a1 100644 --- a/abi-compliance-checker.pl +++ b/abi-compliance-checker.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl ########################################################################### -# ABI Compliance Checker (ABICC) 1.99.16 +# ABI Compliance Checker (ABICC) 1.99.17 # A tool for checking backward compatibility of a C/C++ library API # # Copyright (C) 2009-2011 Institute for System Programming, RAS @@ -21,7 +21,7 @@ # - GNU Binutils (readelf, c++filt, objdump) # - Perl 5 (5.8 or newer) # - Ctags (5.8 or newer) -# - ABI Dumper (0.99.14 or newer) +# - ABI Dumper (0.99.15 or newer) # # Mac OS X # - Xcode (g++, c++filt, otool, nm) @@ -60,7 +60,7 @@ use Storable qw(dclone); use Data::Dumper; use Config; -my $TOOL_VERSION = "1.99.16"; +my $TOOL_VERSION = "1.99.17"; my $ABI_DUMP_VERSION = "3.2"; my $XML_REPORT_VERSION = "1.2"; my $XML_ABI_DUMP_VERSION = "1.2"; @@ -4931,7 +4931,7 @@ sub linkSymbol($) or $EMERGENCY_MODE_48) { # GCC 3.x doesn't mangle class methods names in the TU dump (only functions and global data) # GCC 4.x doesn't mangle C++ functions in the TU dump (only class methods) except extern "C" functions - # GCC 4.8 doesn't mangle anything + # GCC 4.8.[012] doesn't mangle anything if(not $CheckHeadersOnly) { if(my $Mangled = $mangled_name_gcc{modelUnmangled($InfoId, "GCC")}) { @@ -7452,12 +7452,18 @@ sub get_Signature($$) my ($Signature, @Param_Types_FromUnmangledName) = (); my $ShortName = $CompleteSignature{$LibVersion}{$Symbol}{"ShortName"}; + if($Symbol=~/\A(_Z|\?)/) { if(my $ClassId = $CompleteSignature{$LibVersion}{$Symbol}{"Class"}) { my $ClassName = $TypeInfo{$LibVersion}{$ClassId}{"Name"}; $ClassName=~s/\bstruct //g; + + if(index($Symbol, "_ZTV")==0) { + return "vtable for $ClassName [data]"; + } + $Signature .= $ClassName."::"; if($CompleteSignature{$LibVersion}{$Symbol}{"Destructor"}) { $Signature .= "~"; @@ -7480,9 +7486,15 @@ sub get_Signature($$) my @ParamArray = (); foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Symbol}{"Param"}})) { - next if($Pos eq ""); + if($Pos eq "") { + next; + } + my $ParamTypeId = $CompleteSignature{$LibVersion}{$Symbol}{"Param"}{$Pos}{"type"}; - next if(not $ParamTypeId); + if(not $ParamTypeId) { + next; + } + my $ParamTypeName = $TypeInfo{$LibVersion}{$ParamTypeId}{"Name"}; if(not $ParamTypeName) { $ParamTypeName = $Param_Types_FromUnmangledName[$Pos]; @@ -9277,6 +9289,19 @@ sub prepareSymbols($) if(not $MnglName) { next; } + + # NOTE: duplicated entries in the ABI Dump + if(defined $CompleteSignature{$LibVersion}{$MnglName}) + { + if(defined $SymbolInfo{$LibVersion}{$InfoId}{"Param"}) + { + if($SymbolInfo{$LibVersion}{$InfoId}{"Param"}{0}{"name"} eq "p1") + { + next; + } + } + } + if(not $CompleteSignature{$LibVersion}{$MnglName}{"MnglName"}) { # NOTE: global data may enter here twice %{$CompleteSignature{$LibVersion}{$MnglName}} = %{$SymbolInfo{$LibVersion}{$InfoId}}; @@ -9297,6 +9322,7 @@ sub prepareSymbols($) if(my $Alias = $CompleteSignature{$LibVersion}{$MnglName}{"Alias"}) { %{$CompleteSignature{$LibVersion}{$Alias}} = %{$SymbolInfo{$LibVersion}{$InfoId}}; + if($SymVer{$LibVersion}{$Alias}) { %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$Alias}}} = %{$SymbolInfo{$LibVersion}{$InfoId}}; } @@ -9789,14 +9815,26 @@ sub isTargetType($$) } if(my $THeader = $TypeInfo{$LibVersion}{$Tid}{"Header"}) - { + { # NOTE: header is defined to source if undefined (DWARF dumps) if(not is_target_header($THeader, $LibVersion)) { # from target headers return 0; } } - else { - return 0; + else + { # NOTE: if type is defined in source + if($UsedDump{$LibVersion}{"Public"}) + { + if(isPrivateABI($Tid, $LibVersion)) { + return 0; + } + else { + return 1; + } + } + else { + return 0; + } } if($SkipInternalTypes) @@ -10472,7 +10510,7 @@ sub cmpVTables_Real($$) $Entry1 = simpleVEntry($Entry1); $Entry2 = simpleVEntry($Entry2); - if($Entry1=~/ 0x/ and $Entry2=~/ 0x/) + if($Entry1=~/ 0x/ or $Entry2=~/ 0x/) { # NOTE: problem with vtable-dumper next; } @@ -12277,6 +12315,47 @@ sub mergeTypes($$$) } } + if($Type1_Pure{"Type"} eq "FuncPtr") + { + foreach my $PPos (sort {int($a) <=> int($b)} keys(%{$Type1_Pure{"Param"}})) + { + if(not defined $Type2_Pure{"Param"}{$PPos}) { + next; + } + + my $PT1 = $Type1_Pure{"Param"}{$PPos}{"type"}; + my $PT2 = $Type2_Pure{"Param"}{$PPos}{"type"}; + + my $PName = "p".$PPos; + + my $FP_SubProblems = mergeTypes($PT1, $PT2, $Level); + my %DupProblems = (); + + foreach my $FP_SubProblemType (keys(%{$FP_SubProblems})) + { + foreach my $FP_SubLocation (keys(%{$FP_SubProblems->{$FP_SubProblemType}})) + { + if(not defined $AllAffected) + { + if(defined $DupProblems{$FP_SubProblems->{$FP_SubProblemType}{$FP_SubLocation}}) { + next; + } + } + + my $NewLocation = ($FP_SubLocation)?$PName."->".$FP_SubLocation:$PName; + $SubProblems{$FP_SubProblemType}{$NewLocation} = $FP_SubProblems->{$FP_SubProblemType}{$FP_SubLocation}; + + if(not defined $AllAffected) + { + $DupProblems{$FP_SubProblems->{$FP_SubProblemType}{$FP_SubLocation}} = 1; + } + } + } + + %DupProblems = (); + } + } + pop(@RecurTypes); return ($Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id} = \%SubProblems); } @@ -12712,6 +12791,11 @@ sub mergeLibs($) next; } } + + if($SkipSymbols{1}{$Symbol}) + { # user defined symbols to ignore + next; + } } else { next if(not symbolFilter($Symbol, 1, "Affected + InlineVirt", $Level)); @@ -15545,7 +15629,7 @@ sub get_SourceInfo() $CheckedLibs .= "<div class='lib_list'>\n"; foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$Library_Symbol{1}})) { - $Library.=" (.$LIB_EXT)" if($Library!~/\.\w+\Z/); + # $Library .= " (.$LIB_EXT)" if($Library!~/\.\w+\Z/); $CheckedLibs .= $Library."<br/>\n"; } $CheckedLibs .= "</div>\n"; @@ -15860,7 +15944,7 @@ sub get_Summary($) $TestResults .= " <libs>\n"; foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$Library_Symbol{1}})) { - $Library.=" (.$LIB_EXT)" if($Library!~/\.\w+\Z/); + # $Library .= " (.$LIB_EXT)" if($Library!~/\.\w+\Z/); $TestResults .= " <name>$Library</name>\n"; } $TestResults .= " </libs>\n"; @@ -16264,9 +16348,11 @@ sub getTitle($$$) { my ($Header, $Library, $NameSpace) = @_; my $Title = ""; - if($Library and $Library!~/\.\w+\Z/) { - $Library .= " (.$LIB_EXT)"; - } + + # if($Library and $Library!~/\.\w+\Z/) { + # $Library .= " (.$LIB_EXT)"; + # } + if($Header and $Library) { $Title .= "<span class='h_name'>$Header</span>"; @@ -17039,7 +17125,13 @@ sub showVTables($) foreach my $Index (sort {int($a)<=>int($b)} (keys(%Entries))) { my ($Color1, $Color2) = ("", ""); - if($Entries{$Index}{"E1"} ne $Entries{$Index}{"E2"}) + + my $E1 = $Entries{$Index}{"E1"}; + my $E2 = $Entries{$Index}{"E2"}; + + if($E1 ne $E2 + and $E1!~/ 0x/ + and $E2!~/ 0x/) { if($Entries{$Index}{"E1"}) { @@ -17668,10 +17760,10 @@ sub getReportFooter() { my $Footer = ""; - $Footer .= "<hr/>"; - $Footer .= "<div class='footer' align='right'><i>Generated on ".localtime(time); - $Footer .= " by <a href='".$HomePage."'>ABI Compliance Checker</a> $TOOL_VERSION  "; - $Footer .= "</i></div>"; + $Footer .= "<hr/>\n"; + $Footer .= "<div class='footer' align='right'>"; + $Footer .= "<i>Generated by <a href='".$HomePage."'>ABI Compliance Checker</a> $TOOL_VERSION  </i>\n"; + $Footer .= "</div>\n"; $Footer .= "<br/>\n"; return $Footer; @@ -20886,7 +20978,19 @@ sub detect_default_paths($) exitStatus("Not_Found", "can't find GCC>=3.0 in PATH"); } - if(my $GCC_Ver = get_dumpversion($GCC_PATH)) + my $GCC_Ver = get_dumpversion($GCC_PATH); + if($GCC_Ver eq "4.8") + { # on Ubuntu -dumpversion returns 4.8 for gcc 4.8.4 + my $Info = `$GCC_PATH --version`; + + if($Info=~/gcc\s+(|\([^()]+\)\s+)(\d+\.\d+\.\d+)/) + { # gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 + # gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) + $GCC_Ver = $2; + } + } + + if($GCC_Ver) { my $GccTarget = get_dumpmachine($GCC_PATH); @@ -20906,9 +21010,9 @@ sub detect_default_paths($) # check GCC version if($GCC_Ver=~/\A4\.8(|\.[012])\Z/) { # bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57850 - # introduced in 4.8 - # fixed in 4.8.3 - printMsg("WARNING", "Not working properly with GCC $GCC_Ver. Please update or downgrade GCC or use a local installation by --gcc-path=PATH option."); + # introduced in 4.8 and fixed in 4.8.3 + printMsg("WARNING", "Not working properly with GCC $GCC_Ver. Please update GCC to 4.8.3 or downgrade it to 4.7. You can use a local GCC installation by --gcc-path=PATH option."); + $EMERGENCY_MODE_48 = 1; } } diff --git a/doc/index.html b/doc/index.html index 39def3e..a2f47d7 100644 --- a/doc/index.html +++ b/doc/index.html @@ -92,7 +92,7 @@ <a name="Downloads"></a> <h2>Downloads</h2> -<p>All releases can be downloaded from <a href="https://github.com/lvc/abi-compliance-checker/">this page</a>.</p> +<p>All releases can be downloaded from <a href="https://github.com/lvc/abi-compliance-checker/releases">this page</a>.</p> <p>Latest release: <a href="https://github.com/lvc/abi-compliance-checker/archive/1.99.16.tar.gz">abi-compliance-checker-1.99.16.tar.gz</a></p> |