crt*.o Problem - Ctors not being called
Posted: Fri Feb 23, 2018 1:30 am
I have been working on the C++ runtime in my kernel, and trying to call the global object constructors. I have built the i386-elf GCC cross-compiler for C,C++ so that I could use its crtbegin.o and crtend.o objects. Note that I am testing the crt*.o features only one module in the kernel - HAL (hardware abstraction layer). The compiler refused to link with my old linker.ld scripts - first section in dynamic segment not .dynamic sort of error was given. So I just gave up the linker script because I thought the modules didn't need them (except the KernelHost, which is the executable file which starts up the system and is a PIE).
I linked the object in the correct sequence,
But the _init() function in HAL/Build/kernel.silcos.hal didn't call the constructors somehow. Even when the KernelHost's module-loader code called the DT_INIT tag, the constructors weren't being called. To look into the matter I disassembled the whole module - (I have shown only the _init part, the TerminalOuput.txt in root folder has all of it)
You can see the hello() relocation here because I wrote it as a constructor - __attribute__((constructor)) (in HAL/Source/Processor.cpp) but it doesn't print "hello" (whatever is there). Calling _init() doesn't do the work. What is the hecking problem?
Few other notes:
1. I had to implement the functions below because of "undefined symbols" (weak symbols). Note that my ELF dynamic-linker (in the KernelHost module, which is actually a PIE) links the other modules. But my HAL module had undefined references to these functions.
_ITM_deregisterTMCCloneTable & _ITM_register_TMCCloneTable were also undefined. But I just linked the referenced with my LinkerUndefined() function by which I could trap calls to them. But only the __register_frame_info() function was being called.
These are for C++ exception support, right. I use --fno-exceptions; why did these symbols arise?
2. My kernel source - https://github.com/SukantPal/Silcos-Kernel
Goto KernelHost/Source/ModuleLoader for the module-loader. You'll find the ElfLinker.cpp file which has these "undefined" functions implemented.
I linked the object in the correct sequence,
Code: Select all
crti.o, crtbegin.o, All Kernel Objects, -lgcc, crtend.o, crtend.o
Code: Select all
0000438c <_init>:
438c: 55 push ebp
438d: 89 e5 mov ebp,esp
438f: e8 90 0d 00 00 call 5124 <hello+0xf4>
4394: e8 93 56 00 00 call 9a2c <SetupTSS+0x80>
4399: 5d pop ebp
439a: c3 ret
Few other notes:
1. I had to implement the functions below because of "undefined symbols" (weak symbols). Note that my ELF dynamic-linker (in the KernelHost module, which is actually a PIE) links the other modules. But my HAL module had undefined references to these functions.
Code: Select all
///
/// After looking around on the internet, I found them in the C library code. Just copied them from there
/// cause the comments said they were for initialization and really didn't need to do anything.
///
extern "C" void __register_frame_info(void*,struct object*){}
extern "C" void __register_frame_info_bases(void *a1, struct object *a2, void *a3, void *a4);
extern "C" void* __deregister_frame_info(void*){ return (null); }
These are for C++ exception support, right. I use --fno-exceptions; why did these symbols arise?
2. My kernel source - https://github.com/SukantPal/Silcos-Kernel
Goto KernelHost/Source/ModuleLoader for the module-loader. You'll find the ElfLinker.cpp file which has these "undefined" functions implemented.