This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
initializing eh
- To: GCC Mailing List <gcc at gcc dot gnu dot org>
- Subject: initializing eh
- From: Olaf Petzold <opetzold at wit dot regiocom dot net>
- Date: Thu, 1 Mar 2001 09:31:09 +0100
- Cc: libstdc++ at gcc dot gnu dot org
Hello,
some days ago I asked how to initialize the eh for linux kernel. I ripped the
according files (libgcc2.c etc.) from the gcc-2.95.2 dist and from crtstuff.c.
Linux is using elf and dwarf. The problem I can call global C/DTors and can
throw exception but not catch the exceptions. It seems the secrte is related in
the .ini / .fini section of the elf ABI. Anyway, attached is the rewritten
crtstuff for use on linux kernel modules. The linux kernel module loader is
ignoring all elf section - its loading a simple binary archive an locking for
the function symbols int init_module(void) and void cleanup_module(void) and
executes that code. Therefore I have to call the ".init" section in
init_module and the ".fini" section in cleanup_module explicit.
---- kernel_module.c ---
[...] // global class and def. Module
int init_module(void) {
frame_dummy();
__do_global_ctors_aux();
try {
Module::create();
throw int();
}
catch(...) {
WARN("exception catched\n");
return -1;
}
return 0;
}
void cleanup_module(void) {
Module::remove();
__do_global_ctors_aux();
}
-------------------
As I mentioned __do_global_Xtors_aux() is working in that manner only eh isn't.
As I can see there are some assums about the position on symbols (like
CTOR_LIST and CTOR_END etc.) for handling with
static func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) = { (func_ptr) (-1) };
static func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
static void __do_global_ctors_aux (void)
{
func_ptr *p;
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
}
This prinziple doesn't work with eh - there seems to be more secrets? How can I
get it to work ? The compiler is generating the neccessary symbols and
functions __eh_alloc, __throw etc.
Thanks
Olaf
---- kernel_crt.c -----
#include <stddef.h> // size_t
#include "config/i386/i386.h" // FIRST_PSEUDO_REGISTER
#include "frame.h"
extern int rtl_printf(const char* fmt, ...); // kernel printf
typedef void (*func_ptr) (void);
typedef unsigned int ui32 __attribute__ ((mode (SI)));
static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
static func_ptr __CTOR_END__[];
static void __do_global_dtors_aux (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
static int completed = 0;
rtl_printf("__do_global_dtors_aux()\n");
if (completed)
return;
while (*p)
{
p++;
(*(p-1)) ();
}
if (__deregister_frame_info)
__deregister_frame_info (__EH_FRAME_BEGIN__);
completed = 1;
}
static void frame_dummy (void)
{
static struct object object;
rtl_printf("frame_dummy()\n");
if (__register_frame_info) {
rtl_printf("call __register_frame_info()\n");
__register_frame_info (__EH_FRAME_BEGIN__, &object);
}
}
static void __do_global_ctors_aux (void)
{
func_ptr *p;
rtl_printf("__do_global_ctors_aux()\n");
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
}
static func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) = { (func_ptr) (-1) };
static func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
static func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
static func_ptr __DTOR_END__[1] __attribute__ ((__unused__)) = { (func_ptr) 0 };
static char __EH_FRAME_BEGIN__[] = { };
static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
-------------