520 likes | 653 Views
C++ internals. ou comprendre le C++ Par Thomas Sanchez Et Lionel Auroux. C ++ internals / Plan. La Surcharge Les namespaces Fonctions membres Héritage simple/multiple Méthodes dans un héritage simple/multiple Héritage base virtuelle Pointeur sur membre.
E N D
C++ internals ou comprendre le C++ Par Thomas Sanchez Et Lionel Auroux
C ++ internals / Plan La Surcharge Les namespaces Fonctions membres Héritage simple/multiple Méthodes dans un héritage simple/multiple Héritage base virtuelle Pointeur sur membre
Rappel en assembleur et calling convention x64 %registre $const X(%reg) == *(%reg + X) (%reg, X, Y) == *(reg + (X * Y)) mov %src, %dest mov{b,l,q} == mov byte (1octet), long (4 octets), quad-word (8 octets)
Rappel en assembleur et calling convention x64 • Registres: R{A,B,C,D}X, RDI, RSI, RBP, RSP, R8..15. • Si <= 6 paramètres: RDI, RSI, RDX, RCX, R8, R9. • Sinon paramètres poussés sur la pile
La surcharge my_putchar(char) my_strlen(char*) my_strcmp(char*, char*) my_strcmp(string, string)
La surcharge my_putchar my_strlen my_strcmp my_strcmp ELF
La surcharge _Z10my_putcharc _Z9my_strlenPc _Z9my_strcmpPcS_ _Z9my_strcmpRKSsS0_ ELF
Les namespaces _ZN9Namespace10my_putcharc _ZN9Namespace9my_strlenPc _ZN9Namespace9my_strcmpPcS_ _ZN9Namespace9my_strcmpRKSsS0_
Les fonctions membres inst.my_memberfunc(123) ; my_memberfunc(int param) this == &inst; *(int*)this == 123; this->p = param;
D’où vient le this ? Les fonctions membres struct Test { void test() {} }; int main() { Test t; t.test(); } Test t; t.test(); lea -0x1(%rbp),%rax mov %rax,%rdi callq 4008f4 <Test::test()>
Héritage simple Mère Fille
Héritage simple Fille Attributs Mère Mère Attributs Fille
Héritage simple Attributs Mère Attributs Fille Fille *inst = new Fille() ; inst == (Mere*)inst ;
Héritage multiple Mère Père Fille
Héritage multiple Mère Père Fille
Problématique d’accès Comment accéder aux données de Père ?
Problématique d’accès Mere* inst = new Fille; inst == dynamic_cast<Fille*>(inst); inst != dynamic_cast<Pere*>(inst);
Problématique d’accès Mère Méthode dans Mère Père Méthode dans Père Méthode dans Fille Fille
Problématique d’accès Un accès à une méthode de Père
Problématique d’accès Un accès à une méthode dans la seconde branche de l’héritage = recalcul d’adresse !
Héritage en diamant GrandMère Mère Père Fille
Héritage en diamant GrandMère GrandMère Mère Père Fille
Héritage en diamant GrandMère Mère GrandMère Père Fille
ou comment ça devient compliqué… LE VIRTUAL
Surcharge d'une fonction membre virtuelle dit « méthode » Mère virtual int meth(); Fille virtual int meth(); Fille* f = new Fille; Mere* m = new Fille; f->meth(); m->meth();
Surcharge de méthode Mère virtual int meth(); Virtual Table de Mère … [idx Mere::meth] Mere::meth
Surcharge de méthode Mère virtual int meth(); Virtual Table de Fille … Fille virtual int meth(); Mere::meth [idx Mere::meth] Fille::meth
Héritage simple Virtual Table de Fille VPTR Fille::meth Mère … Fille
Remarque intptr_t** vtable = *(intptr_t***)new Fille;
Héritage multiple Mère Père virtual int meth(); virtual int toto(); Fille virtual int meth(); virtual int toto();
Héritage multiple Virtual Table de Fille Mère virtual int meth(); Père virtual int toto(); Virtual Table de Père dans Fille Fille virtual int meth(); virtual int toto(); [idx Mere::meth] Mere::meth [idx Pere::toto] Pere:toto [idx Pere::toto] Pere::toto
Héritage multiple Virtual Table de Fille Mère virtual int meth(); Père virtual int toto(); Virtual Table de Père dans Fille Fille virtual int meth(); virtual int toto(); [idx Mere::meth] Fille::meth [idx Pere::toto] Fille:toto [idx Pere::toto] Fille::toto
Héritage multiple VPTR Virtual Table de Fille Mère VPTR Virtual Table de Pere hérité dans Fille Père Fille
Les préfixes de VTable VTable Préfixe Décalage vers classe concrète Instance typeinfo Virtual Table Pointeurs ptr1 ptr1 ptr2 ptr2 … … VPTR
Remarque intptr_t** vtable = *(intptr_t***)new Fille; intptr_t* typeinfo_ptr = vtable[-1]; size_t offset = (size_t) vtable[-2]; Voir: gcc-src/libstdc++-v3/libsupc++/tinfo.h
Héritage multiple VPTR Mère VPTR2 Père Fille Décalage dans la 2ème VTable
Thunk function Mère Père virtual int meth(); virtual int toto(); Fille virtual int meth(); virtual int toto();
Thunk function Pere* p = new Fille; p->toto();
Thunk function Mère virtual int meth(); VTable de Père Dans Fille Père Fille::toto virtual int toto(); Fille virtual int meth(); virtual int toto(); VTable de Fille
Thunk function Mère virtual int meth(); VTable de Père Dans Fille thunk… Père Fille::toto Aligne this virtual int toto(); jump Fille::toto Fille virtual int meth(); virtual int toto(); VTable de Fille thunk_func_pere_to_fille
Héritage en diamant GrandMère Mère Père Fille
Héritage en diamant GrandMère GrandMère VIRTUAL Mère Père Fille
Héritage en diamant VPTR VPTR GrandMère Mère Mère VPTR Père VPTR Fille GrandMère VPTR Père GrandMère Fille
Héritage en diamant Vtable de GrandMere Préfixe Pointeurs Décalage vers 2 Décalage vers 1
Héritage en diamant VPTR Mère VPTR Père Fille VPTR GrandMère Décalage vers 1 Décalage vers 2
Pointeur sur membre Pointeur sur membre = 16octets
Pointeur sur membre Index dans la VTable 1 0 Adresse de la fonction membre
Pointeur sur membre Aligne “this” Index dans la VTable 1 0 Adresse de la fonction membre Aligne “this”