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};
}
}
}
}
}