// Functions for Exception Support for Java.
-/* Copyright (C) 1998, 1999, 2001 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation
This file is part of libgcj.
#include <java/lang/Class.h>
#include <java/lang/NullPointerException.h>
+#include <gnu/gcj/RawData.h>
#include <gcj/cni.h>
#include <jvm.h>
-#include "unwind.h"
-
-\f
-// More nastiness: the GC wants to define TRUE and FALSE. We don't
-// need the Java definitions (themselves a hack), so we undefine them.
-#undef TRUE
-#undef FALSE
-
-extern "C"
+// unwind-pe.h uses std::abort(), but sometimes we compile libjava
+// without libstdc++-v3. The following hack forces it to use
+// stdlib.h's abort().
+namespace std
{
-#include <gc_priv.h>
-#include <gc_mark.h>
-#include <include/gc_gcj.h>
-};
+ static __attribute__ ((__noreturn__)) void
+ abort ()
+ {
+ ::abort ();
+ }
+}
+#include "unwind.h"
-\f
struct alignment_test_struct
{
char space;
extern "C" void
_Jv_Throw (jthrowable value)
{
- /* FIXME: Use the proper API to the collector. */
java_exception_header *xh
- = static_cast<java_exception_header *>(GC_malloc (sizeof (*xh)));
+ = static_cast<java_exception_header *>(_Jv_AllocRawObj (sizeof (*xh)));
if (value == NULL)
value = new java::lang::NullPointerException ();
code = _Unwind_RaiseException (&xh->unwindHeader);
#endif
- /* FIXME: If code == _URC_END_OF_STACK, then we reached top of
- stack without finding a handler for the exception. I seem to
- recall that Java has specific rules to handle this.
-
- If code is something else, we encountered some sort of heinous
- lossage, from which we could not recover. As is the way of such
- things we'll almost certainly have crashed before now, rather
- than actually being able to diagnose the problem. */
- abort ();
+ /* If code == _URC_END_OF_STACK, then we reached top of stack without
+ finding a handler for the exception. Since each thread is run in
+ a try/catch, this oughtn't happen. If code is something else, we
+ encountered some sort of heinous lossage from which we could not
+ recover. As is the way of such things, almost certainly we will have
+ crashed before now, rather than actually being able to diagnose the
+ problem. */
+ abort();
}
\f
-// ??? These ought to go somewhere else dwarf2 or dwarf2eh related.
-
-// Pointer encodings.
-#define DW_EH_PE_absptr 0x00
-#define DW_EH_PE_omit 0xff
-
-#define DW_EH_PE_uleb128 0x01
-#define DW_EH_PE_udata2 0x02
-#define DW_EH_PE_udata4 0x03
-#define DW_EH_PE_udata8 0x04
-#define DW_EH_PE_sleb128 0x09
-#define DW_EH_PE_sdata2 0x0A
-#define DW_EH_PE_sdata4 0x0B
-#define DW_EH_PE_sdata8 0x0C
-#define DW_EH_PE_signed 0x08
-
-#define DW_EH_PE_pcrel 0x10
-#define DW_EH_PE_textrel 0x20
-#define DW_EH_PE_datarel 0x30
-#define DW_EH_PE_funcrel 0x40
-
-static unsigned int
-size_of_encoded_value (unsigned char encoding)
-{
- switch (encoding & 0x07)
- {
- case DW_EH_PE_absptr:
- return sizeof (void *);
- case DW_EH_PE_udata2:
- return 2;
- case DW_EH_PE_udata4:
- return 4;
- case DW_EH_PE_udata8:
- return 8;
- }
- abort ();
-}
-
-static const unsigned char *
-read_encoded_value (_Unwind_Context *context, unsigned char encoding,
- const unsigned char *p, _Unwind_Ptr *val)
-{
- union unaligned
- {
- void *ptr;
- unsigned u2 __attribute__ ((mode (HI)));
- unsigned u4 __attribute__ ((mode (SI)));
- unsigned u8 __attribute__ ((mode (DI)));
- signed s2 __attribute__ ((mode (HI)));
- signed s4 __attribute__ ((mode (SI)));
- signed s8 __attribute__ ((mode (DI)));
- } __attribute__((__packed__));
-
- union unaligned *u = (union unaligned *) p;
- _Unwind_Ptr result;
-
- switch (encoding & 0x0f)
- {
- case DW_EH_PE_absptr:
- result = (_Unwind_Ptr) u->ptr;
- p += sizeof (void *);
- break;
-
- case DW_EH_PE_uleb128:
- {
- unsigned int shift = 0;
- unsigned char byte;
-
- result = 0;
- do
- {
- byte = *p++;
- result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
- shift += 7;
- }
- while (byte & 0x80);
- }
- break;
-
- case DW_EH_PE_sleb128:
- {
- unsigned int shift = 0;
- unsigned char byte;
-
- result = 0;
- do
- {
- byte = *p++;
- result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
- shift += 7;
- }
- while (byte & 0x80);
-
- if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
- result |= -(1L << shift);
- }
- break;
-
- case DW_EH_PE_udata2:
- result = u->u2;
- p += 2;
- break;
- case DW_EH_PE_udata4:
- result = u->u4;
- p += 4;
- break;
- case DW_EH_PE_udata8:
- result = u->u8;
- p += 8;
- break;
-
- case DW_EH_PE_sdata2:
- result = u->s2;
- p += 2;
- break;
- case DW_EH_PE_sdata4:
- result = u->s4;
- p += 4;
- break;
- case DW_EH_PE_sdata8:
- result = u->s8;
- p += 8;
- break;
-
- default:
- abort ();
- }
-
- if (result != 0)
- switch (encoding & 0xf0)
- {
- case DW_EH_PE_absptr:
- break;
-
- case DW_EH_PE_pcrel:
- // Define as relative to the beginning of the pointer.
- result += (_Unwind_Ptr) u;
- break;
-
- case DW_EH_PE_textrel:
- case DW_EH_PE_datarel:
- // FIXME.
- abort ();
-
- case DW_EH_PE_funcrel:
- result += _Unwind_GetRegionStart (context);
- break;
-
- default:
- abort ();
- }
-
- *val = result;
- return p;
-}
-
-static inline const unsigned char *
-read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
- return read_encoded_value (0, DW_EH_PE_uleb128, p, val);
-}
-
-static inline const unsigned char *
-read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
- return read_encoded_value (0, DW_EH_PE_sleb128, p, val);
-}
-
+#include "unwind-pe.h"
\f
struct lsda_header_info
{
parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
lsda_header_info *info)
{
- _Unwind_Ptr tmp;
+ _Unwind_Word tmp;
unsigned char lpstart_encoding;
info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
return p;
}
-static jclass
+static void **
get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i)
{
_Unwind_Ptr ptr;
i *= size_of_encoded_value (info->ttype_encoding);
read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr);
- return reinterpret_cast<jclass>(ptr);
+ return reinterpret_cast<void **>(ptr);
}
int handler_switch_value;
bool saw_cleanup;
bool saw_handler;
+ int ip_before_insn = 0;
// Interface version check.
goto install_context;
}
- // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
+ // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
// the stack trace for this exception. This will only collect Java
// frames, but perhaps that is acceptable.
- // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
+ // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
// index instead of a PC value. We could perhaps arrange for
// _Unwind_GetRegionStart to return context->fc->jbuf[1], which
// is the address of the handler label for __builtin_longjmp, but
// Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info);
- ip = _Unwind_GetIP (context) - 1;
+ ip = _Unwind_GetIPInfo (context, &ip_before_insn);
+ if (! ip_before_insn)
+ --ip;
landing_pad = 0;
action_record = 0;
handler_switch_value = 0;
return _URC_CONTINUE_UNWIND;
else
{
- _Unwind_Ptr cs_lp, cs_action;
+ _Unwind_Word cs_lp, cs_action;
do
{
p = read_uleb128 (p, &cs_lp);
// Search the call-site table for the action associated with this IP.
while (p < info.action_table)
{
- _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action;
+ _Unwind_Ptr cs_start, cs_len, cs_lp;
+ _Unwind_Word cs_action;
// Note that all call-site encodings are "absolute" displacements.
p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
else
{
// Otherwise we have a catch handler.
- signed long ar_filter, ar_disp;
+ _Unwind_Sword ar_filter, ar_disp;
while (1)
{
- _Unwind_Ptr tmp;
-
p = action_record;
- p = read_sleb128 (p, &tmp); ar_filter = tmp;
- read_sleb128 (p, &tmp); ar_disp = tmp;
+ p = read_sleb128 (p, &ar_filter);
+ read_sleb128 (p, &ar_disp);
if (ar_filter == 0)
{
{
// Positive filter values are handlers.
- jclass catch_type = get_ttype_entry (context, &info, ar_filter);
+ void **catch_word = get_ttype_entry (context, &info, ar_filter);
+ jclass catch_type = (jclass)*catch_word;
- // The catch_type is either a (java::lang::Class*) or
- // is one more than a (Utf8Const*).
- if ((size_t)catch_type & 1)
- catch_type = _Jv_FindClass ((Utf8Const*)catch_type - 1, NULL);
+ // FIXME: This line is a kludge to work around exception
+ // handlers written in C++, which don't yet use indirect
+ // dispatch.
+ if (catch_type == *(void **)&java::lang::Class::class$)
+ catch_type = (jclass)catch_word;
if (_Jv_IsInstanceOf (xh->value, catch_type))
{