This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

initializing eh


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 };
-------------
       


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]