[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)
This commit is contained in:
Joakim Tjernlund 2009-06-25 16:40:06 +01:00 committed by Daniel Walton
parent 63a2a35418
commit bccbd141d2
2 changed files with 40 additions and 4 deletions

View file

@ -580,6 +580,18 @@ AC_CHECK_HEADERS([ucontext.h], [], [],
QUAGGA_INCLUDES
])
m4_define([UCONTEXT_INCLUDES],
[#include <ucontext.h>])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

View file

@ -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;
}