[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
This commit is contained in:
+108
-10
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user