From bccbd141d242c1c57e73c3213371b80779377419 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 25 Jun 2009 16:40:06 +0100 Subject: [PATCH] [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) --- configure.ac | 12 ++++++++++++ lib/sigevent.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 852b63d6ae..5461e362be 100755 --- a/configure.ac +++ b/configure.ac @@ -580,6 +580,18 @@ AC_CHECK_HEADERS([ucontext.h], [], [], QUAGGA_INCLUDES ]) +m4_define([UCONTEXT_INCLUDES], +[#include ])dnl + +AC_CHECK_MEMBERS([ucontext_t.uc_mcontext.uc_regs], + [], [], [UCONTEXT_INCLUDES]) +AC_CHECK_MEMBERS([ucontext_t.uc_mcontext.regs], + [AC_CHECK_MEMBERS([ucontext_t.uc_mcontext.regs.nip], + [], [], [UCONTEXT_INCLUDES])], + [], [UCONTEXT_INCLUDES]) +AC_CHECK_MEMBERS([ucontext_t.uc_mcontext.gregs], + [], [], [UCONTEXT_INCLUDES]) + m4_define([QUAGGA_INCLUDES], QUAGGA_INCLUDES [#if HAVE_SYS_UN_H 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; } -- 2.39.5