C++ Kernel: Undefined reference to __cxa_atexit
Posted: Sun Mar 20, 2011 3:31 pm
I've recently been developing a C++ kernel, which requires me to use a global object. I have defined __cxa_atexit, __dso_handle, and __cxa_pure_virtual in a file called icxxabi.c (basically copied the wiki source for it):
I've also made the required header:
I've included that in the preinit.cpp file which calls the main function of the kernel and does a __cxa_finalize(0) after it:
Yet for some reason, I still get this error even though I have __cxa_atexit defined:
I have icxxabi.o being linked before kernel.o and preinit.o, so I do not see why I am still getting this error.
Also,
Code: Select all
#ifdef _cplusplus
extern "C" {
#endif
#include "type.h"
#include "icxxabi.h"
void __cxa_pure_virtual() {
// Do Nothing
}
atexitFuncEntry_t __atexitFuncs[ATEXIT_FUNC_MAX];
uarch_t __atexitFuncCount = 0;
void *__dso_handle = 0;
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso){
if(__atexitFuncCount >= ATEXIT_FUNC_MAX){
return -1;
}
__atexitFuncs[__atexitFuncCount].destructorFunc = f;
__atexitFuncs[__atexitFuncCount].objPtr = objptr;
__atexitFuncs[__atexitFuncCount].dsoHandle = dso;
__atexitFuncCount++;
return 0;
}
void __cxa_finalize(void *f){
signed i = __atexitFuncCount;
if(!f){
while(i--){
if(__atexitFuncs[i].destructorFunc){
(*__atexitFuncs[i].destructorFunc)(__atexitFuncs[i].objPtr);
}
}
return;
}
for(; i >= 0; i--){
if(__atexitFuncs[i].destructorFunc == f){
(*__atexitFuncs[i].destructorFunc)(__atexitFuncs[i].objPtr);
__atexitFuncs[i].destructorFunc = 0;
}
}
}
#ifdef _cplusplus
};
#endif
Code: Select all
#ifndef ICXXABI_H_
#define ICXXABI_H_
#define ATEXIT_FUNC_MAX 128
#ifdef _cplusplus
extern "C" {
#endif
typedef unsigned uarch_t;
struct atexitFuncEntry_t {
void (*destructorFunc) (void *);
void *objPtr;
void *dsoHandle;
};
extern void *__dso_handle;
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso);
void __cxa_finalize(void *f);
void __cxa_pure_virtual();
#ifdef _cplusplus
};
#endif
#endif//ICXXABI_H_
Code: Select all
#include "icxxabi.h"
#include "kernel.h"
#include "type.h"
extern unsigned long ctorStart, ctorEnd; // Start and end of constructors
extern unsigned long dtorStart, dtorEnd; // Start and end of destructors
extern "C" void kernelPreinit(mbootHeader_t mbootHeader, u32int mbootMagic){
// Loop and call all the constructors
for(unsigned long *ctor(&ctorStart); ctor < &ctorEnd; ctor++){
((void (*) (void)) (*ctor))();
}
// Call the kernel main function
kernelMain((u32int)mbootMagic, mbootHeader);
// Loop and call all the destructors -- Not used after GCC 3.2, but shouldn't hurt anything
for(unsigned long *dtor(&dtorStart); dtor < &dtorEnd; dtor++){
((void (*) (void)) (*dtor))();
}
// Call __cxa_finalize to call all the destructors for after GCC 3.2
__cxa_finalize(0);
}
Code: Select all
kernel.o: In function `__static_initialization_and_destruction_0(int, int)':
kernel.cpp:(.text+0x233): undefined reference to `__cxa_atexit'
Also,
Code: Select all
$ i586-elf-gcc -v
Using built-in specs.
COLLECT_GCC=i586-elf-gcc
COLLECT_LTO_WRAPPER=/usr/local/cross/libexec/gcc/i586-elf/4.5.2/lto-wrapper.exe
Target: i586-elf
Configured with: ../gcc-4.5.2/configure --target=i586-elf --prefix=/usr/local/cr
oss --disable-nls --enable-languages=c,c++ --without-headers
Thread model: single
gcc version 4.5.2 (GCC)