summaryrefslogtreecommitdiffstats
path: root/libgcc
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-20 20:54:25 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-20 20:54:25 +0000
commitd77ac56d6025a8fa68cd9fefad0729bb5d74d675 (patch)
tree508dcec251f6f6475b1d1cd44021a0220b695b7e /libgcc
parent32074525e1434d9a440d101146b237e254dd7179 (diff)
downloadppe42-gcc-d77ac56d6025a8fa68cd9fefad0729bb5d74d675.tar.gz
ppe42-gcc-d77ac56d6025a8fa68cd9fefad0729bb5d74d675.zip
2011-12-20 Sergio Durigan Junior <sergiodj@redhat.com>
* unwind-arm-common.inc: Include `tconfig.h', `tsystem.h' and `sys/sdt.h'. (_Unwind_DebugHook): New function. (uw_restore_core_regs): New define. (unwind_phase2): Use uw_restore_core_regs instead of restore_core_regs. (unwind_phase2_forced): Likewise. (__gnu_Unwind_Resume): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182552 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog11
-rw-r--r--libgcc/unwind-arm-common.inc53
2 files changed, 60 insertions, 4 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 6461ad6b9ac..3f957673680 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,14 @@
+2011-12-20 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * unwind-arm-common.inc: Include `tconfig.h', `tsystem.h' and
+ `sys/sdt.h'.
+ (_Unwind_DebugHook): New function.
+ (uw_restore_core_regs): New define.
+ (unwind_phase2): Use uw_restore_core_regs instead of
+ restore_core_regs.
+ (unwind_phase2_forced): Likewise.
+ (__gnu_Unwind_Resume): Likewise.
+
2011-12-20 Uros Bizjak <ubizjak@gmail.com>
* config/alpha/linux-unwind.h: Update copyright years.
diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc
index 0713056bd1d..bf1690200b8 100644
--- a/libgcc/unwind-arm-common.inc
+++ b/libgcc/unwind-arm-common.inc
@@ -21,8 +21,15 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include "tconfig.h"
+#include "tsystem.h"
#include "unwind.h"
+/* Used for SystemTap unwinder probe. */
+#ifdef HAVE_SYS_SDT_H
+#include <sys/sdt.h>
+#endif
+
/* We add a prototype for abort here to avoid creating a dependency on
target headers. */
extern void abort (void);
@@ -105,6 +112,44 @@ static inline _uw selfrel_offset31 (const _uw *p);
static _uw __gnu_unwind_get_pr_addr (int idx);
+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
+ target frame. HANDLER is the PC to which control will be
+ transferred. */
+
+static void
+_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
+}
+
+/* This is a wrapper to be called when we need to restore core registers.
+ It will call `_Unwind_DebugHook' before restoring the registers, thus
+ making it possible to intercept and debug exceptions.
+
+ When calling `_Unwind_DebugHook', the first argument (the CFA) is zero
+ because we are not interested in it. However, it must be there (even
+ being zero) because GDB expects to find it when using the probe. */
+
+#define uw_restore_core_regs(TARGET, CORE) \
+ do \
+ { \
+ void *handler = __builtin_frob_return_addr ((void *) VRS_PC (TARGET)); \
+ _Unwind_DebugHook (0, handler); \
+ restore_core_regs (CORE); \
+ } \
+ while (0)
+
/* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains
NREC entries. */
@@ -253,8 +298,8 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
if (pr_result != _URC_INSTALL_CONTEXT)
abort();
-
- restore_core_regs (&vrs->core);
+
+ uw_restore_core_regs (vrs, &vrs->core);
}
/* Perform phase2 forced unwinding. */
@@ -339,7 +384,7 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
return _URC_FAILURE;
}
- restore_core_regs (&saved_vrs.core);
+ uw_restore_core_regs (&saved_vrs, &saved_vrs.core);
}
/* This is a very limited implementation of _Unwind_GetCFA. It returns
@@ -450,7 +495,7 @@ __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
{
case _URC_INSTALL_CONTEXT:
/* Upload the registers to enter the landing pad. */
- restore_core_regs (&entry_vrs->core);
+ uw_restore_core_regs (entry_vrs, &entry_vrs->core);
case _URC_CONTINUE_UNWIND:
/* Continue unwinding the next frame. */
OpenPOWER on IntegriCloud