/* DWARF2 exception handling and frame unwind runtime interface routines.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2008, 2009 Free Software Foundation, Inc.
+ 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GCC.
#include "gthr.h"
#include "unwind-dw2.h"
+#ifdef HAVE_SYS_SDT_H
+#include <sys/sdt.h>
+#endif
+
#ifndef __USING_SJLJ_EXCEPTIONS__
#ifndef STACK_GROWS_DOWNWARD
aug += 2;
}
- /* Immediately following the augmentation are the code and
+ /* After the augmentation resp. pointer for "eh" augmentation
+ follows for CIE version >= 4 address size byte and
+ segment size byte. */
+ if (__builtin_expect (cie->version >= 4, 0))
+ {
+ if (p[0] != sizeof (void *) || p[1] != 0)
+ return NULL;
+ p += 2;
+ }
+ /* Immediately following this are the code and
data alignment and return address column. */
p = read_uleb128 (p, &utmp);
fs->code_align = (_Unwind_Word)utmp;
else if (aug[0] == 'P')
{
_Unwind_Ptr personality;
-
+
p = read_encoded_value (context, *p, p + 1, &personality);
fs->personality = (_Unwind_Personality_Fn) personality;
aug += 1;
/* Unary operations. */
gcc_assert (stack_elt);
stack_elt -= 1;
-
+
result = stack[stack_elt];
switch (op)
_Unwind_Word first, second;
gcc_assert (stack_elt >= 2);
stack_elt -= 2;
-
+
second = stack[stack_elt];
first = stack[stack_elt + 1];
result = second - first;
break;
case DW_OP_mod:
- result = (_Unwind_Sword) second % (_Unwind_Sword) first;
+ result = second % first;
break;
case DW_OP_mul:
result = second * first;
case DW_OP_bra:
gcc_assert (stack_elt);
stack_elt -= 1;
-
+
offset = read_2s (op_ptr);
op_ptr += 2;
if (stack[stack_elt] != 0)
case DW_CFA_set_loc:
{
_Unwind_Ptr pc;
-
+
insn_ptr = read_encoded_value (context, fs->fde_encoding,
insn_ptr, &pc);
fs->pc = (void *) pc;
if (fs->lsda_encoding != DW_EH_PE_omit)
{
_Unwind_Ptr lsda;
-
+
aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
context->lsda = (void *) lsda;
}
_Unwind_SpTmp *tmp_sp)
{
int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
-
+
if (size == sizeof(_Unwind_Ptr))
tmp_sp->ptr = (_Unwind_Ptr) cfa;
else
context->ra = __builtin_extract_return_addr (outer_ra);
}
-static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
+static void _Unwind_DebugHook (void *, void *)
+ __attribute__ ((__noinline__, __used__, __noclone__));
/* This function is called during unwinding. It is intended as a hook
for a debugger to intercept exceptions. CFA is the CFA of the
_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
void *handler __attribute__ ((__unused__)))
{
+ /* We only want to use stap probes starting with v3. Earlier
+ versions added too much startup cost. */
+#if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
+ STAP_PROBE2 (libgcc, unwind, cfa, handler);
+#else
asm ("");
+#endif
}
/* Install TARGET into CURRENT so that we can return to it. This is a
static inline _Unwind_Ptr
uw_identify_context (struct _Unwind_Context *context)
{
- return _Unwind_GetCFA (context);
+ /* The CFA is not sufficient to disambiguate the context of a function
+ interrupted by a signal before establishing its frame and the context
+ of the signal itself. */
+ if (STACK_GROWS_DOWNWARD)
+ return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
+ else
+ return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
}