summaryrefslogtreecommitdiff
path: root/arm-riscos-gnueabi
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2023-03-07 17:38:05 +0000
committerJohn-Mark Bell <jmb@netsurf-browser.org>2023-03-07 17:57:42 +0000
commitf07f57628981294b64c6b72bf25f5f588b58444e (patch)
treeb3ea35bb5e2a5e596da9d29cd7e30a967fd8ceab /arm-riscos-gnueabi
parentfb494055c4b58d05f32e50d3806a4ea02874544b (diff)
downloadtoolchains-f07f57628981294b64c6b72bf25f5f588b58444e.tar.gz
toolchains-f07f57628981294b64c6b72bf25f5f588b58444e.tar.bz2
arm-riscos-gnueabi: dump thread stacktraces, too
Diffstat (limited to 'arm-riscos-gnueabi')
-rw-r--r--arm-riscos-gnueabi/recipes/patches/gccsdk/unixlib-unwind.p128
1 files changed, 105 insertions, 23 deletions
diff --git a/arm-riscos-gnueabi/recipes/patches/gccsdk/unixlib-unwind.p b/arm-riscos-gnueabi/recipes/patches/gccsdk/unixlib-unwind.p
index ecc4f99..a917d7c 100644
--- a/arm-riscos-gnueabi/recipes/patches/gccsdk/unixlib-unwind.p
+++ b/arm-riscos-gnueabi/recipes/patches/gccsdk/unixlib-unwind.p
@@ -15,7 +15,15 @@ Index: libunixlib/signal/post.c
===================================================================
--- libunixlib/signal/post.c (revision 7698)
+++ libunixlib/signal/post.c (working copy)
-@@ -267,9 +267,86 @@
+@@ -259,15 +259,115 @@
+ #ifdef __clang__
+ #define FP_OFFSET (0)
+ #define LR_OFFSET (1)
+-#elif defined (__ARM_EABI__)
+-#define FP_OFFSET (-1)
+-#define LR_OFFSET (0)
+ #else
+ #define LR_OFFSET (-1)
#define FP_OFFSET (-3)
#endif
@@ -46,6 +54,22 @@ Index: libunixlib/signal/post.c
+
+#include <unwind.h>
+
++static void __attribute__((naked))
++__do_unwind (_Unwind_Trace_Fn fn, const void *pw)
++{
++ __asm volatile(
++ "stmfd sp!, {fp, lr};"
++ "add fp, sp, #4;"
++ /* Registers at this point in time will be the initial state.
++ * The trace function must unwind the stack frame we just created
++ * because the personality function will be told there is nothing
++ * to do as we are declared naked.
++ */
++ "bl _Unwind_Backtrace;"
++ "ldmfd sp!, {fp, pc};"
++ );
++}
++
+static _Unwind_Reason_Code
+__write_backtrace_cb (_Unwind_Context *ctx, void *pw)
+{
@@ -55,6 +79,25 @@ Index: libunixlib/signal/post.c
+ ucbp = (_Unwind_Control_Block *) _Unwind_GetGR(ctx, UNWIND_POINTER_REG);
+ fn = (const unsigned int *) ucbp->pr_cache.fnstart;
+
++ if (fn == (const unsigned int *) __do_unwind)
++ {
++ /* First call */
++ if (pw == NULL)
++ {
++ /* Running thread: unwind on behalf of __do_unwind */
++ _Unwind_VRS_Pop (ctx, _UVRSC_CORE, (1<<11)|(1<<14), _UVRSD_UINT32);
++ }
++ else
++ {
++ /* Thread backtrace: replace entire VRS */
++ int idx;
++ for (idx = 16; idx > 0; idx--)
++ _Unwind_SetGR (ctx, idx - 1, ((unsigned int *) pw)[idx - 1]);
++ }
++
++ return _URC_NO_REASON;
++ }
++
+ fprintf (stderr, " (%8x) fn: %8x pc: %8x sp: %8x ",
+ _Unwind_GetGR (ctx, 11), (unsigned int)fn, _Unwind_GetIP (ctx),
+ _Unwind_GetGR (ctx, 13));
@@ -81,28 +124,17 @@ Index: libunixlib/signal/post.c
+}
+
static void
- __write_backtrace_thread (const unsigned int *fp)
- {
-+ if (fp != NULL)
-+ {
-+ /* TODO: thread stack traces */
-+ fprintf (stderr, "Thread stack traces not supported\n");
-+ }
-+ else
-+ {
-+ _Unwind_Backtrace(__write_backtrace_cb, NULL);
-+ }
-+
++__write_backtrace_thread (const unsigned int *regs)
++{
++ __do_unwind (__write_backtrace_cb, regs);
+ fputc ('\n', stderr);
+}
+#else
+static void
-+__write_backtrace_thread (const unsigned int *fp)
-+{
+ __write_backtrace_thread (const unsigned int *fp)
+ {
/* Running as USR26 or USR32 ? */
- unsigned int is32bit;
- __asm__ volatile ("SUBS %[is32bit], r0, r0\n\t" /* Set at least one status flag. */
-@@ -306,22 +383,6 @@
+@@ -306,22 +406,6 @@
break;
}
@@ -125,7 +157,7 @@ Index: libunixlib/signal/post.c
/* Retrieve PC counter.
PC counter has been saved using STMxx ..., { ..., PC } so it can be
8 or 12 bytes away from the STMxx instruction depending on the ARM
-@@ -347,10 +408,9 @@
+@@ -347,10 +431,9 @@
int cplusplus_name;
const char *name = extract_name (pc, &cplusplus_name);
fprintf (stderr, (cplusplus_name) ? " %s\n" : " %s()\n", name);
@@ -137,7 +169,7 @@ Index: libunixlib/signal/post.c
if (__ul_callbackfp != NULL && fp == __ul_callbackfp)
{
/* At &oldfp[1] = cpsr, a1-a4, v1-v6, sl, fp, ip, sp, lr, pc */
-@@ -424,18 +484,17 @@
+@@ -424,19 +507,16 @@
fputs ("\n\n", stderr);
}
@@ -152,9 +184,59 @@ Index: libunixlib/signal/post.c
void
__write_backtrace (int signo)
{
- #ifdef __ARM_EABI__
+-#ifdef __ARM_EABI__
- register const unsigned int *fp = __builtin_frame_address(0);
-+ register const unsigned int *fp = NULL;
- #else
+-#else
++#ifndef __ARM_EABI__
register const unsigned int *fp __asm ("fp");
#endif
+
+@@ -485,7 +565,11 @@
+ /* Dump first the details of the current thread. */
+ fprintf (stderr, "Stack backtrace:\n\nRunning thread %p (%s)\n",
+ __pthread_running_thread, __pthread_running_thread->name);
++#ifdef __ARM_EABI__
++ __write_backtrace_thread (NULL);
++#else
+ __write_backtrace_thread (fp);
++#endif
+
+ /* And then the other suspended threads if any. */
+ for (pthread_t th = __pthread_thread_list; th != NULL; th = th->next)
+@@ -494,7 +578,10 @@
+ continue;
+
+ fprintf (stderr, "\nThread %p (%s)\n", th, th->name);
+-#ifdef __clang__
++#ifdef __ARM_EABI__
++ __write_backtrace_thread (&th->saved_context->r[0]);
++#else
++# ifdef __clang__
+ const unsigned int fakestackframe[] =
+ {
+ (unsigned int)th->saved_context->r[11],
+@@ -501,22 +588,16 @@
+ (unsigned int)th->saved_context->r[14]
+ };
+ __write_backtrace_thread (&fakestackframe[0]);
+-#elif defined (__ARM_EABI__)
++# else
+ const unsigned int fakestackframe[] =
+ {
+ (unsigned int)th->saved_context->r[11],
+- (unsigned int)th->saved_context->r[14]
+- };
+- __write_backtrace_thread (&fakestackframe[1]);
+-#else
+- const unsigned int fakestackframe[] =
+- {
+- (unsigned int)th->saved_context->r[11],
+ (unsigned int)th->saved_context->r[13],
+ (unsigned int)th->saved_context->r[14],
+ (unsigned int)th->saved_context->r[15]
+ };
+ __write_backtrace_thread (&fakestackframe[3]);
++# endif
+ #endif
+ }
+ }