Commit 817e7411 by Richard Henderson Committed by Richard Henderson

eh_personality.cc: Include unwind-pe.h.

        * libsupc++/eh_personality.cc: Include unwind-pe.h.  Remove
        all pointer encoding logic.
        (struct lsda_header_info): Add ttype_base.
        (get_ttype_entry): Use it instead of a context.
        (check_exception_spec): Likewise.
        (PERSONALITY_FUNCTION): Initialize ttype_base.  Store it in
        the c++ exception header for __cxa_call_unexpected.
        (__cxa_call_unexpected): Use it.

From-SVN: r41982
parent 2a1ee410
2001-05-11 Richard Henderson <rth@redhat.com>
* libsupc++/eh_personality.cc: Include unwind-pe.h. Remove
all pointer encoding logic.
(struct lsda_header_info): Add ttype_base.
(get_ttype_entry): Use it instead of a context.
(check_exception_spec): Likewise.
(PERSONALITY_FUNCTION): Initialize ttype_base. Store it in
the c++ exception header for __cxa_call_unexpected.
(__cxa_call_unexpected): Use it.
2001-05-09 Benjamin Kosnik <bkoz@redhat.com> 2001-05-09 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/lib/libstdc++.exp: Use libgloss.exp. Call * testsuite/lib/libstdc++.exp: Use libgloss.exp. Call
......
...@@ -34,181 +34,14 @@ ...@@ -34,181 +34,14 @@
using namespace __cxxabiv1; using namespace __cxxabiv1;
#include "unwind-pe.h"
// ??? 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);
}
struct lsda_header_info struct lsda_header_info
{ {
_Unwind_Ptr Start; _Unwind_Ptr Start;
_Unwind_Ptr LPStart; _Unwind_Ptr LPStart;
_Unwind_Ptr ttype_base;
const unsigned char *TType; const unsigned char *TType;
const unsigned char *action_table; const unsigned char *action_table;
unsigned char ttype_encoding; unsigned char ttype_encoding;
...@@ -251,19 +84,20 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p, ...@@ -251,19 +84,20 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
} }
static const std::type_info * static const std::type_info *
get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) get_ttype_entry (lsda_header_info *info, long i)
{ {
_Unwind_Ptr ptr; _Unwind_Ptr ptr;
i *= size_of_encoded_value (info->ttype_encoding); i *= size_of_encoded_value (info->ttype_encoding);
read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr); read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
info->TType - i, &ptr);
return reinterpret_cast<const std::type_info *>(ptr); return reinterpret_cast<const std::type_info *>(ptr);
} }
static bool static bool
check_exception_spec (_Unwind_Context *context, lsda_header_info *info, check_exception_spec (lsda_header_info *info, const std::type_info *throw_type,
const std::type_info *throw_type, long filter_value) long filter_value)
{ {
const unsigned char *e = info->TType - filter_value - 1; const unsigned char *e = info->TType - filter_value - 1;
...@@ -281,7 +115,7 @@ check_exception_spec (_Unwind_Context *context, lsda_header_info *info, ...@@ -281,7 +115,7 @@ check_exception_spec (_Unwind_Context *context, lsda_header_info *info,
return false; return false;
// Match a ttype entry. // Match a ttype entry.
catch_type = get_ttype_entry (context, info, tmp); catch_type = get_ttype_entry (info, tmp);
if (catch_type->__do_catch (throw_type, &dummy, 1)) if (catch_type->__do_catch (throw_type, &dummy, 1))
return true; return true;
} }
...@@ -344,6 +178,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -344,6 +178,7 @@ PERSONALITY_FUNCTION (int version,
// Parse the LSDA header. // Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info); p = parse_lsda_header (context, language_specific_data, &info);
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
ip = _Unwind_GetIP (context) - 1; ip = _Unwind_GetIP (context) - 1;
landing_pad = 0; landing_pad = 0;
action_record = 0; action_record = 0;
...@@ -458,7 +293,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -458,7 +293,7 @@ PERSONALITY_FUNCTION (int version,
else if (ar_filter > 0) else if (ar_filter > 0)
{ {
// Positive filter values are handlers. // Positive filter values are handlers.
catch_type = get_ttype_entry (context, &info, ar_filter); catch_type = get_ttype_entry (&info, ar_filter);
adjusted_ptr = xh + 1; adjusted_ptr = xh + 1;
// Null catch type is a catch-all handler. We can catch // Null catch type is a catch-all handler. We can catch
...@@ -494,8 +329,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -494,8 +329,7 @@ PERSONALITY_FUNCTION (int version,
// see we can't match because there's no __cxa_exception // see we can't match because there's no __cxa_exception
// object to stuff bits in for __cxa_call_unexpected to use. // object to stuff bits in for __cxa_call_unexpected to use.
if (throw_type if (throw_type
&& ! check_exception_spec (context, &info, throw_type, && ! check_exception_spec (&info, throw_type, ar_filter))
ar_filter))
{ {
saw_handler = true; saw_handler = true;
break; break;
...@@ -547,6 +381,15 @@ PERSONALITY_FUNCTION (int version, ...@@ -547,6 +381,15 @@ PERSONALITY_FUNCTION (int version,
__terminate (xh->terminateHandler); __terminate (xh->terminateHandler);
} }
// Cache the TType base value for __cxa_call_unexpected, as we won't
// have an _Unwind_Context then.
if (handler_switch_value < 0)
{
parse_lsda_header (context, xh->languageSpecificData, &info);
xh->catchTemp = (void *) base_of_encoded_value (info.ttype_encoding,
context);
}
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0), _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
(_Unwind_Ptr) &xh->unwindHeader); (_Unwind_Ptr) &xh->unwindHeader);
_Unwind_SetGR (context, __builtin_eh_return_data_regno (1), _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
...@@ -582,15 +425,16 @@ __cxa_call_unexpected (_Unwind_Exception *exc_obj) ...@@ -582,15 +425,16 @@ __cxa_call_unexpected (_Unwind_Exception *exc_obj)
// We don't quite have enough stuff cached; re-parse the LSDA. // We don't quite have enough stuff cached; re-parse the LSDA.
lsda_header_info info; lsda_header_info info;
parse_lsda_header (0, xh->languageSpecificData, &info); parse_lsda_header (0, xh->languageSpecificData, &info);
info.ttype_base = (_Unwind_Ptr) xh->catchTemp;
// If this new exception meets the exception spec, allow it. // If this new exception meets the exception spec, allow it.
if (check_exception_spec (0, &info, new_xh->exceptionType, if (check_exception_spec (&info, new_xh->exceptionType,
xh->handlerSwitchValue)) xh->handlerSwitchValue))
throw; throw;
// If the exception spec allows std::bad_exception, throw that. // If the exception spec allows std::bad_exception, throw that.
const std::type_info &bad_exc = typeid (std::bad_exception); const std::type_info &bad_exc = typeid (std::bad_exception);
if (check_exception_spec (0, &info, &bad_exc, xh->handlerSwitchValue)) if (check_exception_spec (&info, &bad_exc, xh->handlerSwitchValue))
throw std::bad_exception (); throw std::bad_exception ();
// Otherwise, die. // Otherwise, die.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment