|
@@ -0,0 +1,552 @@
|
|
|
+Patches for mpatrol to support uClibc and MIPS full call stack tracing
|
|
|
+by Dan Howell <dahowell@directv.com>
|
|
|
+
|
|
|
+diff -urN mpatrol/src/config.h mpatrol-uclibc/src/config.h
|
|
|
+--- mpatrol/src/config.h 2006-04-27 15:58:21.000000000 -0700
|
|
|
++++ mpatrol-uclibc/src/config.h 2006-05-05 20:32:58.000000000 -0700
|
|
|
+@@ -795,6 +795,10 @@
|
|
|
+ */
|
|
|
+
|
|
|
+ #ifndef MP_INIT_SUPPORT
|
|
|
++/* Note that machine.c currently only implements MP_INIT_SUPPORT for
|
|
|
++ * x86, 68k, 88k, and Sparc architechtures. */
|
|
|
++#if ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
|
|
|
++ ARCH == ARCH_M88K || ARCH == ARCH_SPARC
|
|
|
+ #if SYSTEM == SYSTEM_DGUX || SYSTEM == SYSTEM_DRSNX || \
|
|
|
+ SYSTEM == SYSTEM_DYNIX || SYSTEM == SYSTEM_LINUX || \
|
|
|
+ SYSTEM == SYSTEM_SOLARIS || SYSTEM == SYSTEM_UNIXWARE
|
|
|
+@@ -809,6 +813,9 @@
|
|
|
+ #else /* SYSTEM */
|
|
|
+ #define MP_INIT_SUPPORT 0
|
|
|
+ #endif /* SYSTEM */
|
|
|
++#else /* ARCH */
|
|
|
++#define MP_INIT_SUPPORT 0
|
|
|
++#endif
|
|
|
+ #endif /* MP_INIT_SUPPORT */
|
|
|
+
|
|
|
+
|
|
|
+diff -urN mpatrol/src/inter.c mpatrol-uclibc/src/inter.c
|
|
|
+--- mpatrol/src/inter.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/inter.c 2006-05-17 18:02:04.000000000 -0700
|
|
|
+@@ -79,12 +79,24 @@
|
|
|
+
|
|
|
+ #if TARGET == TARGET_UNIX
|
|
|
+ #if SYSTEM == SYSTEM_LINUX
|
|
|
++#ifndef __UCLIBC__
|
|
|
+ /* This contains a pointer to the environment variables for a process. If
|
|
|
+ * it is not set up yet then we must use sbrk() to allocate all memory since
|
|
|
+ * we can't initialise mpatrol until the environment variable can be read.
|
|
|
+ */
|
|
|
+
|
|
|
+ extern char **__environ;
|
|
|
++#else /* __UCLIBC__ */
|
|
|
++/* In uClibc, the dynamic loader calls malloc() and related functions,
|
|
|
++ * and sets __environ before these calls, so we can't use it to determine
|
|
|
++ * if we can initialize mpatrol. Instead, we use __progname, which is set
|
|
|
++ * in __uClibc_main just before before uClibc transfers control to the
|
|
|
++ * application's main() function (and static constructors, if any). Before
|
|
|
++ * this, we must use sbrk() to allocate memory.
|
|
|
++ */
|
|
|
++
|
|
|
++extern const char *__progname;
|
|
|
++#endif /* __UCLIBC__ */
|
|
|
+ #elif SYSTEM == SYSTEM_TRU64
|
|
|
+ /* The exception support library on Tru64 always allocates some memory from
|
|
|
+ * the heap in order to initialise the code address range tables. We need
|
|
|
+@@ -118,7 +130,11 @@
|
|
|
+
|
|
|
+ #if TARGET == TARGET_UNIX
|
|
|
+ #if SYSTEM == SYSTEM_LINUX
|
|
|
++#ifndef __UCLIBC__
|
|
|
+ #define crt_initialised() (__environ)
|
|
|
++#else /* __UCLIBC__ */
|
|
|
++#define crt_initialised() (__progname)
|
|
|
++#endif /* __UCLIBC__ */
|
|
|
+ #elif SYSTEM == SYSTEM_TRU64
|
|
|
+ #define crt_initialised() (__exc_crd_list_head && init_flag)
|
|
|
+ #else /* SYSTEM */
|
|
|
+@@ -306,7 +322,7 @@
|
|
|
+ alloctype t;
|
|
|
+ int c;
|
|
|
+
|
|
|
+- if (memhead.fini || (memhead.astack.size == 0))
|
|
|
++ if (memhead.fini || (memhead.astack.size == 0) || memhead.recur != 1)
|
|
|
+ return;
|
|
|
+ #if MP_FULLSTACK
|
|
|
+ /* Create the address nodes for the current call. This is not necessarily
|
|
|
+@@ -1307,7 +1323,7 @@
|
|
|
+ loginfo v;
|
|
|
+ int j;
|
|
|
+
|
|
|
+- if (!memhead.init || memhead.fini)
|
|
|
++ if (!memhead.init || memhead.fini || memhead.recur != 0)
|
|
|
+ {
|
|
|
+ __mp_memset(p, c, l);
|
|
|
+ return p;
|
|
|
+@@ -1371,7 +1387,7 @@
|
|
|
+ loginfo v;
|
|
|
+ int j;
|
|
|
+
|
|
|
+- if (!memhead.init || memhead.fini)
|
|
|
++ if (!memhead.init || memhead.fini || memhead.recur != 0)
|
|
|
+ if (f == AT_MEMCCPY)
|
|
|
+ {
|
|
|
+ if (r = __mp_memfind(p, l, &c, 1))
|
|
|
+diff -ur mpatrol/src/machine.c mpatrol-uclibc/src/machine.c
|
|
|
+--- mpatrol/src/machine.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/machine.c 2006-06-07 15:11:20.000000000 -0700
|
|
|
+@@ -217,6 +217,19 @@
|
|
|
+ .end __mp_stackpointer
|
|
|
+
|
|
|
+
|
|
|
++/* Obtain the frame pointer (s8) for the current function.
|
|
|
++ */
|
|
|
++
|
|
|
++ .text
|
|
|
++ .globl __mp_framepointer
|
|
|
++ .ent __mp_framepointer
|
|
|
++__mp_framepointer:
|
|
|
++ .frame $29,0,$31
|
|
|
++ move $2,$30
|
|
|
++ j $31
|
|
|
++ .end __mp_framepointer
|
|
|
++
|
|
|
++
|
|
|
+ /* Obtain the return address for the current function.
|
|
|
+ */
|
|
|
+
|
|
|
+diff -urN mpatrol/src/memory.c mpatrol-uclibc/src/memory.c
|
|
|
+--- mpatrol/src/memory.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/memory.c 2006-05-12 18:12:39.000000000 -0700
|
|
|
+@@ -47,7 +47,7 @@
|
|
|
+ #endif /* SYSTEM */
|
|
|
+ #include <setjmp.h>
|
|
|
+ #include <signal.h>
|
|
|
+-#if MP_SIGINFO_SUPPORT
|
|
|
++#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
|
|
|
+ #include <siginfo.h>
|
|
|
+ #endif /* MP_SIGINFO_SUPPORT */
|
|
|
+ #include <fcntl.h>
|
|
|
+diff -urN mpatrol/src/signals.c mpatrol-uclibc/src/signals.c
|
|
|
+--- mpatrol/src/signals.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/signals.c 2006-05-12 18:12:19.000000000 -0700
|
|
|
+@@ -36,7 +36,7 @@
|
|
|
+ #include <stdlib.h>
|
|
|
+ #include <signal.h>
|
|
|
+ #if TARGET == TARGET_UNIX
|
|
|
+-#if MP_SIGINFO_SUPPORT
|
|
|
++#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
|
|
|
+ #include <siginfo.h>
|
|
|
+ #endif /* MP_SIGINFO_SUPPORT */
|
|
|
+ #elif TARGET == TARGET_WINDOWS
|
|
|
+diff -urN mpatrol/src/stack.c mpatrol-uclibc/src/stack.c
|
|
|
+--- mpatrol/src/stack.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/stack.c 2006-06-22 15:39:04.000000000 -0700
|
|
|
+@@ -48,7 +48,7 @@
|
|
|
+ #else /* MP_LIBRARYSTACK_SUPPORT */
|
|
|
+ #if TARGET == TARGET_UNIX
|
|
|
+ #include <setjmp.h>
|
|
|
+-#if MP_SIGINFO_SUPPORT
|
|
|
++#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
|
|
|
+ #include <siginfo.h>
|
|
|
+ #endif /* MP_SIGINFO_SUPPORT */
|
|
|
+ #if SYSTEM == SYSTEM_DRSNX || SYSTEM == SYSTEM_SOLARIS
|
|
|
+@@ -58,6 +58,17 @@
|
|
|
+ #define R_SP REG_SP
|
|
|
+ #endif /* R_SP */
|
|
|
+ #endif /* ARCH */
|
|
|
++#elif SYSTEM == SYSTEM_LINUX
|
|
|
++#if ARCH == ARCH_MIPS
|
|
|
++#include <linux/unistd.h>
|
|
|
++/* We need the ucontext defined in asm/ucontext.h, but sys/ucontext.h
|
|
|
++ * has a conflicting definition of ucontext. So we'll trick the
|
|
|
++ * preprocessor into letting the include file define a non-conflicting
|
|
|
++ * name. */
|
|
|
++#define ucontext asm_ucontext
|
|
|
++#include <asm/ucontext.h>
|
|
|
++#undef ucontext
|
|
|
++#endif /* ARCH */
|
|
|
+ #endif /* SYSTEM */
|
|
|
+ #endif /* TARGET */
|
|
|
+ #endif /* MP_LIBRARYSTACK_SUPPORT */
|
|
|
+@@ -122,6 +133,15 @@
|
|
|
+ #define SP_OFFSET 2 /* stack pointer offset has been set */
|
|
|
+ #define SP_LOWER 4 /* lower part of stack pointer offset has been set */
|
|
|
+ #define SP_UPPER 8 /* upper part of stack pointer offset has been set */
|
|
|
++#define BR_UNCOND 16 /* unconditional branch needs to be taken */
|
|
|
++#define BR_COND 32 /* conditional branch encountered */
|
|
|
++#define RA_NOFRAME 64 /* no frame - return address is in ra register */
|
|
|
++#define SP_IN_FP 128 /* stack pointer stored in frame pointer (s8) register */
|
|
|
++
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++#define RA_SIGTRAMP 1 /* return address is a signal trampoline */
|
|
|
++#define RA_SIGRETURN 2 /* return address is in the signalled function */
|
|
|
++#endif /* SYSTEM */
|
|
|
+ #endif /* TARGET && ARCH */
|
|
|
+ #endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
|
|
|
+
|
|
|
+@@ -152,6 +172,13 @@
|
|
|
+ #endif /* SYSTEM */
|
|
|
+ #endif /* SYSTEM */
|
|
|
+ #else /* MP_LIBRARYSTACK_SUPPORT */
|
|
|
++/* On some systems, such as those using uClibc, the signal() function may
|
|
|
++ * call memcpy() or other memory related functions, so we need to guard
|
|
|
++ * against recursion.
|
|
|
++ */
|
|
|
++
|
|
|
++static unsigned char recursive;
|
|
|
++
|
|
|
+ static jmp_buf environment;
|
|
|
+ #if MP_SIGINFO_SUPPORT
|
|
|
+ static struct sigaction bushandler;
|
|
|
+@@ -261,23 +288,41 @@
|
|
|
+ int
|
|
|
+ unwind(frameinfo *f)
|
|
|
+ {
|
|
|
+- long p, s;
|
|
|
+- unsigned long a, i, q;
|
|
|
++ long p, m, s;
|
|
|
++ unsigned long a, i, q, t, b, r;
|
|
|
+ unsigned short l, u;
|
|
|
+
|
|
|
+ s = -1;
|
|
|
+- p = 0;
|
|
|
++ p = m = 0;
|
|
|
+ q = 0xFFFFFFFF;
|
|
|
+ l = u = 0;
|
|
|
+ a = 0;
|
|
|
++ t = b = 0;
|
|
|
+ /* Determine the current stack pointer and return address if we are
|
|
|
+ * initiating call stack traversal.
|
|
|
+ */
|
|
|
+ if (f->ra == 0)
|
|
|
+ {
|
|
|
+ f->sp = __mp_stackpointer();
|
|
|
++ f->fp = __mp_framepointer();
|
|
|
+ f->ra = __mp_returnaddress();
|
|
|
+ }
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++ /* Handle signal frames.
|
|
|
++ */
|
|
|
++ if (f->ra & RA_SIGRETURN)
|
|
|
++ {
|
|
|
++ /* in case of frameless function, get ra and sp from sigcontext */
|
|
|
++ p = ((struct sigcontext *) f->sp)->sc_regs[31];
|
|
|
++ f->fp = ((struct sigcontext *) f->sp)->sc_regs[30];
|
|
|
++ f->sp = ((struct sigcontext *) f->sp)->sc_regs[29];
|
|
|
++ a |= RA_NOFRAME;
|
|
|
++ }
|
|
|
++ f->ra &= ~3;
|
|
|
++#endif
|
|
|
++ /* Save initial code-reading starting point.
|
|
|
++ */
|
|
|
++ r = f->ra;
|
|
|
+ /* Search for the return address offset in the stack frame.
|
|
|
+ */
|
|
|
+ while (!((a & RA_OFFSET) && (a & SP_OFFSET)) && (f->ra < q))
|
|
|
+@@ -294,6 +339,67 @@
|
|
|
+ s = 0;
|
|
|
+ a |= SP_OFFSET;
|
|
|
+ }
|
|
|
++ else if (i == 0x03C0E821)
|
|
|
++ {
|
|
|
++ /* move sp,s8 */
|
|
|
++ a |= SP_IN_FP;
|
|
|
++ }
|
|
|
++ else if ((i >> 28 == 0x1) || (i >> 26 == 0x01))
|
|
|
++ {
|
|
|
++ /* branch */
|
|
|
++ t = f->ra + ((signed short)(i & 0xFFFF) * 4) + 4;
|
|
|
++ if ((i >> 16 == 0x1000) && !(a & BR_COND))
|
|
|
++ {
|
|
|
++ /* unconditional branch, if no conditional branch could
|
|
|
++ branch past this code */
|
|
|
++ b = t;
|
|
|
++ a |= BR_UNCOND;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ /* conditional branch, ignore if previous conditional branch
|
|
|
++ is further forwards */
|
|
|
++ if ((t > b) && (t > f->ra))
|
|
|
++ {
|
|
|
++ b = t;
|
|
|
++ a |= BR_COND;
|
|
|
++ /* can branch past an unconditional branch */
|
|
|
++ if (b > q)
|
|
|
++ q = 0xFFFFFFFF;
|
|
|
++ }
|
|
|
++ else if (t < r)
|
|
|
++ {
|
|
|
++ /* but if branching backwards, set reverse branch target to
|
|
|
++ lowest address target encountered so far */
|
|
|
++ r = t;
|
|
|
++ /* ensure a loop back */
|
|
|
++ q = 0xFFFFFFFF;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++ else if (i == 0x0000000c)
|
|
|
++ {
|
|
|
++ /* syscall - check for signal handler trampolines */
|
|
|
++ if (*((unsigned long *) (f->ra - 4)) == 0x24020000 + __NR_sigreturn)
|
|
|
++ {
|
|
|
++ /* li v0,__NR_sigreturn */
|
|
|
++ /* get pointer to sigcontext */
|
|
|
++ f->sp = f->ra + 4;
|
|
|
++ f->ra = ((struct sigcontext *) f->sp)->sc_pc | RA_SIGRETURN;
|
|
|
++ return 1;
|
|
|
++ }
|
|
|
++ else if (*((unsigned long *) (f->ra - 4)) == 0x24020000 + __NR_rt_sigreturn)
|
|
|
++ {
|
|
|
++ /* li v0,__NR_rt_sigreturn */
|
|
|
++ /* get pointer to sigcontext */
|
|
|
++ f->sp = f->ra + 4 +
|
|
|
++ sizeof(struct siginfo) + offsetof(struct asm_ucontext, uc_mcontext);
|
|
|
++ f->ra = ((struct sigcontext *) f->sp)->sc_pc | RA_SIGRETURN;
|
|
|
++ return 1;
|
|
|
++ }
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ else
|
|
|
+ switch (i >> 16)
|
|
|
+ {
|
|
|
+@@ -319,6 +425,10 @@
|
|
|
+ u = i & 0xFFFF;
|
|
|
+ a |= SP_UPPER;
|
|
|
+ break;
|
|
|
++ case 0x8FBE:
|
|
|
++ /* lw s8,##(sp) */
|
|
|
++ m = i & 0xFFFF;
|
|
|
++ break;
|
|
|
+ case 0x8FBF:
|
|
|
+ /* lw ra,##(sp) */
|
|
|
+ p = i & 0xFFFF;
|
|
|
+@@ -326,9 +436,52 @@
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ f->ra += 4;
|
|
|
++ /* Process branch instructions.
|
|
|
++ */
|
|
|
++ if (a & BR_COND)
|
|
|
++ {
|
|
|
++ if (f->ra >= b)
|
|
|
++ {
|
|
|
++ /* reached target of previous conditional branch */
|
|
|
++ a &= ~BR_COND;
|
|
|
++ b = 0;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else if (a & BR_UNCOND)
|
|
|
++ /* clear branch flag and process instruction in delay slot */
|
|
|
++ a &= ~BR_UNCOND;
|
|
|
++ else if (b != 0)
|
|
|
++ {
|
|
|
++ /* now follow the unconditional branch */
|
|
|
++ if (b < f->ra)
|
|
|
++ {
|
|
|
++ /* avoid infinite loops */
|
|
|
++ q = f->ra - 8;
|
|
|
++ /* go back as far as possible */
|
|
|
++ if (r < b)
|
|
|
++ b = r;
|
|
|
++ }
|
|
|
++ f->ra = b;
|
|
|
++ b = 0;
|
|
|
++ }
|
|
|
+ }
|
|
|
+ if ((s == 0) && ((a & SP_LOWER) || (a & SP_UPPER)))
|
|
|
+ s = (u << 16) | l;
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++ if ((a & RA_NOFRAME) && !(a & RA_OFFSET) &&
|
|
|
++ ((*((unsigned long *) (p - 8)) == 0x0320F809) ||
|
|
|
++ (*((unsigned long *) (p - 8)) >> 16 == 0x0C10)))
|
|
|
++ {
|
|
|
++ /* jalr ra,t9 or jal ## */
|
|
|
++ /* f->sp already set */
|
|
|
++ f->ra = p;
|
|
|
++ return 1;
|
|
|
++ }
|
|
|
++#endif
|
|
|
++ if (a & SP_IN_FP)
|
|
|
++ f->sp = f->fp;
|
|
|
++ if (m > 0)
|
|
|
++ f->fp = ((unsigned long *) f->sp)[m >> 2];
|
|
|
+ if ((s > 0) && (i = ((unsigned long *) f->sp)[p >> 2]) &&
|
|
|
+ ((*((unsigned long *) (i - 8)) == 0x0320F809) ||
|
|
|
+ (*((unsigned long *) (i - 8)) >> 16 == 0x0C10)))
|
|
|
+@@ -338,6 +491,19 @@
|
|
|
+ f->ra = i;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++ else if ((s > 0) && (i != 0) &&
|
|
|
++ (*((unsigned long *) (i + 4)) == 0x0000000c) &&
|
|
|
++ ((*((unsigned long *) i) == 0x24020000 + __NR_sigreturn) ||
|
|
|
++ (*((unsigned long *) i) == 0x24020000 + __NR_rt_sigreturn)))
|
|
|
++ {
|
|
|
++ /* li v0,__NR_sigreturn or __NR_rt_sigreturn ; syscall */
|
|
|
++ /* signal trampoline */
|
|
|
++ f->sp += s;
|
|
|
++ f->ra = i | RA_SIGTRAMP;
|
|
|
++ return 1;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ f->sp = f->ra = 0;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+@@ -573,16 +739,14 @@
|
|
|
+ }
|
|
|
+ #endif /* TARGET */
|
|
|
+ #else /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
|
|
|
+-#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
|
|
|
+- ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \
|
|
|
+- ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \
|
|
|
+- TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)
|
|
|
+- /* This section is not complete in any way for the OS / processor
|
|
|
+- * combinations it supports, as it is intended to be as portable as possible
|
|
|
+- * without writing in assembler. In particular, optimised code is likely
|
|
|
+- * to cause major problems for stack traversal on some platforms.
|
|
|
+- */
|
|
|
+ #if TARGET == TARGET_UNIX
|
|
|
++ /* On some systems, such as those using uClibc, the signal() function may
|
|
|
++ * call memcpy() or other memory related functions, so we need to guard
|
|
|
++ * against recursion here.
|
|
|
++ */
|
|
|
++ if (!recursive)
|
|
|
++ {
|
|
|
++ recursive = 1;
|
|
|
+ #if MP_SIGINFO_SUPPORT
|
|
|
+ i.sa_flags = 0;
|
|
|
+ (void *) i.sa_handler = (void *) stackhandler;
|
|
|
+@@ -597,6 +761,15 @@
|
|
|
+ __mp_newframe(p, p->first);
|
|
|
+ else
|
|
|
+ #endif /* TARGET */
|
|
|
++#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
|
|
|
++ ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \
|
|
|
++ ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \
|
|
|
++ TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)
|
|
|
++ /* This section is not complete in any way for the OS / processor
|
|
|
++ * combinations it supports, as it is intended to be as portable as possible
|
|
|
++ * without writing in assembler. In particular, optimised code is likely
|
|
|
++ * to cause major problems for stack traversal on some platforms.
|
|
|
++ */
|
|
|
+ {
|
|
|
+ if (p->frame == NULL)
|
|
|
+ if (p->first == NULL)
|
|
|
+@@ -640,32 +813,10 @@
|
|
|
+ r = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+-#if TARGET == TARGET_UNIX
|
|
|
+-#if MP_SIGINFO_SUPPORT
|
|
|
+- sigaction(SIGBUS, &bushandler, NULL);
|
|
|
+- sigaction(SIGSEGV, &segvhandler, NULL);
|
|
|
+-#else /* MP_SIGINFO_SUPPORT */
|
|
|
+- signal(SIGBUS, bushandler);
|
|
|
+- signal(SIGSEGV, segvhandler);
|
|
|
+-#endif /* MP_SIGINFO_SUPPORT */
|
|
|
+-#endif /* TARGET */
|
|
|
+ #elif TARGET == TARGET_UNIX && ARCH == ARCH_MIPS
|
|
|
+ /* For the MIPS architecture we perform code reading to determine the
|
|
|
+ * frame pointers and the return addresses.
|
|
|
+ */
|
|
|
+-#if MP_SIGINFO_SUPPORT
|
|
|
+- i.sa_flags = 0;
|
|
|
+- (void *) i.sa_handler = (void *) stackhandler;
|
|
|
+- sigfillset(&i.sa_mask);
|
|
|
+- sigaction(SIGBUS, &i, &bushandler);
|
|
|
+- sigaction(SIGSEGV, &i, &segvhandler);
|
|
|
+-#else /* MP_SIGINFO_SUPPORT */
|
|
|
+- bushandler = signal(SIGBUS, stackhandler);
|
|
|
+- segvhandler = signal(SIGSEGV, stackhandler);
|
|
|
+-#endif /* MP_SIGINFO_SUPPORT */
|
|
|
+- if (setjmp(environment))
|
|
|
+- __mp_newframe(p, p->first);
|
|
|
+- else
|
|
|
+ {
|
|
|
+ if (p->frame == NULL)
|
|
|
+ unwind(&p->next);
|
|
|
+@@ -673,6 +824,10 @@
|
|
|
+ {
|
|
|
+ p->frame = (void *) p->next.sp;
|
|
|
+ p->addr = (void *) (p->next.ra - 8);
|
|
|
++#if SYSTEM == SYSTEM_LINUX
|
|
|
++ if (p->next.ra & (RA_SIGTRAMP|RA_SIGRETURN))
|
|
|
++ p->addr = (void *) (p->next.ra & ~3);
|
|
|
++#endif /* SYSTEM */
|
|
|
+ r = 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+@@ -681,6 +836,8 @@
|
|
|
+ p->addr = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* TARGET && ARCH */
|
|
|
++#if TARGET == TARGET_UNIX
|
|
|
+ #if MP_SIGINFO_SUPPORT
|
|
|
+ sigaction(SIGBUS, &bushandler, NULL);
|
|
|
+ sigaction(SIGSEGV, &segvhandler, NULL);
|
|
|
+@@ -688,7 +845,9 @@
|
|
|
+ signal(SIGBUS, bushandler);
|
|
|
+ signal(SIGSEGV, segvhandler);
|
|
|
+ #endif /* MP_SIGINFO_SUPPORT */
|
|
|
+-#endif /* TARGET && ARCH */
|
|
|
++ recursive = 0;
|
|
|
++ } /* if (!bushandler) */
|
|
|
++#endif /* TARGET */
|
|
|
+ #endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+diff -ur mpatrol/src/stack.h mpatrol-uclibc/src/stack.h
|
|
|
+--- mpatrol/src/stack.h 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/stack.h 2006-06-07 15:12:58.000000000 -0700
|
|
|
+@@ -75,6 +75,7 @@
|
|
|
+ typedef struct frameinfo
|
|
|
+ {
|
|
|
+ unsigned int sp; /* stack pointer */
|
|
|
++ unsigned int fp; /* frame pointer (s8) */
|
|
|
+ unsigned int ra; /* return address */
|
|
|
+ }
|
|
|
+ frameinfo;
|
|
|
+diff -urN mpatrol/src/symbol.c mpatrol-uclibc/src/symbol.c
|
|
|
+--- mpatrol/src/symbol.c 2002-01-08 12:13:59.000000000 -0800
|
|
|
++++ mpatrol-uclibc/src/symbol.c 2006-05-24 15:43:04.000000000 -0700
|
|
|
+@@ -1157,7 +1157,7 @@
|
|
|
+ __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+- if (n == 0)
|
|
|
++ if (n <= sizeof(asymbol *))
|
|
|
+ {
|
|
|
+ /* If we couldn't find the symbol table then it is likely that the file
|
|
|
+ * has been stripped. However, if the file was dynamically linked then
|
|
|
+@@ -1172,7 +1172,7 @@
|
|
|
+ __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+- if (n == 0)
|
|
|
++ if (n <= sizeof(asymbol *))
|
|
|
+ {
|
|
|
+ m = "missing symbol table";
|
|
|
+ if (a != NULL)
|
|
|
+@@ -1893,6 +1893,17 @@
|
|
|
+ l = (dynamiclink *) *((unsigned long *) d->d_un.d_ptr + 1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
++#if ARCH == ARCH_MIPS
|
|
|
++ else if (d->d_tag == DT_MIPS_RLD_MAP)
|
|
|
++ {
|
|
|
++ /* MIPS elf has DT_MIPS_RLD_MAP instead of DT_DEBUG. */
|
|
|
++ if (!d->d_un.d_ptr || !(*(unsigned long **) d->d_un.d_ptr))
|
|
|
++ l = NULL;
|
|
|
++ else
|
|
|
++ l = (dynamiclink *) *((*(unsigned long **) d->d_un.d_ptr) + 1);
|
|
|
++ break;
|
|
|
++ }
|
|
|
++#endif /* ARCH */
|
|
|
+ /* We skip past the first item on the list since it represents the
|
|
|
+ * executable file, but we may wish to record the name of the file
|
|
|
+ * if we haven't already determined it.
|