Check if the cpu architecture of the input objects is equal to architecture of the used GCC compiler; Added -arch option
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl
index bd08cdd..6ac2bf2 100755
--- a/abi-compliance-checker.pl
+++ b/abi-compliance-checker.pl
@@ -93,7 +93,8 @@
 $UserLang, $TargetHeadersPath, $BinaryOnly, $SourceOnly, $BinaryReportPath,
 $SourceReportPath, $UseXML, $Browse, $OpenReport, $SortDump, $DumpFormat,
 $ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant, $SkipSymbolsListPath,
-$CheckInfo, $Quick, $AffectLimit, $AllAffected, $CppIncompat, $SkipInternal);
+$CheckInfo, $Quick, $AffectLimit, $AllAffected, $CppIncompat, $SkipInternal,
+$TargetArch);
 
 my $CmdName = get_filename($0);
 my %OS_LibExt = (
@@ -244,6 +245,7 @@
   "dump-format=s" => \$DumpFormat,
   "xml!" => \$UseXML,
   "lang=s" => \$UserLang,
+  "arch=s" => \$TargetArch,
   "binary|bin|abi!" => \$BinaryOnly,
   "source|src|api!" => \$SourceOnly,
   "limit-affected|affected-limit=s" => \$AffectLimit,
@@ -631,6 +633,11 @@
       Set library language (C or C++). You can use this option if the tool
       cannot auto-detect a language. This option may be useful for checking
       C-library headers (--lang=C) in --headers-only or --extended modes.
+  
+  -arch ARCH
+      Set library architecture (x86, x86_64, ia64, arm, ppc32, ppc64, s390,
+      ect.). The option is useful if the tool cannot detect correct architecture
+      of the input objects.
 
   -binary|-bin|-abi
       Show \"Binary\" compatibility problems only.
@@ -15560,6 +15567,11 @@
 sub getArch($)
 {
     my $LibVersion = $_[0];
+    
+    if($TargetArch) {
+        return $TargetArch;
+    }
+    
     if($CPU_ARCH{$LibVersion})
     { # dump version
         return $CPU_ARCH{$LibVersion};
@@ -15568,8 +15580,14 @@
     { # old-version dumps
         return "unknown";
     }
-    if(defined $Cache{"getArch"}{$LibVersion}) {
-        return $Cache{"getArch"}{$LibVersion};
+    
+    return getArch_GCC();
+}
+
+sub getArch_GCC()
+{
+    if(defined $Cache{"getArch_GCC"}) {
+        return $Cache{"getArch_GCC"};
     }
     my $Arch = get_dumpmachine($GCC_PATH); # host version
     if(not $Arch) {
@@ -15585,8 +15603,7 @@
         $Arch = "x86" if($Arch=~/win32|mingw32/i);
         $Arch = "x86_64" if($Arch=~/win64|mingw64/i);
     }
-    $Cache{"getArch"}{$LibVersion} = $Arch;
-    return $Arch;
+    return ($Cache{"getArch_GCC"} = $Arch);
 }
 
 sub get_Report_Header($)
@@ -19265,9 +19282,10 @@
         { # 1197 4AC 0000A620 SetThreadStackGuarantee
           # 1198 4AD          SetThreadToken (forwarded to ...)
           # 3368 _o2i_ECPublicKey
-            if(/\A\s*\d+\s+[a-f\d]+\s+[a-f\d]+\s+([\w\?\@]+)\s*\Z/i
+          # 1 0 00005B30 ??0?N = ... (with pdb)
+            if(/\A\s*\d+\s+[a-f\d]+\s+[a-f\d]+\s+([\w\?\@]+)\s*(?:=.+)?\Z/i
             or /\A\s*\d+\s+[a-f\d]+\s+([\w\?\@]+)\s*\(\s*forwarded\s+/
-            or /\A\s*\d+\s+_([\w\?\@]+)\s*\Z/)
+            or /\A\s*\d+\s+_([\w\?\@]+)\s*(?:=.+)?\Z/)
             { # dynamic, static and forwarded symbols
                 my $realname = $1;
                 if($IsNeededLib)
@@ -19805,6 +19823,7 @@
 sub registerObject($$)
 {
     my ($Path, $LibVersion) = @_;
+    
     my $Name = get_filename($Path);
     $RegisteredObjects{$LibVersion}{$Name} = $Path;
     if($OSgroup=~/linux|bsd/i)
@@ -19816,6 +19835,108 @@
     if(my $Short = parse_libname($Name, "name+ext", $OStarget)) {
         $RegisteredObjects_Short{$LibVersion}{$Short} = $Path;
     }
+    
+    if(not $CPU_ARCH{$LibVersion})
+    {
+        $CPU_ARCH{$LibVersion} = getArch_Object($Path);
+        
+        if($CPU_ARCH{$LibVersion})
+        {
+            if(my $GccArch = getArch_GCC())
+            {
+                if($CPU_ARCH{$LibVersion} ne $GccArch)
+                { # translation unit dump generated by the GCC compiler should correspond to the input objects
+                    printMsg("WARNING", "the architectures of input objects and the used GCC compiler are not equal, please change the compiler by --gcc-path=PATH option.");
+                    $CPU_ARCH{$LibVersion} = $GccArch;
+                }
+            }
+        }
+    }
+}
+
+sub getArch_Object($)
+{
+    my $Path = $_[0];
+    
+    my %MachineType = (
+        "14C" => "x86",
+        "8664" => "x86_64",
+        "1C0" => "arm",
+        "200" => "ia64"
+    );
+    
+    if($OSgroup eq "windows")
+    {
+        my $DumpbinCmd = get_CmdPath("dumpbin");
+        if(not $DumpbinCmd) {
+            exitStatus("Not_Found", "can't find \"dumpbin\"");
+        }
+        
+        my $Cmd = $DumpbinCmd." /headers \"$Path\"";
+        my $Out = `$Cmd`;
+        
+        if($Out=~/(\w+)\smachine/)
+        {
+            if(my $Type = $MachineType{uc($1)})
+            {
+                return $Type;
+            }
+        }
+    }
+    elsif($OSgroup=~/linux|bsd/)
+    {
+        my $ObjdumpCmd = get_CmdPath("objdump");
+        if(not $ObjdumpCmd) {
+            exitStatus("Not_Found", "can't find \"objdump\"");
+        }
+        
+        my $Cmd = $ObjdumpCmd." -f \"$Path\"";
+        my $Out = `$Cmd`;
+        
+        if($Out=~/architecture:\s+([\w\-\:]+)/)
+        {
+            my $Arch = $1;
+            if($Arch=~s/\:(.+)//)
+            {
+                my $Suffix = $1;
+                
+                if($Suffix eq "x86-64") {
+                    $Arch = $Suffix;
+                }
+                
+                if($Arch eq "powerpc")
+                {
+                    if($Suffix eq "common64")
+                    {
+                        $Arch = "ppc64";
+                    }
+                    elsif($Suffix eq "common")
+                    {
+                        $Arch = "ppc32";
+                    }
+                }
+            }
+            
+            if($Arch=~/i[3-7]86/) {
+                $Arch = "x86";
+            }
+            
+            if($Arch eq "x86-64") {
+                $Arch = "x86_64";
+            }
+            
+            if($Arch=~/\A(x86|x86_64|arm|ia64)\Z/)
+            {
+                return $Arch;
+            }
+        }
+    }
+    else
+    { # macos, etc.
+        # TODO
+    }
+    
+    return undef;
 }
 
 sub getSONAME($)
@@ -19836,7 +19957,8 @@
     else {
         $SonameCmd .= " | grep SONAME";
     }
-    if(my $SonameInfo = `$SonameCmd`) {
+    if(my $SonameInfo = `$SonameCmd`)
+    {
         if($SonameInfo=~/SONAME\s+([^\s]+)/) {
             return ($Cache{"getSONAME"}{$Path} = $1);
         }
@@ -19912,34 +20034,50 @@
     return (grep {$_ eq $Value} @{$Stack});
 }
 
-sub detectWordSize()
+sub detectWordSize($)
 {
-    return "" if(not $GCC_PATH);
-    if($Cache{"detectWordSize"}) {
-        return $Cache{"detectWordSize"};
-    }
-    writeFile("$TMP_DIR/empty.h", "");
-    my $Defines = `$GCC_PATH -E -dD \"$TMP_DIR/empty.h\"`;
-    unlink("$TMP_DIR/empty.h");
-    my $WSize = 0;
-    if($Defines=~/ __SIZEOF_POINTER__\s+(\d+)/)
-    { # GCC 4
-        $WSize = $1;
-    }
-    elsif($Defines=~/ __PTRDIFF_TYPE__\s+(\w+)/)
-    { # GCC 3
-        my $PTRDIFF = $1;
-        if($PTRDIFF=~/long/) {
-            $WSize = "8";
+    my $LibVersion = $_[0];
+    
+    if(my $Arch = getArch($LibVersion))
+    {
+        if($Arch=~/64|390x/)
+        { # x86_64, ppc64, s390x, ia64, etc.
+            return "8";
         }
-        else {
-            $WSize = "4";
+        else
+        { # x86, ppc, s390, etc.
+            return "4";
         }
     }
-    if(not $WSize) {
-        exitStatus("Error", "can't check WORD size");
+    elsif($GCC_PATH)
+    {
+        writeFile("$TMP_DIR/empty.h", "");
+        my $Defines = `$GCC_PATH -E -dD \"$TMP_DIR/empty.h\"`;
+        unlink("$TMP_DIR/empty.h");
+        
+        my $WSize = 0;
+        if($Defines=~/ __SIZEOF_POINTER__\s+(\d+)/)
+        { # GCC 4
+            $WSize = $1;
+        }
+        elsif($Defines=~/ __PTRDIFF_TYPE__\s+(\w+)/)
+        { # GCC 3
+            my $PTRDIFF = $1;
+            if($PTRDIFF=~/long/) {
+                $WSize = "8";
+            }
+            else {
+                $WSize = "4";
+            }
+        }
+        if(not $WSize) {
+            exitStatus("Error", "can't check WORD size");
+        }
+        return $WSize;
     }
-    return ($Cache{"detectWordSize"} = $WSize);
+    
+    # error
+    return undef;
 }
 
 sub getWordSize($) {
@@ -21767,6 +21905,7 @@
     if(not -e $DumpAPI) {
         exitStatus("Access_Error", "can't access \'$DumpAPI\'");
     }
+    
     my @DParts = split(/\s*,\s*/, $DumpAPI);
     foreach my $Part (@DParts)
     {
@@ -21834,7 +21973,7 @@
         if(not $CheckObjectsOnly) {
             searchForHeaders(1);
         }
-        $WORD_SIZE{1} = detectWordSize();
+        $WORD_SIZE{1} = detectWordSize(1);
     }
     if(not $Descriptor{1}{"Dump"})
     {
@@ -22456,7 +22595,7 @@
         if(not $CheckObjectsOnly) {
             searchForHeaders(1);
         }
-        $WORD_SIZE{1} = detectWordSize();
+        $WORD_SIZE{1} = detectWordSize(1);
     }
     if(not $Descriptor{2}{"Dump"})
     {
@@ -22469,7 +22608,7 @@
         if(not $CheckObjectsOnly) {
             searchForHeaders(2);
         }
-        $WORD_SIZE{2} = detectWordSize();
+        $WORD_SIZE{2} = detectWordSize(2);
     }
     if($WORD_SIZE{1} ne $WORD_SIZE{2})
     { # support for old ABI dumps