c++虚函数表汇编及内存布局分析(基于gdb)(五)
#include <iostream> class Base { public: void NormalShow() { std::cout<<"Base Normal show"<<std::endl; } static void StaticNormalShow() { std::cout<<"Base StaticNormalShow show"<<std::endl; } virtual void Show() { std::cout<<"Base show"<<std::endl; } int b1; }; class Derive: public Base { public: void NormalShow() { std::cout<<"Derive Normal show"<<std::endl; } static void StaticNormalShow() { std::cout<<"Derive StaticNormalShow show"<<std::endl; } void Show() { std::cout<<"Derive show"<<std::endl; } int d1; }; int main() { Base *b_ptr = new Derive(); b_ptr->Show(); (*b_ptr).Show(); b_ptr->Base::Show(); b_ptr->NormalShow(); (*b_ptr).NormalShow(); b_ptr->Base::NormalShow(); Base::StaticNormalShow(); Derive::StaticNormalShow(); return 0;
45 Base *b_ptr = new Derive(); (gdb) info line memory_layout.cpp:18 Line 18 of "/home/tzy/work/tzy/project/cpp_code/slambook/cpp/memory_layout.cpp" starts at address 0x400aaa <Base::Show()> and ends at 0x400ab6 <Base::Show()+12>. 400aaa为基类函数show地址 (gdb) print Base::Show() Cannot resolve method Base::Show to any overloaded instance (gdb) set print object on 查看当前对象的真实类别 (gdb) p b_ptr $1 = (Derive *) 0x2264c20 (gdb) p *b_ptr $2 = (Derive) {<Base> = {_vptr.Base = 0x400c68 <vtable for Derive+16>, b1 = 0}, d1 = 0} 虚函数表位置400c68,应该位于rodata,即为全局数据区(静态区) (gdb) p /a *(void**)0x400c68@2 查看对象里面的虚指针,显示指针指向的内容
$5 = {0x400af8 <Derive::Show()>, 0x0}
(gdb) p /a *((void**)0x400c68-1) 查看虚表的前面,会发现g++实现的时候将RTTI信息放到虚函数表的前面一点点了。反汇编查看代码其实也可以发现的,typeid会根据虚表指针偏移一下去找RTTI信息。
$6 = 0x400c88 <typeinfo for Derive>
objdump memory_layout -x memory_layout: file format elf64-x86-64 memory_layout architecture: i386:x86-64, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x0000000000400870 Program Header: PHDR off 0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3 filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x INTERP off 0x0000000000000238 vaddr 0x0000000000400238 paddr 0x0000000000400238 align 2**0 filesz 0x000000000000001c memsz 0x000000000000001c flags r-- LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21 filesz 0x0000000000000f5c memsz 0x0000000000000f5c flags r-x LOAD off 0x0000000000001df8 vaddr 0x0000000000601df8 paddr 0x0000000000601df8 align 2**21 filesz 0x0000000000000270 memsz 0x0000000000000458 flags rw- DYNAMIC off 0x0000000000001e18 vaddr 0x0000000000601e18 paddr 0x0000000000601e18 align 2**3 filesz 0x00000000000001e0 memsz 0x00000000000001e0 flags rw- NOTE off 0x0000000000000254 vaddr 0x0000000000400254 paddr 0x0000000000400254 align 2**2 filesz 0x0000000000000044 memsz 0x0000000000000044 flags r-- EH_FRAME off 0x0000000000000cc0 vaddr 0x0000000000400cc0 paddr 0x0000000000400cc0 align 2**2 filesz 0x000000000000007c memsz 0x000000000000007c flags r-- STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4 filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- RELRO off 0x0000000000001df8 vaddr 0x0000000000601df8 paddr 0x0000000000601df8 align 2**0 filesz 0x0000000000000208 memsz 0x0000000000000208 flags r-- Dynamic Section: NEEDED libstdc++.so.6 NEEDED libc.so.6 INIT 0x00000000004007a8 FINI 0x0000000000400be4 INIT_ARRAY 0x0000000000601df8 INIT_ARRAYSZ 0x0000000000000010 FINI_ARRAY 0x0000000000601e08 FINI_ARRAYSZ 0x0000000000000008 GNU_HASH 0x0000000000400298 STRTAB 0x0000000000400450 SYMTAB 0x00000000004002d0 STRSZ 0x00000000000001c8 SYMENT 0x0000000000000018 DEBUG 0x0000000000000000 PLTGOT 0x0000000000602000 PLTRELSZ 0x00000000000000c0 PLTREL 0x0000000000000007 JMPREL 0x00000000004006e8 RELA 0x0000000000400688 RELASZ 0x0000000000000060 RELAENT 0x0000000000000018 VERNEED 0x0000000000400638 VERNEEDNUM 0x0000000000000002 VERSYM 0x0000000000400618 Version References: required from libc.so.6: 0x09691a75 0x00 03 GLIBC_2.2.5 required from libstdc++.so.6: 0x056bafd3 0x00 04 CXXABI_1.3 0x08922974 0x00 02 GLIBCXX_3.4 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.gnu.build-id 00000024 0000000000400274 0000000000400274 00000274 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.hash 00000038 0000000000400298 0000000000400298 00000298 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .dynsym 00000180 00000000004002d0 00000000004002d0 000002d0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynstr 000001c8 0000000000400450 0000000000400450 00000450 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .gnu.version 00000020 0000000000400618 0000000000400618 00000618 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version_r 00000050 0000000000400638 0000000000400638 00000638 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .rela.dyn 00000060 0000000000400688 0000000000400688 00000688 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.plt 000000c0 00000000004006e8 00000000004006e8 000006e8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .init 0000001a 00000000004007a8 00000000004007a8 000007a8 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 11 .plt 00000090 00000000004007d0 00000000004007d0 000007d0 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .plt.got 00000008 0000000000400860 0000000000400860 00000860 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .text 00000372 0000000000400870 0000000000400870 00000870 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 14 .fini 00000009 0000000000400be4 0000000000400be4 00000be4 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 15 .rodata 000000ce 0000000000400bf0 0000000000400bf0 00000bf0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 16 .eh_frame_hdr 0000007c 0000000000400cc0 0000000000400cc0 00000cc0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 17 .eh_frame 0000021c 0000000000400d40 0000000000400d40 00000d40 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 18 .init_array 00000010 0000000000601df8 0000000000601df8 00001df8 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .fini_array 00000008 0000000000601e08 0000000000601e08 00001e08 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .jcr 00000008 0000000000601e10 0000000000601e10 00001e10 2**3 CONTENTS, ALLOC, LOAD, DATA 21 .dynamic 000001e0 0000000000601e18 0000000000601e18 00001e18 2**3 CONTENTS, ALLOC, LOAD, DATA 22 .got 00000008 0000000000601ff8 0000000000601ff8 00001ff8 2**3 CONTENTS, ALLOC, LOAD, DATA 23 .got.plt 00000058 0000000000602000 0000000000602000 00002000 2**3 CONTENTS, ALLOC, LOAD, DATA 24 .data 00000010 0000000000602058 0000000000602058 00002058 2**3 CONTENTS, ALLOC, LOAD, DATA 25 .bss 000001d0 0000000000602080 0000000000602080 00002068 2**5 ALLOC 26 .comment 00000035 0000000000000000 0000000000000000 00002068 2**0 CONTENTS, READONLY 27 .debug_aranges 000000a0 0000000000000000 0000000000000000 0000209d 2**0 CONTENTS, READONLY, DEBUGGING 28 .debug_info 000029a5 0000000000000000 0000000000000000 0000213d 2**0 CONTENTS, READONLY, DEBUGGING 29 .debug_abbrev 0000064e 0000000000000000 0000000000000000 00004ae2 2**0 CONTENTS, READONLY, DEBUGGING 30 .debug_line 000003d1 0000000000000000 0000000000000000 00005130 2**0 CONTENTS, READONLY, DEBUGGING 31 .debug_str 000018be 0000000000000000 0000000000000000 00005501 2**0 CONTENTS, READONLY, DEBUGGING 32 .debug_ranges 00000090 0000000000000000 0000000000000000 00006dbf 2**0 CONTENTS, READONLY, DEBUGGING SYMBOL TABLE: 0000000000400238 l d .interp 0000000000000000 .interp 0000000000400254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag 0000000000400274 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id 0000000000400298 l d .gnu.hash 0000000000000000 .gnu.hash 00000000004002d0 l d .dynsym 0000000000000000 .dynsym 0000000000400450 l d .dynstr 0000000000000000 .dynstr 0000000000400618 l d .gnu.version 0000000000000000 .gnu.version 0000000000400638 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000400688 l d .rela.dyn 0000000000000000 .rela.dyn 00000000004006e8 l d .rela.plt 0000000000000000 .rela.plt 00000000004007a8 l d .init 0000000000000000 .init 00000000004007d0 l d .plt 0000000000000000 .plt 0000000000400860 l d .plt.got 0000000000000000 .plt.got 0000000000400870 l d .text 0000000000000000 .text 0000000000400be4 l d .fini 0000000000000000 .fini 0000000000400bf0 l d .rodata 0000000000000000 .rodata 0000000000400cc0 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr 0000000000400d40 l d .eh_frame 0000000000000000 .eh_frame 0000000000601df8 l d .init_array 0000000000000000 .init_array 0000000000601e08 l d .fini_array 0000000000000000 .fini_array 0000000000601e10 l d .jcr 0000000000000000 .jcr 0000000000601e18 l d .dynamic 0000000000000000 .dynamic 0000000000601ff8 l d .got 0000000000000000 .got 0000000000602000 l d .got.plt 0000000000000000 .got.plt 0000000000602058 l d .data 0000000000000000 .data 0000000000602080 l d .bss 0000000000000000 .bss 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges 0000000000000000 l d .debug_info 0000000000000000 .debug_info 0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev 0000000000000000 l d .debug_line 0000000000000000 .debug_line 0000000000000000 l d .debug_str 0000000000000000 .debug_str 0000000000000000 l d .debug_ranges 0000000000000000 .debug_ranges 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 0000000000601e10 l O .jcr 0000000000000000 __JCR_LIST__ 00000000004008a0 l F .text 0000000000000000 deregister_tm_clones 00000000004008e0 l F .text 0000000000000000 register_tm_clones 0000000000400920 l F .text 0000000000000000 __do_global_dtors_aux 0000000000602248 l O .bss 0000000000000001 completed.7594 0000000000601e08 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry 0000000000400940 l F .text 0000000000000000 frame_dummy 0000000000601df8 l O .init_array 0000000000000000 __frame_dummy_init_array_entry 0000000000000000 l df *ABS* 0000000000000000 memory_layout.cpp 0000000000400bf4 l O .rodata 0000000000000001 _ZStL19piecewise_construct 0000000000602249 l O .bss 0000000000000001 _ZStL8__ioinit 0000000000400a09 l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii 0000000000400a47 l F .text 0000000000000015 _GLOBAL__sub_I_main 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 0000000000400f58 l O .eh_frame 0000000000000000 __FRAME_END__ 0000000000601e10 l O .jcr 0000000000000000 __JCR_END__ 0000000000000000 l df *ABS* 0000000000000000 0000000000400cc0 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR 0000000000602000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000601e08 l .init_array 0000000000000000 __init_array_end 0000000000601df8 l .init_array 0000000000000000 __init_array_start 0000000000601e18 l O .dynamic 0000000000000000 _DYNAMIC 0000000000602058 w .data 0000000000000000 data_start 0000000000400be0 g F .text 0000000000000002 __libc_csu_fini 0000000000400870 g F .text 000000000000002a _start 0000000000000000 w *UND* 0000000000000000 __gmon_start__ 0000000000000000 w *UND* 0000000000000000 _Jv_RegisterClasses 0000000000400aaa w F .text 000000000000002b _ZN4Base4ShowEv 0000000000400be4 g F .fini 0000000000000000 _fini 0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4 0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5 0000000000400af8 w F .text 000000000000002b _ZN6Derive4ShowEv 0000000000400ad5 w F .text 0000000000000023 _ZN6Derive16StaticNormalShowEv 0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.5 0000000000400b3c w F .text 0000000000000027 _ZN6DeriveC1Ev 0000000000400810 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4 0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable 0000000000000000 F *UND* 0000000000000000 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4 0000000000400bf0 g O .rodata 0000000000000004 _IO_stdin_used 0000000000400b24 w F .text 0000000000000017 _ZN4BaseC1Ev 0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable 0000000000602058 g .data 0000000000000000 __data_start 0000000000602080 w O .bss 0000000000000058 _ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 0000000000602068 g O .data 0000000000000000 .hidden __TMC_END__ 00000000006020e0 g O .bss 0000000000000110 _ZSt4cout@@GLIBCXX_3.4 0000000000602060 g O .data 0000000000000000 .hidden __dso_handle 0000000000400b70 g F .text 0000000000000065 __libc_csu_init 0000000000400cb8 w O .rodata 0000000000000006 _ZTS4Base 0000000000602068 g .bss 0000000000000000 __bss_start 0000000000400ca8 w O .rodata 0000000000000010 _ZTI4Base 00000000006021f0 w O .bss 0000000000000058 _ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 0000000000400a5c w F .text 000000000000002b _ZN4Base10NormalShowEv 0000000000400a87 w F .text 0000000000000023 _ZN4Base16StaticNormalShowEv 0000000000602250 g .bss 0000000000000000 _end 0000000000000000 F *UND* 0000000000000000 _ZNSolsEPFRSoS_E@@GLIBCXX_3.4 0000000000400c88 w O .rodata 0000000000000018 _ZTI6Derive 0000000000400b24 w F .text 0000000000000017 _ZN4BaseC2Ev 0000000000400840 F *UND* 0000000000000000 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 0000000000400c70 w O .rodata 0000000000000018 _ZTV4Base 0000000000602068 g .data 0000000000000000 _edata 0000000000000000 F *UND* 0000000000000000 _Znwm@@GLIBCXX_3.4 0000000000400b3c w F .text 0000000000000027 _ZN6DeriveC2Ev 0000000000400ca0 w O .rodata 0000000000000008 _ZTS6Derive 0000000000400966 g F .text 00000000000000a3 main 00000000004007a8 g F .init 0000000000000000 _init 0000000000400c58 w O .rodata 0000000000000018 _ZTV6Derive
readelf memory_layout -a ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x400870 Start of program headers: 64 (bytes into file) Start of section headers: 32296 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 9 Size of section headers: 64 (bytes) Number of section headers: 37 Section header string table index: 34 Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000400238 00000238 000000000000001c 0000000000000000 A 0 0 1 [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 0000000000000020 0000000000000000 A 0 0 4 [ 3] .note.gnu.build-i NOTE 0000000000400274 00000274 0000000000000024 0000000000000000 A 0 0 4 [ 4] .gnu.hash GNU_HASH 0000000000400298 00000298 0000000000000038 0000000000000000 A 5 0 8 [ 5] .dynsym DYNSYM 00000000004002d0 000002d0 0000000000000180 0000000000000018 A 6 1 8 [ 6] .dynstr STRTAB 0000000000400450 00000450 00000000000001c8 0000000000000000 A 0 0 1 [ 7] .gnu.version VERSYM 0000000000400618 00000618 0000000000000020 0000000000000002 A 5 0 2 [ 8] .gnu.version_r VERNEED 0000000000400638 00000638 0000000000000050 0000000000000000 A 6 2 8 [ 9] .rela.dyn RELA 0000000000400688 00000688 0000000000000060 0000000000000018 A 5 0 8 [10] .rela.plt RELA 00000000004006e8 000006e8 00000000000000c0 0000000000000018 AI 5 24 8 [11] .init PROGBITS 00000000004007a8 000007a8 000000000000001a 0000000000000000 AX 0 0 4 [12] .plt PROGBITS 00000000004007d0 000007d0 0000000000000090 0000000000000010 AX 0 0 16 [13] .plt.got PROGBITS 0000000000400860 00000860 0000000000000008 0000000000000000 AX 0 0 8 [14] .text PROGBITS 0000000000400870 00000870 0000000000000372 0000000000000000 AX 0 0 16 [15] .fini PROGBITS 0000000000400be4 00000be4 0000000000000009 0000000000000000 AX 0 0 4 [16] .rodata PROGBITS 0000000000400bf0 00000bf0 00000000000000ce 0000000000000000 A 0 0 8 [17] .eh_frame_hdr PROGBITS 0000000000400cc0 00000cc0 000000000000007c 0000000000000000 A 0 0 4 [18] .eh_frame PROGBITS 0000000000400d40 00000d40 000000000000021c 0000000000000000 A 0 0 8 [19] .init_array INIT_ARRAY 0000000000601df8 00001df8 0000000000000010 0000000000000000 WA 0 0 8 [20] .fini_array FINI_ARRAY 0000000000601e08 00001e08 0000000000000008 0000000000000000 WA 0 0 8 [21] .jcr PROGBITS 0000000000601e10 00001e10 0000000000000008 0000000000000000 WA 0 0 8 [22] .dynamic DYNAMIC 0000000000601e18 00001e18 00000000000001e0 0000000000000010 WA 6 0 8 [23] .got PROGBITS 0000000000601ff8 00001ff8 0000000000000008 0000000000000008 WA 0 0 8 [24] .got.plt PROGBITS 0000000000602000 00002000 0000000000000058 0000000000000008 WA 0 0 8 [25] .data PROGBITS 0000000000602058 00002058 0000000000000010 0000000000000000 WA 0 0 8 [26] .bss NOBITS 0000000000602080 00002068 00000000000001d0 0000000000000000 WA 0 0 32 [27] .comment PROGBITS 0000000000000000 00002068 0000000000000035 0000000000000001 MS 0 0 1 [28] .debug_aranges PROGBITS 0000000000000000 0000209d 00000000000000a0 0000000000000000 0 0 1 [29] .debug_info PROGBITS 0000000000000000 0000213d 00000000000029a5 0000000000000000 0 0 1 [30] .debug_abbrev PROGBITS 0000000000000000 00004ae2 000000000000064e 0000000000000000 0 0 1 [31] .debug_line PROGBITS 0000000000000000 00005130 00000000000003d1 0000000000000000 0 0 1 [32] .debug_str PROGBITS 0000000000000000 00005501 00000000000018be 0000000000000001 MS 0 0 1 [33] .debug_ranges PROGBITS 0000000000000000 00006dbf 0000000000000090 0000000000000000 0 0 1 [34] .shstrtab STRTAB 0000000000000000 00007ccc 000000000000015a 0000000000000000 0 0 1 [35] .symtab SYMTAB 0000000000000000 00006e50 0000000000000978 0000000000000018 36 57 8 [36] .strtab STRTAB 0000000000000000 000077c8 0000000000000504 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)
参考链接:
(15条消息) 查看虚函数表_愿世界和平的IT劝退师-CSDN博客
虚函数表存放在哪里 - chenhuan001 - 博客园 (cnblogs.com)