summaryrefslogtreecommitdiff
path: root/lib/sigevent.c
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2009-06-25 16:40:06 +0100
committerDaniel Walton <dwalton@cumulusnetworks.com>2016-05-26 01:09:43 +0000
commitbccbd141d242c1c57e73c3213371b80779377419 (patch)
treeb014807eb97e5e5ad3a7052ceec8945965254ba4 /lib/sigevent.c
parent63a2a3541828d438a0b6ecff013c4756aa447ac2 (diff)
[lib] Add support for backtrace on more platforms
* lib/sigevent.c: (program_counter) extend to support more platforms. Joint effort with Paul Jakma. (cherry picked from commit b166ea2dda9f04a8b75e0bf5adb7064580695f22)
Diffstat (limited to 'lib/sigevent.c')
-rw-r--r--lib/sigevent.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/sigevent.c b/lib/sigevent.c
index 7d08fd97ce..c80a729012 100644
--- a/lib/sigevent.c
+++ b/lib/sigevent.c
@@ -175,11 +175,35 @@ program_counter(void *context)
{
#ifdef HAVE_UCONTEXT_H
#ifdef GNU_LINUX
-#ifdef REG_EIP
- if (context)
- return (void *)(((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]);
-#endif /* REG_EIP */
+ /* these are from GNU libc, rather than Linux, strictly speaking */
+# if defined(REG_EIP)
+# define REG_INDEX REG_EIP
+# elif defined(REG_RIP)
+# define REG_INDEX REG_RIP
+# elif defined(__powerpc__)
+# define REG_INDEX 32
+# endif
+#elif defined(SUNOS_5) /* !GNU_LINUX */
+# define REG_INDEX REG_PC
#endif /* GNU_LINUX */
+
+#ifdef REG_INDEX
+# ifdef HAVE_UCONTEXT_T_UC_MCONTEXT_GREGS
+# define REGS gregs[REG_INDEX]
+# elif defined(HAVE_UCONTEXT_T_UC_MCONTEXT_UC_REGS)
+# define REGS uc_regs->gregs[REG_INDEX]
+# endif /* HAVE_UCONTEXT_T_UC_MCONTEXT_GREGS */
+#endif /* REG_INDEX */
+
+#ifdef REGS
+ if (context)
+ return (void *)(((ucontext_t *)context)->uc_mcontext.REGS);
+#elif defined(HAVE_UCONTEXT_T_UC_MCONTEXT_REGS__NIP)
+ /* older Linux / struct pt_regs ? */
+ if (context)
+ return (void *)(((ucontext_t *)context)->uc_mcontext.regs->nip);
+#endif /* REGS */
+
#endif /* HAVE_UCONTEXT_H */
return NULL;
}