diff options
author | Andrew Haley <aph@gcc.gnu.org> | 2007-09-04 18:00:31 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2007-09-04 18:00:31 +0000 |
commit | f202305d019c7a5d86bcbc14f9d6fe64c3fbe05b (patch) | |
tree | 09a5f1f5bb8173c991287a709677d9c9cb1925ab /libjava/exception.cc | |
parent | da6c9e40179629b60f3559b42eca8fa95f8a2a3a (diff) | |
download | gcc-f202305d019c7a5d86bcbc14f9d6fe64c3fbe05b.tar.gz |
[multiple changes]
2007-09-04 Andrew Haley <aph@redhat.com>
PR java/27908
* testsuite/libjava.lang/PR27908.java
({run1,run2,run3}.isRunning): New Method.
(main): Fix race condition.
2007-08-29 Andrew Haley <aph@redhat.com>
* gnu/classpath/natVMStackWalker.cc (VMStackWalker::getCallingClass):
Make sure we're not sibcalled.
(GET_CALLING_CLASS): Define for ARM EABI.
2007-08-22 Andrew Haley <aph@redhat.com>
* configure.host (BACKTRACESPEC): Add arm*-linux*.
2007-08-22 Andrew Haley <aph@redhat.com>
* configure.ac (LIBSTDCXXSPEC): New.
* configure.host: Add arm*-linux* to pthread test.
* configure.ac (LIBGCJTESTSPEC): Add path to libstdc++ for ARM
EABI.
* testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Use
-fexceptions for ARM EABI.
* testsuite/lib/libjava.exp (libjava_arguments): Add libgcj-test.spec.
(libjava_invoke): Log the invocation.
2007-08-15 Andrew Haley <aph@redhat.com>
* configure.ac (extra_ldflags): Define.
* Makefile.am: Use extra_ldflags for all executables.
2007-08-14 Andrew Haley <aph@redhat.com>
* sysdep/arm/backtrace.h: Remove stubs for _Unwind_GetIPInfo,
_Unwind_GetRegionStart, and _Unwind_Backtrace.
2007-07-27 Andrew Haley <aph@redhat.com>
* gnu/classpath/natVMStackWalker.cc (GET_CALLING_CLASS): Stub for
ARM EABI.
* exception.cc (get_exception_header_from_ue): New.
(get_ttype_entry): ARM EABI version.
(PERSONALITY_FUNCTION): Add ARM EABI code.
* sysdep/arm/backtrace.h: New file.
* stacktrace.cc (_URC_NORMAL_STOP): New.
* configure.ac (extra_ldflags_libjava): Add libsupc++.la for ARM
EABI.
* configure.host (BACKTRACESPEC): Add arm/backtrace.h.
From-SVN: r128098
Diffstat (limited to 'libjava/exception.cc')
-rw-r--r-- | libjava/exception.cc | 118 |
1 files changed, 108 insertions, 10 deletions
diff --git a/libjava/exception.cc b/libjava/exception.cc index 4875dfde52f..3a8fe46d57d 100644 --- a/libjava/exception.cc +++ b/libjava/exception.cc @@ -58,6 +58,21 @@ struct java_exception_header _Unwind_Exception unwindHeader; }; +#ifdef __ARM_EABI_UNWINDER__ +// This is the exception class we report -- "GNUCJAVA". + +const _Unwind_Exception_Class __gcj_exception_class + = {'G', 'N', 'U', 'C', 'J', 'A', 'V', 'A'}; + +static inline java_exception_header * +get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<java_exception_header *>(exc + 1) - 1; +} + +extern "C" void __cxa_begin_cleanup (_Unwind_Exception*); + +#else // !__ARM_EABI_UNWINDER__ // This is the exception class we report -- "GNUCJAVA". const _Unwind_Exception_Class __gcj_exception_class = ((((((((_Unwind_Exception_Class) 'G' @@ -75,6 +90,7 @@ get_exception_header_from_ue (_Unwind_Exception *exc) { return reinterpret_cast<java_exception_header *>(exc + 1) - 1; } +#endif // !__ARM_EABI_UNWINDER__ /* Perform a throw, Java style. Throw will unwind through this call, so there better not be any handlers or exception thrown here. */ @@ -89,7 +105,8 @@ _Jv_Throw (jthrowable value) value = new java::lang::NullPointerException (); xh->value = value; - xh->unwindHeader.exception_class = __gcj_exception_class; + memcpy (&xh->unwindHeader.exception_class, &__gcj_exception_class, + sizeof xh->unwindHeader.exception_class); xh->unwindHeader.exception_cleanup = NULL; /* We're happy with setjmp/longjmp exceptions or region-based @@ -159,6 +176,21 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p, return p; } +#ifdef __ARM_EABI_UNWINDER__ + +static void ** +get_ttype_entry(_Unwind_Context *, lsda_header_info* info, _uleb128_t i) +{ + _Unwind_Ptr ptr; + + ptr = (_Unwind_Ptr) (info->TType - (i * 4)); + ptr = _Unwind_decode_target2(ptr); + + return reinterpret_cast<void **>(ptr); +} + +#else + static void ** get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) { @@ -170,6 +202,7 @@ get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) return reinterpret_cast<void **>(ptr); } +#endif // Using a different personality function name causes link failures // when trying to mix code using different exception handling models. @@ -180,12 +213,33 @@ get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) #define PERSONALITY_FUNCTION __gcj_personality_v0 #endif +#ifdef __ARM_EABI_UNWINDER__ + +#define CONTINUE_UNWINDING \ + do \ + { \ + if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \ + return _URC_FAILURE; \ + return _URC_CONTINUE_UNWIND; \ + } \ + while (0) + +extern "C" _Unwind_Reason_Code +PERSONALITY_FUNCTION (_Unwind_State state, + struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context) +#else + +#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND + extern "C" _Unwind_Reason_Code PERSONALITY_FUNCTION (int version, _Unwind_Action actions, _Unwind_Exception_Class exception_class, struct _Unwind_Exception *ue_header, struct _Unwind_Context *context) + +#endif { java_exception_header *xh = get_exception_header_from_ue (ue_header); @@ -197,16 +251,56 @@ PERSONALITY_FUNCTION (int version, int handler_switch_value; bool saw_cleanup; bool saw_handler; + bool foreign_exception; int ip_before_insn = 0; +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Action actions; + + switch (state & _US_ACTION_MASK) + { + case _US_VIRTUAL_UNWIND_FRAME: + actions = _UA_SEARCH_PHASE; + break; + + case _US_UNWIND_FRAME_STARTING: + actions = _UA_CLEANUP_PHASE; + if (!(state & _US_FORCE_UNWIND) + && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + actions |= _UA_HANDLER_FRAME; + break; + + case _US_UNWIND_FRAME_RESUME: + CONTINUE_UNWINDING; + break; + + default: + std::abort(); + } + actions |= state & _US_FORCE_UNWIND; + + // We don't know which runtime we're working with, so can't check this. + // However the ABI routines hide this from us, and we don't actually need + // to know. + foreign_exception = false; + + // The dwarf unwinder assumes the context structure holds things like the + // function and LSDA pointers. The ARM implementation caches these in + // the exception header (UCB). To avoid rewriting everything we make the + // virtual IP register point at the UCB. + ip = (_Unwind_Ptr) ue_header; + _Unwind_SetGR(context, 12, ip); +#else // Interface version check. if (version != 1) return _URC_FATAL_PHASE1_ERROR; + foreign_exception = exception_class != __gcj_exception_class; +#endif // Shortcut for phase 2 found handler for domestic exception. if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) - && exception_class == __gcj_exception_class) + && !foreign_exception) { handler_switch_value = xh->handlerSwitchValue; landing_pad = xh->landingPad; @@ -227,17 +321,17 @@ PERSONALITY_FUNCTION (int version, // If no LSDA, then there are no handlers or cleanups. if (! language_specific_data) - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; // Parse the LSDA header. p = parse_lsda_header (context, language_specific_data, &info); #ifdef HAVE_GETIPINFO ip = _Unwind_GetIPInfo (context, &ip_before_insn); - if (! ip_before_insn) - --ip; #else ip = _Unwind_GetIP (context) - 1; #endif + if (! ip_before_insn) + --ip; landing_pad = 0; action_record = 0; handler_switch_value = 0; @@ -296,7 +390,7 @@ PERSONALITY_FUNCTION (int version, // If ip is not present in the table, C++ would call terminate. // ??? It is perhaps better to tweek the LSDA so that no-action // is mapped to no-entry for Java. - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; found_something: saw_cleanup = false; @@ -334,7 +428,7 @@ PERSONALITY_FUNCTION (int version, // During forced unwinding, we only run cleanups. With a // foreign exception class, we have no class info to match. else if ((actions & _UA_FORCE_UNWIND) - || exception_class != __gcj_exception_class) + || foreign_exception) ; else if (ar_filter > 0) @@ -374,15 +468,15 @@ PERSONALITY_FUNCTION (int version, } if (! saw_handler && ! saw_cleanup) - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; if (actions & _UA_SEARCH_PHASE) { if (! saw_handler) - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; // For domestic exceptions, we cache data from phase 1 for phase 2. - if (exception_class == __gcj_exception_class) + if (! foreign_exception) { xh->handlerSwitchValue = handler_switch_value; xh->landingPad = landing_pad; @@ -396,5 +490,9 @@ PERSONALITY_FUNCTION (int version, _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), handler_switch_value); _Unwind_SetIP (context, landing_pad); +#ifdef __ARM_EABI_UNWINDER__ + if (saw_cleanup) + __cxa_begin_cleanup(ue_header); +#endif return _URC_INSTALL_CONTEXT; } |