C ++ compiler retrieves the specific method of VTABLE

zhaozj2021-02-08  195

I haven't told this problem before, I only know that the C code calls a virtual function to find the virtual function table and then perform a specific function. It was found that the implementation method of this retrieval operation was found to be in the process of tune the procedure for two days.

Early GCC (May 2001?) Is a more intuitive check table method. The pointer to the member function in the GCC is actually a structure, similar to the earliest CFRONT compiler:

Struct {??? short __delta; ??? short __index; ??? union ??? {??????? void * __pfn; ??????? short _delta2; ???} _pfn_or_delta2;} ;

If you point to the non-virtual member function, the actual function pointer in the memory is saved in the __ PFN. If you point to the virtual member function, __ pfn is invalid, __ index is the index of the function in the virtual function table. When you call the virtual function, based on the address and index of the virtual function table, check the specific function address.

Subsequent version of GCC is constantly improving the retrieval method of this virtual function table (which is more subsequent GCC has more changes to C ABI), and now GCC 3.3.3 source code, GCC / CP / CP-Tree.h, etc. The file contains related code. But now the implementation code is more complicated, I have not fully understood.

The implementation of VC is very different from this. VC generates a vCall code for each virtual function on a inherited tree (can be seen as a small intermedifier), depending on the offset in the virtual function table, Eax is eax according to each virtual function. The increased offset is different. This is actually a fast check-in mechanism, and Inexing can be called to a specific function without the index of the legendary function table.

`vcall ': 00401010? MOV ???????? eax, dword PTR [ECX] 00401012? JMP ??????? DWord PTR [EAX]` vcall': 00401020? MOV ????? ??? eax, dword ptr [ECX] 00401022? jmp ???????? DWORD PTR [EAX 4] `vcall ': 00401030? MOV ???????? eax, dword PTR [ECX] 00401032? JMP ???????? DWORD PTR [EAX 8] `vcall ': 00401040? MOV ???????? eax, dword PTR [ECX] 00401042? JMP ??????? DWORD PTR [EAX 0CH]

When calling, the same name virtual function (whether the function belongs to a class), is the same vcall, but when calling different types of virtual functions, the virtual function table of the incoming VCALL is different (below the C2 class below) Class C1 derived class, F1 and F2 are virtual functions).

& C1 :: F1 - Offset `vcall '(401010H) & C1 :: F2 - Offset` vcall' (401020H) & C2 :: F1 - Offset `vcall '(401010H) & C2 :: F2 - Offset` vcall' 401020H)


New Post(0)