diff options
| author | Mike Pall <mike> | 2012-03-25 21:52:07 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2012-03-25 21:52:07 +0200 |
| commit | 018792452ecdcaeff9362e4238004420665b450b (patch) | |
| tree | e103602609405f1da2dc6f33d2409bf7228dfc14 /src | |
| parent | 339142c2aaa82fd6e3c71fdbbb12296899e8cdd2 (diff) | |
| download | luajit-018792452ecdcaeff9362e4238004420665b450b.tar.gz luajit-018792452ecdcaeff9362e4238004420665b450b.tar.bz2 luajit-018792452ecdcaeff9362e4238004420665b450b.zip | |
Replace unwind.h definitions with our own.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_err.c | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/src/lj_err.c b/src/lj_err.c index a4c74780..b46a6dc9 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
| @@ -187,24 +187,48 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
| 187 | 187 | ||
| 188 | #if defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) | 188 | #if defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) |
| 189 | 189 | ||
| 190 | #ifdef __clang__ | 190 | /* |
| 191 | /* http://llvm.org/bugs/show_bug.cgi?id=8703 */ | 191 | ** We have to use our own definitions instead of the mandatory (!) unwind.h, |
| 192 | #define __unwind_word__ word | 192 | ** since various OS, distros and compilers mess up the header installation. |
| 193 | #endif | 193 | */ |
| 194 | |||
| 195 | typedef struct _Unwind_Exception | ||
| 196 | { | ||
| 197 | uint64_t exclass; | ||
| 198 | void (*excleanup)(int, struct _Unwind_Exception); | ||
| 199 | uintptr_t p1, p2; | ||
| 200 | } __attribute__((__aligned__)) _Unwind_Exception; | ||
| 201 | |||
| 202 | typedef struct _Unwind_Context _Unwind_Context; | ||
| 194 | 203 | ||
| 195 | #include <unwind.h> | 204 | #define _URC_OK 0 |
| 205 | #define _URC_FATAL_PHASE1_ERROR 3 | ||
| 206 | #define _URC_HANDLER_FOUND 6 | ||
| 207 | #define _URC_INSTALL_CONTEXT 7 | ||
| 208 | #define _URC_CONTINUE_UNWIND 8 | ||
| 209 | #define _URC_FAILURE 9 | ||
| 196 | 210 | ||
| 197 | #if !LJ_TARGET_ARM | 211 | #if !LJ_TARGET_ARM |
| 198 | 212 | ||
| 213 | extern uintptr_t _Unwind_GetCFA(_Unwind_Context *); | ||
| 214 | extern void _Unwind_SetGR(_Unwind_Context *, int, uintptr_t); | ||
| 215 | extern void _Unwind_SetIP(_Unwind_Context *, uintptr_t); | ||
| 216 | extern void _Unwind_DeleteException(_Unwind_Exception *); | ||
| 217 | extern int _Unwind_RaiseException(_Unwind_Exception *); | ||
| 218 | |||
| 219 | #define _UA_SEARCH_PHASE 1 | ||
| 220 | #define _UA_CLEANUP_PHASE 2 | ||
| 221 | #define _UA_HANDLER_FRAME 4 | ||
| 222 | #define _UA_FORCE_UNWIND 8 | ||
| 223 | |||
| 199 | #define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ | 224 | #define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ |
| 200 | #define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) | 225 | #define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) |
| 201 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) | 226 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) |
| 202 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) | 227 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) |
| 203 | 228 | ||
| 204 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ | 229 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ |
| 205 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | 230 | LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, |
| 206 | uint64_t uexclass, struct _Unwind_Exception *uex, | 231 | uint64_t uexclass, _Unwind_Exception *uex, _Unwind_Context *ctx) |
| 207 | struct _Unwind_Context *ctx) | ||
| 208 | { | 232 | { |
| 209 | void *cf; | 233 | void *cf; |
| 210 | lua_State *L; | 234 | lua_State *L; |
| @@ -255,7 +279,7 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | |||
| 255 | #endif | 279 | #endif |
| 256 | #else | 280 | #else |
| 257 | /* This is not the proper way to escape from the unwinder. We get away with | 281 | /* This is not the proper way to escape from the unwinder. We get away with |
| 258 | ** it on x86/PPC because the interpreter restores all callee-saved regs. | 282 | ** it on non-x64 because the interpreter restores all callee-saved regs. |
| 259 | */ | 283 | */ |
| 260 | lj_err_throw(L, errcode); | 284 | lj_err_throw(L, errcode); |
| 261 | #endif | 285 | #endif |
| @@ -266,26 +290,46 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | |||
| 266 | #if LJ_UNWIND_EXT | 290 | #if LJ_UNWIND_EXT |
| 267 | #if LJ_TARGET_OSX || defined(__OpenBSD__) | 291 | #if LJ_TARGET_OSX || defined(__OpenBSD__) |
| 268 | /* Sorry, no thread safety for OSX. Complain to Apple, not me. */ | 292 | /* Sorry, no thread safety for OSX. Complain to Apple, not me. */ |
| 269 | static struct _Unwind_Exception static_uex; | 293 | static _Unwind_Exception static_uex; |
| 270 | #else | 294 | #else |
| 271 | static __thread struct _Unwind_Exception static_uex; | 295 | static __thread _Unwind_Exception static_uex; |
| 272 | #endif | 296 | #endif |
| 273 | 297 | ||
| 274 | /* Raise DWARF2 exception. */ | 298 | /* Raise DWARF2 exception. */ |
| 275 | static void err_raise_ext(int errcode) | 299 | static void err_raise_ext(int errcode) |
| 276 | { | 300 | { |
| 277 | static_uex.exception_class = LJ_UEXCLASS_MAKE(errcode); | 301 | static_uex.exclass = LJ_UEXCLASS_MAKE(errcode); |
| 278 | static_uex.exception_cleanup = NULL; | 302 | static_uex.excleanup = NULL; |
| 279 | _Unwind_RaiseException(&static_uex); | 303 | _Unwind_RaiseException(&static_uex); |
| 280 | } | 304 | } |
| 281 | #endif | 305 | #endif |
| 282 | 306 | ||
| 283 | #else | 307 | #else |
| 284 | 308 | ||
| 309 | extern void _Unwind_DeleteException(void *); | ||
| 310 | extern int __gnu_unwind_frame (void *, _Unwind_Context *); | ||
| 311 | extern int _Unwind_VRS_Set(_Unwind_Context *, int, uint32_t, int, void *); | ||
| 312 | extern int _Unwind_VRS_Get(_Unwind_Context *, int, uint32_t, int, void *); | ||
| 313 | |||
| 314 | static inline uint32_t _Unwind_GetGR(_Unwind_Context *ctx, int r) | ||
| 315 | { | ||
| 316 | uint32_t v; | ||
| 317 | _Unwind_VRS_Get(ctx, 0, r, 0, &v); | ||
| 318 | return v; | ||
| 319 | } | ||
| 320 | |||
| 321 | static inline void _Unwind_SetGR(_Unwind_Context *ctx, int r, uint32_t v) | ||
| 322 | { | ||
| 323 | _Unwind_VRS_Set(ctx, 0, r, 0, &v); | ||
| 324 | } | ||
| 325 | |||
| 326 | #define _US_VIRTUAL_UNWIND_FRAME 0 | ||
| 327 | #define _US_UNWIND_FRAME_STARTING 1 | ||
| 328 | #define _US_ACTION_MASK 3 | ||
| 329 | #define _US_FORCE_UNWIND 8 | ||
| 330 | |||
| 285 | /* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ | 331 | /* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ |
| 286 | LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state, | 332 | LJ_FUNCA int lj_err_unwind_arm(int state, void *ucb, _Unwind_Context *ctx) |
| 287 | _Unwind_Control_Block *ucb, | ||
| 288 | _Unwind_Context *ctx) | ||
| 289 | { | 333 | { |
| 290 | void *cf = (void *)_Unwind_GetGR(ctx, 13); | 334 | void *cf = (void *)_Unwind_GetGR(ctx, 13); |
| 291 | lua_State *L = cframe_L(cf); | 335 | lua_State *L = cframe_L(cf); |
| @@ -295,9 +339,9 @@ LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state, | |||
| 295 | } | 339 | } |
| 296 | if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) { | 340 | if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) { |
| 297 | _Unwind_DeleteException(ucb); | 341 | _Unwind_DeleteException(ucb); |
| 298 | _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw); | 342 | _Unwind_SetGR(ctx, 15, (uint32_t)(void *)lj_err_throw); |
| 299 | _Unwind_SetGR(ctx, 0, (_Unwind_Word)L); | 343 | _Unwind_SetGR(ctx, 0, (uint32_t)L); |
| 300 | _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN); | 344 | _Unwind_SetGR(ctx, 1, (uint32_t)LUA_ERRRUN); |
| 301 | return _URC_INSTALL_CONTEXT; | 345 | return _URC_INSTALL_CONTEXT; |
| 302 | } | 346 | } |
| 303 | if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) | 347 | if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) |
