For C++ nonstatic member functions (methods), the first slot in the stack frame is reserved for the hidden pointer this.
hello.o: file format coff-go32 Disassembly of section .text: 00000000 <.text>: 00000008 <_greet__Fv>: int greet(void) { cout << "hello" << endl; return 0; } 8: 55 push %ebp 9: 89 e5 mov %esp,%ebp b: 83 ec 08 sub $0x8,%esp e: 83 c4 f8 add $0xfffffff8,%espgreet has become _greet__Fv
Note that there is no standard for name-mangling -- different compilers and different versions of the same compiler do it differently.
Name-mangling can be turned off for external C or asm functions by declaring prototypes for those functions with C linkage:
extern "C" void foo(void); extern "C" { extern int errno; void exit(int status); int putchar(int c); };The GCC binutils for C++ contain a utility called c++filt (or, for DJGPP, cxxfilt) which demangles C++ symbol names:
C:\tmp>nm test.cof 00000000 a .absolut ... 00001130 T __ZdlPv 00001140 T __ZdaPv 00001150 T _main ... 00005ad0 N .comment C:\tmp>echo __ZdaPv | cxxfilt operator delete[](void*)nm -C ... will also display de-mangled symbol names.
void *operator new(size_t size); /* wrapper around calloc() */ void *operator new[](size_t size); /* wrapper around calloc() */ void operator delete(void *arg); /* wrapper around free() */ void operator delete[](void *arg); /* wrapper around free() */These must be compiled as C++. Do not bracket them with extern "C" { ... };. Maybe compile with "-fno-builtin" too, so GCC doesn't try to use it's own versions of these functions. Defining these functions like this:
void *__builtin_new(unsigned long a); void __builtin_delete(void *p); etc.works only with GCC 2.x
The kernel linker script can simply copy the .ctors and .dtors sections to the output (executable) file, or it can combine these sections with .data, .rodata, or even .text. Labels should be defined in the linker script to mark the start and end of these sections.
In older (2.x) versions of GCC, the section names ".ctor" and ".dtor" were used instead of ".ctors" and ".dtors". Maybe use a wildcard for these names in your linker script.
The constructors should be called from the kernel startup code. They can also be called from main() before accessing global or static local objects (see example linker script below).
If you don't use C++ structured exception handling (try, catch, throw), compile with "gcc -fno-exceptions ...". Otherwise, you will get undefined symbols at link time.
Unless you need it, turn off run-time type information by compiling with "gcc -fno-rtti ...". Otherwise, you will get undefined symbols at link time.
ENTRY(entry) SECTIONS { /* use ld -Ttext=nnn ... to set starting virtual address */ .text : { g_code = .; _g_code = .; /* symbols to mark start of section */ /* code */ *(.text*) /* wildcard for "gcc -ffunction-sections" */ *(.gnu.linkonce.t.*) /* C++ templates? */ *(.rodata*) /* read-only data (ELF only) */ *(.gnu.linkonce.r.*) /* C++ static constructors and destructors */ start_ctors = .; *(SORT(.ctor*)) end_ctors = .; /* accessed from asm code only... */ start_dtors = .; /* ...so no leading underscore */ *(SORT(.dtor*)) end_dtors = .; . = ALIGN(4096); } .data : { g_data = .; _g_data = .; /* data */ *(.data*) /* wildcard for "gcc -fdata-sections" */ *(.gnu.linkonce.d.*) . = ALIGN(4096); } .bss : { g_bss = .; _g_bss = .; /* BSS */ *(.bss*) /* wildcard for "gcc -fdata-sections" */ *(.gnu.linkonce.b.*) *(COMMON) /* "common" variables */ . = ALIGN(4096); } g_end = .; _g_end = .; /* MinGW debug sections Omit these and you may get an invalid executable file */ .stab : { *(.stab) } .stabstr : { *(.stabstr) } }Assembly-language startup code to call the static constructors before calling main() (assuming the linker script shown above):
mov $start_ctors,%ebx jmp 2f .1: call *(%ebx) add $4,%ebx .2: cmp $end_ctors,%ebx jb 1bConstructors can also be called from main(), but before accessing global or static local objects.
- how to declare pure_virtual(void) ? - say "ld --verbose" and check built-in linker script for details...varies between DJGPP, MinGW, and Linux - Strange sections seen in MinGW linker script: .text$* .data$* .glue_7t .glue_7 - RTTI? - C++ exceptions? - making static constructor code discardable?