Skip to content

Commit

Permalink
Fixed error message if modules are not installed. Compare versioned d…
Browse files Browse the repository at this point in the history
…ata types. Fixed analysis of versioned symbols. Fixed analysis of alias symbols.
  • Loading branch information
lvc committed Jan 19, 2017
1 parent a6554a1 commit d90ffe3
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 237 deletions.
4 changes: 2 additions & 2 deletions INSTALL
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

Copyright (C) 2009-2011 Institute for System Programming, RAS
Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies)
Copyright (C) 2012-2016 Andrey Ponomarenko's ABI Laboratory
Copyright (C) 2012-2017 Andrey Ponomarenko's ABI Laboratory
All rights reserved.


RELEASE INFORMATION

Project: ABI Compliance Checker (ABICC)
Version: 2.0 Beta
Date: 2016-11-14
Date: 2017-01-19


This file explains how to install and setup environment
Expand Down
193 changes: 169 additions & 24 deletions abi-compliance-checker.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# Copyright (C) 2009-2011 Institute for System Programming, RAS
# Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies)
# Copyright (C) 2012-2016 Andrey Ponomarenko's ABI Laboratory
# Copyright (C) 2012-2017 Andrey Ponomarenko's ABI Laboratory
#
# Written by Andrey Ponomarenko
#
Expand Down Expand Up @@ -72,8 +72,9 @@
my %LoadedModules = ();
loadModule("Basic");
loadModule("Input");
loadModule("Utils");
loadModule("Path");
loadModule("Logging");
loadModule("Utils");
loadModule("TypeAttr");
loadModule("Filter");
loadModule("SysFiles");
Expand All @@ -95,7 +96,7 @@

my $ShortUsage = "ABI Compliance Checker (ABICC) $TOOL_VERSION
A tool for checking backward compatibility of a C/C++ library API
Copyright (C) 2016 Andrey Ponomarenko's ABI Laboratory
Copyright (C) 2017 Andrey Ponomarenko's ABI Laboratory
License: GNU LGPL or GNU GPL
Usage: $CmdName [options]
Expand Down Expand Up @@ -938,7 +939,9 @@ ()
return $DIR."/modules";
}
}
exitStatus("Module_Error", "can't find modules");

print STDERR "ERROR: can't find modules (Did you installed the tool by 'make install' command?)\n";
exit(9); # Module_Error
}

sub loadModule($)
Expand Down Expand Up @@ -1431,6 +1434,20 @@ ($)
$MnglName = $ShortName;
}

# symbol and its symlink have same signatures
if(my $SVer = $In::ABI{$LVer}{"SymbolVersion"}{$MnglName}) {
$CompSign{$LVer}{$SVer} = $SymbolInfo{$LVer}{$InfoId};
}

if(my $Alias = $SymbolInfo{$LVer}{$InfoId}{"Alias"})
{
$CompSign{$LVer}{$Alias} = $SymbolInfo{$LVer}{$InfoId};

if(my $SAVer = $In::ABI{$LVer}{"SymbolVersion"}{$Alias}) {
$CompSign{$LVer}{$SAVer} = $SymbolInfo{$LVer}{$InfoId};
}
}

if(defined $CompSign{$LVer}{$MnglName})
{ # NOTE: duplicated entries in the ABI Dump
if(defined $SymbolInfo{$LVer}{$InfoId}{"Param"})
Expand All @@ -1455,20 +1472,6 @@ ($)
$SymbolInfo{$LVer}{$InfoId}{"Unmangled"} = getSignature($MnglName, $LVer, "Class|Name|Qual");
}
}

# symbol and its symlink have same signatures
if(my $SVer = $In::ABI{$LVer}{"SymbolVersion"}{$MnglName}) {
$CompSign{$LVer}{$SVer} = $SymbolInfo{$LVer}{$InfoId};
}

if(my $Alias = $CompSign{$LVer}{$MnglName}{"Alias"})
{
$CompSign{$LVer}{$Alias} = $SymbolInfo{$LVer}{$InfoId};

if(my $SAVer = $In::ABI{$LVer}{"SymbolVersion"}{$Alias}) {
$CompSign{$LVer}{$SAVer} = $SymbolInfo{$LVer}{$InfoId};
}
}
}

if($In::ABI{$LVer}{"Language"} eq "C++"
Expand Down Expand Up @@ -1767,8 +1770,14 @@ ($)
}
foreach my $VirtFunc (@Funcs)
{
if($UsedDump{$LVer}{"DWARF"}) {
$VirtualTable{$LVer}{$ClassName}{$VirtFunc} = $CompSign{$LVer}{$VirtFunc}{"VirtPos"};
if($UsedDump{$LVer}{"DWARF"})
{
if(defined $CompSign{$LVer}{$VirtFunc}{"VirtPos"}) {
$VirtualTable{$LVer}{$ClassName}{$VirtFunc} = $CompSign{$LVer}{$VirtFunc}{"VirtPos"};
}
else {
$VirtualTable{$LVer}{$ClassName}{$VirtFunc} = 1;
}
}
else {
$VirtualTable{$LVer}{$ClassName}{$VirtFunc} = $Num++;
Expand Down Expand Up @@ -2954,15 +2963,17 @@ ($$)
$N1=~s/\A(struct|union|enum) //;
$N2=~s/\A(struct|union|enum) //;

if($N1 ne $N2
if($N1 ne $N2 and $N2!~/\A\Q$N1\E_v\d+\Z/
and not isAnon($N1)
and not isAnon($N2))
{ # different names
# NOTE: compare versioned types (type vs type_v30)
if($T1->{"Type"} ne "Pointer"
or $T2->{"Type"} ne "Pointer")
{ # compare base types
return 1;
}

if($N1!~/\Avoid\s*\*/
and $N2=~/\Avoid\s*\*/)
{
Expand Down Expand Up @@ -8756,7 +8767,7 @@ ($)
{ # expressions
next;
}
if(convert_integer($Old_Value) eq convert_integer($New_Value))
if(convertInteger($Old_Value) eq convertInteger($New_Value))
{ # 0x0001 and 0x1, 0x1 and 1 equal constants
next;
}
Expand Down Expand Up @@ -8825,7 +8836,7 @@ ($)
}
}

sub convert_integer($)
sub convertInteger($)
{
my $Value = $_[0];
if($Value=~/\A0x[a-f0-9]+\Z/)
Expand Down Expand Up @@ -9192,6 +9203,140 @@ ()
}
}

sub unpackDump($)
{
my $Path = $_[0];

$Path = getAbsPath($Path);
my ($Dir, $FileName) = sepPath($Path);

my $TmpDir = $In::Opt{"Tmp"};
my $UnpackDir = $TmpDir."/unpack";
rmtree($UnpackDir);
mkpath($UnpackDir);

if($FileName=~s/\Q.zip\E\Z//g)
{ # *.zip
my $UnzipCmd = getCmdPath("unzip");
if(not $UnzipCmd) {
exitStatus("Not_Found", "can't find \"unzip\" command");
}
chdir($UnpackDir);
system("$UnzipCmd \"$Path\" >\"$TmpDir/null\"");
if($?) {
exitStatus("Error", "can't extract \'$Path\' ($?): $!");
}
chdir($In::Opt{"OrigDir"});
my @Contents = cmdFind($UnpackDir, "f");
if(not @Contents) {
exitStatus("Error", "can't extract \'$Path\'");
}
return $Contents[0];
}
elsif($FileName=~s/\Q.tar.gz\E(\.\w+|)\Z//g)
{ # *.tar.gz
# *.tar.gz.amd64 (dh & cdbs)
if($In::Opt{"OS"} eq "windows")
{ # -xvzf option is not implemented in tar.exe (2003)
# use "gzip.exe -k -d -f" + "tar.exe -xvf" instead
my $TarCmd = getCmdPath("tar");
if(not $TarCmd) {
exitStatus("Not_Found", "can't find \"tar\" command");
}
my $GzipCmd = getCmdPath("gzip");
if(not $GzipCmd) {
exitStatus("Not_Found", "can't find \"gzip\" command");
}
chdir($UnpackDir);
system("$GzipCmd -k -d -f \"$Path\""); # keep input files (-k)
if($?) {
exitStatus("Error", "can't extract \'$Path\'");
}
system("$TarCmd -xvf \"$Dir\\$FileName.tar\" >\"$TmpDir/null\"");
if($?) {
exitStatus("Error", "can't extract \'$Path\' ($?): $!");
}
chdir($In::Opt{"OrigDir"});
unlink($Dir."/".$FileName.".tar");
my @Contents = cmdFind($UnpackDir, "f");
if(not @Contents) {
exitStatus("Error", "can't extract \'$Path\'");
}
return $Contents[0];
}
else
{ # Unix, Mac
my $TarCmd = getCmdPath("tar");
if(not $TarCmd) {
exitStatus("Not_Found", "can't find \"tar\" command");
}
chdir($UnpackDir);
system("$TarCmd -xvzf \"$Path\" >\"$TmpDir/null\"");
if($?) {
exitStatus("Error", "can't extract \'$Path\' ($?): $!");
}
chdir($In::Opt{"OrigDir"});
my @Contents = cmdFind($UnpackDir, "f");
if(not @Contents) {
exitStatus("Error", "can't extract \'$Path\'");
}
return $Contents[0];
}
}
}

sub createArchive($$)
{
my ($Path, $To) = @_;
if(not $To) {
$To = ".";
}

my ($From, $Name) = sepPath($Path);
if($In::Opt{"OS"} eq "windows")
{ # *.zip
my $ZipCmd = getCmdPath("zip");
if(not $ZipCmd) {
exitStatus("Not_Found", "can't find \"zip\"");
}
my $Pkg = $To."/".$Name.".zip";
unlink($Pkg);
chdir($To);
system("$ZipCmd -j \"$Name.zip\" \"$Path\" >\"".$In::Opt{"Tmp"}."/null\"");
if($?)
{ # cannot allocate memory (or other problems with "zip")
unlink($Path);
exitStatus("Error", "can't pack the ABI dump: ".$!);
}
chdir($In::Opt{"OrigDir"});
unlink($Path);
return $Pkg;
}
else
{ # *.tar.gz
my $TarCmd = getCmdPath("tar");
if(not $TarCmd) {
exitStatus("Not_Found", "can't find \"tar\"");
}
my $GzipCmd = getCmdPath("gzip");
if(not $GzipCmd) {
exitStatus("Not_Found", "can't find \"gzip\"");
}
my $Pkg = abs_path($To)."/".$Name.".tar.gz";
unlink($Pkg);
chdir($From);
system($TarCmd, "-czf", $Pkg, $Name);
if($?)
{ # cannot allocate memory (or other problems with "tar")
unlink($Path);
exitStatus("Error", "can't pack the ABI dump: ".$!);
}
chdir($In::Opt{"OrigDir"});
unlink($Path);
return $To."/".$Name.".tar.gz";
}
}

sub defaultDumpPath($$)
{
my ($N, $V) = @_;
Expand Down Expand Up @@ -10094,7 +10239,7 @@ ()
}
if($In::Opt{"ShowVersion"})
{
printMsg("INFO", "ABI Compliance Checker (ABICC) $TOOL_VERSION\nCopyright (C) 2016 Andrey Ponomarenko's ABI Laboratory\nLicense: LGPL or GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.");
printMsg("INFO", "ABI Compliance Checker (ABICC) $TOOL_VERSION\nCopyright (C) 2017 Andrey Ponomarenko's ABI Laboratory\nLicense: LGPL or GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.");
exit(0);
}
if($In::Opt{"DumpVersion"})
Expand Down
19 changes: 11 additions & 8 deletions modules/Internals/ABIDump.pm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###########################################################################
# A module to create ABI dump from AST tree
#
# Copyright (C) 2015-2016 Andrey Ponomarenko's ABI Laboratory
# Copyright (C) 2015-2017 Andrey Ponomarenko's ABI Laboratory
#
# Written by Andrey Ponomarenko
#
Expand Down Expand Up @@ -566,19 +566,22 @@ sub readSymbols_Lib($$$$$$)
my %Found = ();

# by value
foreach my $Symbol (keys(%{$In::ABI{$LVer}{"Symbols"}{$Lib_Name}}))
foreach my $Symbol (sort keys(%{$In::ABI{$LVer}{"Symbols"}{$Lib_Name}}))
{
next if(index($Symbol,"\@")==-1);
next if(index($Symbol, '@')==-1);
if(my $Value = $Interface_Value{$LVer}{$Symbol})
{
foreach my $Symbol_SameValue (keys(%{$Value_Interface{$LVer}{$Value}}))
foreach my $Symbol_SameValue (sort keys(%{$Value_Interface{$LVer}{$Value}}))
{
if($Symbol_SameValue ne $Symbol
and index($Symbol_SameValue,"\@")==-1)
and index($Symbol_SameValue, '@')==-1)
{
$In::ABI{$LVer}{"SymbolVersion"}{$Symbol_SameValue} = $Symbol;
$Found{$Symbol} = 1;
last;

if(index($Symbol, '@@')==-1) {
last;
}
}
}
}
Expand All @@ -588,7 +591,7 @@ sub readSymbols_Lib($$$$$$)
foreach my $Symbol (keys(%{$In::ABI{$LVer}{"Symbols"}{$Lib_Name}}))
{
next if(defined $Found{$Symbol});
next if(index($Symbol,"\@\@")==-1);
next if(index($Symbol, '@@')==-1);

if($Symbol=~/\A([^\@]*)\@\@/
and not $In::ABI{$LVer}{"SymbolVersion"}{$1})
Expand All @@ -602,7 +605,7 @@ sub readSymbols_Lib($$$$$$)
foreach my $Symbol (keys(%{$In::ABI{$LVer}{"Symbols"}{$Lib_Name}}))
{
next if(defined $Found{$Symbol});
next if(index($Symbol,"\@")==-1);
next if(index($Symbol, '@')==-1);

if($Symbol=~/\A([^\@]*)\@([^\@]*)/
and not $In::ABI{$LVer}{"SymbolVersion"}{$1})
Expand Down
Loading

0 comments on commit d90ffe3

Please sign in to comment.