From: Peter Korsgaard Date: Fri, 2 Oct 2009 11:32:23 +0000 (+0200) Subject: mpatrol: remove package X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a6fc3387268574b2ba106f932398d1f38b34849a;p=buildroot.git mpatrol: remove package It doesn't compile: ../../src/memory.c: In function '__mp_memquery': ../../src/memory.c:769: error: lvalue required as left operand of assignment And hasn't seen any updates since it got added in 2006, so it cannot have many users. People most likely use valgrind nowadays for memory debugging anyway - Drop it. Signed-off-by: Peter Korsgaard --- diff --git a/CHANGES b/CHANGES index a6e0cba70a..78dc44315f 100644 --- a/CHANGES +++ b/CHANGES @@ -8,7 +8,7 @@ openssl, python, radvd, samba, squashfs, syslinux, u-boot, xdata_xcursor-themes, - Removed package: mdnsresponder + Removed package: mdnsresponder, mpatrol Issues resolved (http://bugs.uclibc.org): diff --git a/package/Config.in b/package/Config.in index 77de7d208b..c78fd31912 100644 --- a/package/Config.in +++ b/package/Config.in @@ -41,7 +41,6 @@ source "package/gperf/Config.in" source "package/mpfr/Config.in" source "package/libtool/Config.in" source "package/m4/Config.in" -source "package/mpatrol/Config.in" source "package/oprofile/Config.in" source "package/pkg-config/Config.in" source "package/readline/Config.in" diff --git a/package/mpatrol/Config.in b/package/mpatrol/Config.in deleted file mode 100644 index 16cf1ab9ca..0000000000 --- a/package/mpatrol/Config.in +++ /dev/null @@ -1,11 +0,0 @@ -config BR2_PACKAGE_MPATROL - bool "mpatrol" - depends on BR2_PACKAGE_GDB || BR2_PACKAGE_GCC_TARGET || BR2_PACKAGE_LIBELF - - help - A debugging tool that attempts to diagnose run-time errors that are - caused by the wrong use of dynamically allocated memory. It acts as - a malloc() debugger for debugging dynamic memory allocations, although - it can also trace and profile calls to malloc() and free() too. - - http://www.cbmamiga.demon.co.uk/mpatrol/ diff --git a/package/mpatrol/mpatrol-uclibc.patch b/package/mpatrol/mpatrol-uclibc.patch deleted file mode 100644 index aab70a8768..0000000000 --- a/package/mpatrol/mpatrol-uclibc.patch +++ /dev/null @@ -1,552 +0,0 @@ -Patches for mpatrol to support uClibc and MIPS full call stack tracing -by Dan Howell - -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 - #include --#if MP_SIGINFO_SUPPORT -+#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX - #include - #endif /* MP_SIGINFO_SUPPORT */ - #include -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 - #include - #if TARGET == TARGET_UNIX --#if MP_SIGINFO_SUPPORT -+#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX - #include - #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 --#if MP_SIGINFO_SUPPORT -+#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX - #include - #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 -+/* 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 -+#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. diff --git a/package/mpatrol/mpatrol-unwindcache.patch b/package/mpatrol/mpatrol-unwindcache.patch deleted file mode 100644 index 3234d5c817..0000000000 --- a/package/mpatrol/mpatrol-unwindcache.patch +++ /dev/null @@ -1,208 +0,0 @@ -Patch to improve MIPS call stack unwind performance by caching the results -of code reading. -by Dan Howell - -diff -urN mpatrol-uclibc/src/stack.c mpatrol-unwindcache/src/stack.c ---- mpatrol-uclibc/src/stack.c 2006-06-22 15:39:04.000000000 -0700 -+++ mpatrol-unwindcache/src/stack.c 2006-06-22 15:42:20.000000000 -0700 -@@ -68,6 +68,7 @@ - #define ucontext asm_ucontext - #include - #undef ucontext -+#include "heap.h" - #endif /* ARCH */ - #endif /* SYSTEM */ - #endif /* TARGET */ -@@ -280,6 +281,136 @@ - - #if !MP_BUILTINSTACK_SUPPORT && !MP_LIBRARYSTACK_SUPPORT - #if TARGET == TARGET_UNIX && ARCH == ARCH_MIPS -+/* Set up a tree to cache the results of code searching to determine the -+ location of the return address for each code point encountered. */ -+ -+/* An unwind node belongs to a binary search tree of nodes, ordered by -+ * code address, and contains call stack unwinding details for a given -+ * code address. An internal index node stores details of a single memory -+ * block allocated for unwind node slots. -+ */ -+typedef union unwindnode -+{ -+ struct -+ { -+ treenode node; /* internal tree node */ -+ void *block; /* pointer to block of memory */ -+ size_t size; /* size of block of memory */ -+ } -+ index; -+ struct -+ { -+ treenode node; /* tree node */ -+ long p; /* return address offset in the stack */ -+ long m; /* frame pointer offset in stack */ -+ long s; /* stack pointer offset from previous frame */ -+ unsigned long a; /* flags */ -+ } -+ data; -+} -+unwindnode; -+ -+/* An unwindhead holds the table of address node slots as well as the -+ * internal list of memory blocks allocated for address node slots. -+ */ -+typedef struct unwindhead -+{ -+ heaphead heap; /* pointer to heap */ -+ slottable table; /* table of address nodes */ -+ treeroot itree; /* internal list of memory blocks */ -+ treeroot dtree; /* tree for sorting */ -+ size_t size; /* memory used by internal blocks */ -+ char init; /* initialization flag */ -+} -+unwindhead; -+ -+static unwindhead unwindcache; -+ -+/* Initialise the fields of an unwindhead so that there are no allocated, -+ * freed or free blocks. -+ */ -+ -+static -+void -+newunwindcache(void) -+{ -+ struct { char x; unwindnode y; } z; -+ long n; -+ -+ __mp_newheap(&unwindcache.heap); -+ /* Determine the minimum alignment for an unwind node on this -+ * system and force the alignment to be a power of two. This -+ * information is used when initialising the slot table. -+ */ -+ n = (char *) &z.y - &z.x; -+ __mp_newslots(&unwindcache.table, sizeof(unwindnode), __mp_poweroftwo(n)); -+ __mp_newtree(&unwindcache.itree); -+ __mp_newtree(&unwindcache.dtree); -+ unwindcache.size = 0; -+ unwindcache.init = 1; -+} -+ -+ -+/* Forget all unwind information. -+ */ -+ -+static -+void -+deleteunwindcache(void) -+{ -+ /* We don't need to explicitly free any memory as this is dealt with -+ * at a lower level by the heap manager. -+ */ -+ __mp_deleteheap(&unwindcache.heap); -+ unwindcache.table.free = NULL; -+ unwindcache.table.size = 0; -+ __mp_newtree(&unwindcache.itree); -+ __mp_newtree(&unwindcache.dtree); -+ unwindcache.size = 0; -+ unwindcache.init = 0; -+} -+ -+ -+/* Allocate a new unwind node. -+ */ -+ -+static -+unwindnode * -+getunwindnode(void) -+{ -+ unwindnode *n; -+ heapnode *p; -+ -+ /* If we have no more allocation node slots left then we must allocate -+ * some more memory for them. An extra MP_ALLOCFACTOR pages of memory -+ * should suffice. -+ */ -+ if ((n = (unwindnode *) __mp_getslot(&unwindcache.table)) == NULL) -+ { -+ if ((p = __mp_heapalloc(&unwindcache.heap, unwindcache.heap.memory.page * MP_ALLOCFACTOR, -+ unwindcache.table.entalign, 1)) == NULL) -+ return NULL; -+ __mp_initslots(&unwindcache.table, p->block, p->size); -+ n = (unwindnode *) __mp_getslot(&unwindcache.table); -+ __mp_treeinsert(&unwindcache.itree, &n->index.node, (unsigned long) p->block); -+ n->index.block = p->block; -+ n->index.size = p->size; -+ unwindcache.size += p->size; -+ n = (unwindnode *) __mp_getslot(&unwindcache.table); -+ } -+ return n; -+} -+ -+/* Search for the unwind node associated with a given address. -+ */ -+static -+unwindnode * -+findunwindnode(unsigned long p) -+{ -+ return (unwindnode *) __mp_search(unwindcache.dtree.root, p); -+} -+ -+ - /* Determine the stack pointer and return address of the previous stack frame - * by performing code reading. - */ -@@ -289,8 +420,9 @@ - unwind(frameinfo *f) - { - long p, m, s; -- unsigned long a, i, q, t, b, r; -+ unsigned long a, i, q, t, b, r, k; - unsigned short l, u; -+ unwindnode *n = NULL; - - s = -1; - p = m = 0; -@@ -322,7 +454,23 @@ - #endif - /* Save initial code-reading starting point. - */ -- r = f->ra; -+ r = k = f->ra; -+ /* Create the cache if not yet created. -+ */ -+ if (!unwindcache.init) -+ { -+ newunwindcache(); -+ __mp_atexit(deleteunwindcache); -+ } -+ if ((n = findunwindnode(f->ra)) != NULL) -+ { -+ /* We've been here before, so get the cached information. -+ */ -+ p = n->data.p; -+ m = n->data.m; -+ s = n->data.s; -+ a = n->data.a; -+ } - /* Search for the return address offset in the stack frame. - */ - while (!((a & RA_OFFSET) && (a & SP_OFFSET)) && (f->ra < q)) -@@ -478,6 +626,19 @@ - return 1; - } - #endif -+ if (n == NULL) -+ { -+ if ((n = getunwindnode()) != NULL) -+ { -+ /* Cache the information we just got in the tree. -+ */ -+ n->data.p = p; -+ n->data.m = m; -+ n->data.s = s; -+ n->data.a = a; -+ __mp_treeinsert(&unwindcache.dtree, &n->data.node, k); -+ } -+ } - if (a & SP_IN_FP) - f->sp = f->fp; - if (m > 0) diff --git a/package/mpatrol/mpatrol.mk b/package/mpatrol/mpatrol.mk deleted file mode 100644 index dd348a1e0d..0000000000 --- a/package/mpatrol/mpatrol.mk +++ /dev/null @@ -1,91 +0,0 @@ -############################################################# -# -# mpatrol -# -############################################################# -MPATROL_VERSION:=1.4.8 -MPATROL_SOURCE:=mpatrol_$(MPATROL_VERSION).tar.gz -MPATROL_SITE:=http://www.cbmamiga.demon.co.uk/mpatrol/files -MPATROL_DIR:=$(BUILD_DIR)/mpatrol -MPATROL_CAT:=$(ZCAT) -MPATROL_BINARY:=mleak -MPATROL_BUILD_DIR:=$(MPATROL_DIR)/build/unix -MPATROL_TARGET_BINARY:=usr/bin/mleak - -# Pick a symbol library to use. We have a choice of GDB BFD, binutils BFD, or libelf. -# If one of them is already being built, then use it, otherwise, default to GDB -ifeq ($(BR2_PACKAGE_GDB),y) -MPATROL_SYMBOL_LIBS:=-L$(GDB_TARGET_DIR)/bfd -lbfd -L$(GDB_TARGET_DIR)/libiberty -liberty -MPATROL_SYMBOL_INCS:=-I$(GDB_TARGET_DIR)/bfd -I$(GDB_DIR)/include -DMP_SYMBOL_LIBS= -MPATROL_SYMBOL_DEPS:=gdb_target -else -ifeq ($(BR2_PACKAGE_GCC_TARGET),y) -MPATROL_SYMBOL_LIBS:=-L$(BINUTILS_DIR2)/bfd -lbfd -L$(BINUTILS_DIR2)/libiberty -liberty -MPATROL_SYMBOL_INCS:=-I$(BINUTILS_DIR2)/bfd -I$(BINUTILS_DIR)/include -DMP_SYMBOL_LIBS= -MPATROL_SYMBOL_DEPS:=binutils_target -else -ifeq ($(BR2_PACKAGE_LIBELF),y) -MPATROL_SYMBOL_LIBS:=-L$(LIBELF_DIR)/lib -lelf -MPATROL_SYMBOL_INCS:=-I$(STAGING_DIR)/usr/include -DFORMAT=FORMAT_ELF32 -DMP_SYMBOL_LIBS= -MPATROL_SYMBOL_DEPS:=libelf -else # use GDB by default -MPATROL_SYMBOL_LIBS:=-L$(GDB_TARGET_DIR)/bfd -lbfd -L$(GDB_TARGET_DIR)/libiberty -liberty -MPATROL_SYMBOL_INCS:=-I$(GDB_TARGET_DIR)/bfd -I$(GDB_DIR)/include -DMP_SYMBOL_LIBS= -MPATROL_SYMBOL_DEPS:=gdb_target -endif -endif -endif - -$(DL_DIR)/$(MPATROL_SOURCE): - $(call DOWNLOAD,$(MPATROL_SITE),$(MPATROL_SOURCE)) - -mpatrol-source: $(DL_DIR)/$(MPATROL_SOURCE) - -$(MPATROL_DIR)/.unpacked: $(DL_DIR)/$(MPATROL_SOURCE) - $(MPATROL_CAT) $(DL_DIR)/$(MPATROL_SOURCE) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - - toolchain/patch-kernel.sh $(MPATROL_DIR) package/mpatrol mpatrol\*.patch - $(SED) '/LD.*MPTOBJS/s,$$, $$(LDLIBS),' $(MPATROL_BUILD_DIR)/Makefile - $(SED) '/CFLAGS.*=/s,$$, $$(IFLAGS),' $(MPATROL_BUILD_DIR)/Makefile - touch $(MPATROL_DIR)/.unpacked - -$(MPATROL_BUILD_DIR)/$(MPATROL_BINARY): $(MPATROL_DIR)/.unpacked - $(MAKE) CC=$(TARGET_CROSS)gcc AR=$(TARGET_CROSS)ar LD=$(TARGET_CROSS)gcc \ - IFLAGS="-g $(MPATROL_SYMBOL_INCS) -DMP_USE_ATEXIT=1 -DMP_SIGINFO_SUPPORT=1" \ - LDLIBS="$(MPATROL_SYMBOL_LIBS)" -C $(MPATROL_BUILD_DIR) all - -$(TARGET_DIR)/$(MPATROL_TARGET_BINARY): $(MPATROL_BUILD_DIR)/$(MPATROL_BINARY) - mkdir -p $(TARGET_DIR)/usr/lib - (cd $(MPATROL_BUILD_DIR); \ - cp -dpf lib*.so* $(TARGET_DIR)/usr/lib; \ - cp -dpf mpatrol mprof mptrace mleak $(TARGET_DIR)/usr/bin) - if [ ! -e $(TARGET_DIR)/lib/libpthread.so ]; then \ - ln -sf libpthread.so.0 $(TARGET_DIR)/lib/libpthread.so; fi - (cd $(MPATROL_DIR); \ - cp -dpf bin/mp* bin/hexwords $(TARGET_DIR)/usr/bin; \ - cp -dpf src/mp*.h $(STAGING_DIR)/usr/include; \ - mkdir -p $(STAGING_DIR)/usr/include/mpatrol; \ - cp -dpf tools/*.h $(STAGING_DIR)/usr/include/mpatrol) - touch $(TARGET_DIR)/$(MPATROL_TARGET_BINARY) - -mpatrol: $(MPATROL_SYMBOL_DEPS) $(TARGET_DIR)/$(MPATROL_TARGET_BINARY) - -mpatrol-clean: - (cd $(TARGET_DIR)/usr/lib; rm -f libmpatrol* libmpalloc*) - (cd $(TARGET_DIR)/usr/bin; \ - rm -f mpatrol mprof mptrace mleak mpsym mpedit hexwords) - (cd $(STAGING_DIR)/usr/include; \ - rm -rf mpatrol.h mpalloc.h mpdebug.h mpatrol) - $(MAKE) -C $(MPATROL_DIR)/build/unix clobber - -mpatrol-dirclean: - rm -rf $(MPATROL_DIR) - - -############################################################# -# -# Toplevel Makefile options -# -############################################################# -ifeq ($(BR2_PACKAGE_MPATROL),y) -TARGETS+=mpatrol -endif