/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*	Copyright (C) 2004 Garrett A. Kajmowicz

	This file is part of the uClibc++ Library.

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <exception>
#include <cstdlib>
#include <typeinfo>

#ifndef HEADER_ULC_SUPPORT
#define HEADER_ULC_SUPPORT 1

using namespace std;

//From C++ ABI spec
typedef enum {
	_URC_NO_REASON = 0,
	_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
	_URC_FATAL_PHASE2_ERROR = 2,
	_URC_FATAL_PHASE1_ERROR = 3,
	_URC_NORMAL_STOP = 4,
	_URC_END_OF_STACK = 5,
	_URC_HANDLER_FOUND = 6,
	_URC_INSTALL_CONTEXT = 7,
	_URC_CONTINUE_UNWIND = 8
} _Unwind_Reason_Code;


typedef void (*_Unwind_Exception_Cleanup_Fn)
	(_Unwind_Reason_Code reason, struct _Unwind_Exception *exc);

//The following definitions were grabbed from the gcc implementation
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, struct _Unwind_Exception *);

typedef int _Unwind_Action;
static const _Unwind_Action _UA_SEARCH_PHASE = 1;
static const _Unwind_Action _UA_CLEANUP_PHASE = 2;
static const _Unwind_Action _UA_HANDLER_FRAME = 4;
static const _Unwind_Action _UA_FORCE_UNWIND = 8;

const _Unwind_Exception_Class __uclibcxx_exception_class = ((((((((
	_Unwind_Exception_Class) 'u' << 8 | (_Unwind_Exception_Class) 'l') << 8 
	| (_Unwind_Exception_Class) 'i') << 8 | (_Unwind_Exception_Class) 'b') << 8
	| (_Unwind_Exception_Class) 'C')<< 8 | (_Unwind_Exception_Class) '+') << 8 
	| (_Unwind_Exception_Class) '+') << 8 | (_Unwind_Exception_Class) '\0');


#define _UA_SEARCH_PHASE        1
#define _UA_CLEANUP_PHASE       2
#define _UA_HANDLER_FRAME       4
#define _UA_FORCE_UNWIND        8
#define _UA_END_OF_STACK        16

struct _Unwind_Exception{
        _Unwind_Exception_Class exception_class;		//Type of exception, eg ulibC++\0
        _Unwind_Exception_Cleanup_Fn exception_cleanup;		//Destructor if from diff runtime
        _Unwind_Word private_1;					//Don't touch at all!
        _Unwind_Word private_2;					//Don't touch at all!
} __attribute__((__aligned__));


//The following structure is system-dependent and defined by the compiler
//Thus it's definition was copied from the gcc 3.4.0 header files
struct _Unwind_Context;
//{
//	void *reg[DWARF_FRAME_REGISTERS+1];
//	void *cfa;
//	void *ra;
//	void *lsda;
//	struct dwarf_eh_bases bases;
//	_Unwind_Word args_size;
//};



_Unwind_Reason_Code _Unwind_RaiseException ( struct _Unwind_Exception *exception_object );

//_Unwind_ForcedUnwind 

typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
	(int version, _Unwind_Action actions,  _Unwind_Exception_Class exceptionClass,
	struct _Unwind_Exception *exceptionObject, 
	struct _Unwind_Context *context, void *stop_parameter );

_Unwind_Reason_Code _Unwind_ForcedUnwind ( 
	struct _Unwind_Exception *exception_object, _Unwind_Stop_Fn stop,
	void *stop_parameter );

void _Unwind_Resume (struct _Unwind_Exception *exception_object);
void _Unwind_DeleteException (struct _Unwind_Exception *exception_object);

_Unwind_Word _Unwind_GetGR (struct _Unwind_Context *context, int index);
void _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word);

_Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *context);
void _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr new_value);

_Unwind_Ptr _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context);
_Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *context);

_Unwind_Reason_Code (*__personality_routine)
	(int version,					//Should be 1
	_Unwind_Action actions,				//Actions the routine will perform (bitmask)
	_Unwind_Exception_Class exceptionClass,		//Type of exception - vendor is high 4 bytes
	struct _Unwind_Exception *exceptionObject,	//Points to exception header
	struct _Unwind_Context *context);		//Unwinder state information


/*The following part is the Level II ABI which is required for compatability*/
//This might be the only stuff that *I* need to implement

struct __cxa_exception { 
	std::type_info *exceptionType;		//Type of thrown exception
	void (*exceptionDestructor) (void *); 	//Pointer to the destructor
	unexpected_handler unexpectedHandler;	//Unexpected handler to use
	terminate_handler terminateHandler;	//Terminate handle to use
	__cxa_exception *nextException;		//per thread linked list

	int handlerCount;			//How many handlers have caught this
	int handlerSwitchValue;			
	const char *actionRecord;
	const char *languageSpecificData;
	void *catchTemp;
	void *adjustedPtr;

	_Unwind_Exception unwindHeader;
};

struct __cxa_eh_globals {
	__cxa_exception *caughtExceptions;
	unsigned int uncaughtExceptions;
};

extern "C" __cxa_eh_globals *__cxa_get_globals(void);	//Return ptr to the eh_globals object for current thread
extern "C" __cxa_eh_globals *__cxa_get_globals_fast(void);	//Same as above, assumes that above called at least once

extern "C" void *__cxa_allocate_exception(size_t thrown_size);	//Allocate space for exception plus header
extern "C" void __cxa_free_exception(void *thrown_exception);	//Free space allocated from the above

extern "C" void __cxa_throw (void *thrown_exception, 	//This is the actual throw call
//	std::type_info *tinfo, 			//Type of object
	void * tinfo, 			//Type of object
	void (*dest) (void *) );		//Pointer to destructor destroy object


#endif