sub readVtables()

in src/main/abi-symbols/abi-dumper.pl [1959:2054]


sub readVtables($)
{
    my $Path = $_[0];
    
    $Path = abs_path($Path);
    
    my $Dir = getDirname($Path);
    
    if(index($LIB_LANG, "C++")!=-1
    or $OBJ_LANG eq "C++")
    {
        printMsg("INFO", "Reading v-tables");
        
        if(checkCmd($VTABLE_DUMPER))
        {
            if(my $Version = `$VTABLE_DUMPER -dumpversion`)
            {
                if(cmpVersions($Version, $VTABLE_DUMPER_VERSION)<0)
                {
                    printMsg("ERROR", "the version of Vtable-Dumper should be $VTABLE_DUMPER_VERSION or newer");
                    return;
                }
            }
        }
        else
        {
            printMsg("ERROR", "cannot find \'$VTABLE_DUMPER\'");
            return;
        }
        
        my $ExtraPath = $TMP_DIR."/v-tables";
        
        if($ExtraInfo)
        {
            mkpath($ExtraInfo);
            $ExtraPath = $ExtraInfo."/v-tables";
        }
        
        my $LdPaths = $Dir;
        
        if(defined $LdLibraryPath) {
            $LdPaths .= ":".$LdLibraryPath;
        }
        
        system("LD_LIBRARY_PATH=\"$LdPaths\" $VTABLE_DUMPER -mangled -demangled \"$Path\" >\"$ExtraPath\"");
        
        my $Content = readFile($ExtraPath);
        foreach my $ClassInfo (split(/\n\n\n/, $Content))
        {
            if($ClassInfo=~/\AVtable\s+for\s+(.+)\n((.|\n)+)\Z/i)
            {
                my ($CName, $VTable) = ($1, $2);
                my @Entries = split(/\n/, $VTable);
                
                foreach (1 .. $#Entries)
                {
                    my $Entry = $Entries[$_];
                    if($Entry=~/\A(\d+)\s+(.+)\Z/) {
                        $VirtualTable{$CName}{$1} = $2;
                    }
                }

                if(defined $ExtraDump)
                {
                    if($Entries[0]=~/\A(\w+)\:/)
                    {
                        $VTable_Symbol{$CName} = $1;
                        $VTable_Class{$1} = $CName;
                    }
                }
            }
        }
    }
    
    if(keys(%VirtualTable))
    {
        foreach my $Tid (sort keys(%TypeInfo))
        {
            if($TypeInfo{$Tid}{"Type"}=~/\A(Struct|Class)\Z/)
            {
                my $TName = $TypeInfo{$Tid}{"Name"};
                $TName=~s/\bstruct //g;
                if(defined $VirtualTable{$TName})
                {
                    $TypeInfo{$Tid}{"VTable"} = $VirtualTable{$TName};

                    if(defined $ExtraDump)
                    {
                        $TypeInfo{$Tid}{"VTable_Sym"} = $VTable_Symbol{$TName};
                    }
                    $TypeInfo{$Tid}{"VTable"} = $VirtualTable{$TName};
                }
            }
        }
    }
}