This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
initializing eh (2)
- To: GCC Mailing List <gcc at gcc dot gnu dot org>
- Subject: initializing eh (2)
- From: Olaf Petzold <opetzold at wit dot regiocom dot net>
- Date: Tue, 23 Jan 2001 13:43:39 +0100
Hello,
after some weeks I had time to try it once more to get the eh working on linux
kernel. At this moment i kick the crtbegin/end since the linux kernel module
loader doesn't use elf section. Therefore I wrote my own. But crtstuff works as
a template for this. Unfortunally it isn't working yet - I can't catched the
exceptions (it results in a seg fault in user space/kernel gives me an "big"
error).
The question is what is necessary and what not.
Thanks
Olaf
/* -*- C++ -*- ***************************************************
* $Id$
*
* Definition of test_mod class
*
* root <opetzold@wit.regiocom.net>
* Created on: <00/12/15 13:20:20 root>
*
*/
#ifdef __cplusplus
extern "C" {
#include "hide_keywords.h"
#define __NO_VERSION__
#include <linux/config.h>
#include <linux/types.h>
#include <stddef.h>
#include "restore_keywords.h"
}
#endif
#include <new>
#include <memory>
#include "err_msg.h"
#include "config.h"
// nessary for initilalizing eh
extern "C" {
#include "config/i386/i386.h" // FIRST_PSEUDO_REGISTER
#include "frame.h"
}
/* Declare a pointer to void function type. */
typedef void (*func_ptr) (void);
static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
static func_ptr __CTOR_END__[];
static func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) = { (func_ptr) (-1) };
static func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
char __EH_FRAME_BEGIN__[] = { };
static func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
static func_ptr __DTOR_END__[1] __attribute__ ((__unused__)) = { (func_ptr) 0 };
typedef unsigned int ui32 __attribute__ ((mode (SI)));
static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
void __do_global_ctors_aux (void)
{
func_ptr *p;
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
}
void init_section() {
__do_global_ctors_aux ();
static struct object object;
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
}
void __do_global_dtors_aux (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
static int completed = 0;
if (completed)
return;
while (*p) {
p++;
(*(p-1)) ();
}
if (__deregister_frame_info)
__deregister_frame_info (__EH_FRAME_BEGIN__);
completed = 1;
}
void fini_section() {
__do_global_dtors_aux();
}
using namespace std;
class ClassA {
public:
ClassA() {
INFO("CTor Class A\n");
throw int();
}
virtual ~ClassA() { INFO("DTor Class A\n"); }
};
class ClassB : public ClassA {
public:
ClassB() {
INFO("CTor Class B\n");
}
~ClassB() { INFO("DTor Class B\n"); }
};
class Module {
public:
Module();
~Module();
static Module& module() {return *reinterpret_cast<Module*>(module_); }
/** install the module using placement new. */
static int create() {
INFO("Load Module:\n");
new (&module()) Module();
INFO("(done.)\n");
INFO("%s version %s started\n", PACKAGE, VERSION);
return 0;
}
/** remove the module and call explicit the destructor. */
static void remove() {
INFO("Remove Module:\n");
module().~Module();
INFO("(done.)\n");
INFO("%s version %s removed\n", PACKAGE, VERSION);
}
private:
/** This hack allows us to use placement new. */
static char module_[];
/** The Shm for the Card. */
auto_ptr<ClassA> a_;
};
/**
* Module implementation
*/
Module::Module()
: a_ ( new ClassA() )
{
INFO("CTor Module\n");
}
Module::~Module()
{
INFO("DTor Module\n");
}
/**
* kernel interface
*/
extern "C" {
int init_module(void);
void cleanup_module(void);
}
char Module::module_[sizeof(Module)];
int init_module(void)
{
INFO("init eh\n");
init_section();
int ret;
INFO("init_module\n");
try {
ret = Module::create();
}
catch(std::bad_alloc& e) {
WARN("exception <%s> here\n", e.what());
return -1;
}
catch(int&) {
WARN("exception int catched\n");
return -1;
}
catch(...) {
WARN("exception catched\n");
return -1;
}
return 0;
}
void cleanup_module(void)
{
INFO("cleanup_module\n");
Module::remove();
INFO("fini eh\n");
fini_section();
}