ご存知のように、仮想関数テーブル ポインターは通常、インスタンスの最初の 4 バイトに格納されます。しかし、指定された ELF ファイルのどこに仮想関数テーブルが格納されているのか、非常に興味があります。テスト用に以下のプログラムを書き、readelf -s a.out
コマンドでELFファイルのシンボルテーブルを取得したのですが、「vtable」とかそういうのが見つかりません。
#include <iostream>
#include <stdio.h>
using namespace std;
typedef void (*fun_pointer)(void);
class Test
{
public:
Test()
{
cout<<"Test()."<<endl;
}
virtual void print()
{
cout<<"Test::Virtual void print()."<<endl;
}
virtual void print2()
{
cout<<"Test::Virtual void print2()."<<endl;
}
};
class TestDrived:public Test
{
public:
TestDrived()
{
cout<<"TestDrived()."<<endl;
}
virtual void print()
{
cout<<"TestDrived::virtual void print()."<<endl;
}
virtual void print2()
{
cout<<"TestDrived::virutual void print2()."<<endl;
}
void GetVtblAddress()
{
cout<<"vtbl address:"<<(int*)this<<endl;
}
void GetFirstVtblFunctionAddress(void)
{
cout<<"First function address in vtbl:"<< (int*)*(int*)this+0;
}
void GetSecondVtblFunctionAddress(void)
{
cout<<"First function address in vtbl:"<< (int*)*(int*)this+2<<endl; //my os is 64bit //linux, if you use 32bit OS, please replace the "this+2" with "this+1"
}
void CallFirstVtblFunction()
{
fun = (fun_pointer)* ( (int*)*(int*)this+0 );
fun();
}
void CallSecondVtblFunction()
{
fun = (fun_pointer)* ( (int*)*(int*)this+2 ); //my os is 64bit
//linux, if you use 32bit OS, please replace the "this+2" with "this+1"
fun();
}
private:
fun_pointer fun;
};
int main()
{
cout<<"sizeof(int):"<<sizeof(int)<<"sizeof(int*)"<<endl<<sizeof(int*)<<endl;
fun_pointer fun = NULL;
TestDrived a;
a.GetVtblAddress();
a.GetFirstVtblFunctionAddress();
a.GetSecondVtblFunctionAddress();
a.CallFirstVtblFunction();
a.CallSecondVtblFunction();
return 0;
}