Page 1 of 1

DTORS

Posted: Fri Jul 02, 2004 11:00 pm
by prabuinet
I'm using the g++ that came with RH linux 8.

I had wrote my runtime support for constructors.
My Problem is with the Desctructors.

I can't add the Destructor for the Global Object classes.
If i put a destructor. I get some error in linking.

" undefined symbols. __dso_handle and __cxa_atexit "
__dso_handle is in data section.
__cxa_atexit may be a function.

I found this after doing some search in the "libc" with "objdump"

when I dump my kernel i cant found any .dtors section.

I just defined a variable and a dummy function as
extern "C" {
void *__dso_handle;
void __cxa_atexit() {

}
}

Now my linker is cheated by me.

BUT BUT BUT. HOW can I handle it properly.

When and how my destructors can be called without a .dtors section.

help me please...
thank you.

RE:DTORS

Posted: Wed Jul 07, 2004 11:00 pm
by bregmasoft
> I can't add the Destructor for the Global Object classes.
> If i put a destructor. I get some error in linking.
>
> " undefined symbols. __dso_handle and __cxa_atexit "
> __dso_handle is in data section.
> __cxa_atexit may be a function.

You don't have to worry about __dso_handle until you're doing dynamic linking.  It has nothing to do with the C++ runtime.  Just make sure the symbol exists (it doesn't have to be dereferencable).  What you did is fine.

The global constructor driver emitted by the compiler will attempt to register a special callback through __cxa_atexit() to run the global destructors at process exit time.  You will either have to provide a working __cxa_atexit() (examples shouldn't be hard to find) or just ignore the whole mess by supplying an empty function (as you've done) since it's only invoked when your kernel is shutting down anyways.

To get everything working, you'll need to write a C++ runtime initialization prologue and epilogue in assembly, and do some fancy-pants dancing in your linker script.  Here's an excerpt from my linker script.

/*
* Initialization code.
*/
.init :
{
    KEEP(*cppruntimeinit.o(.prologue))
    KEEP(*(.init))
    KEEP(*cppruntimeinit.o(.epilogue))
}

/*
* Global object constructor and destructor entry point lists.
*/
.ctors :
{
    KEEP(*crtbegin*.o(.ctors))
    KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors))
    KEEP(*(.ctors))
}
.dtors :
{
    KEEP(*crtbegin*.o(.dtors))
    KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors))
    KEEP(*(.dtors))
}

The .ctors and .dtors sections are just data:  they're lists of function entry points called by the code emitted by the compiler and run by the .init section code (for constructors) and the __cxa_atexit() function (for destructors).