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 (2)


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


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