fix copy'n paste error
[buildroot.git] / package / mpatrol / mpatrol-uclibc.patch
blobaab70a87687824a9cad2fbca7f58fb26f6327753
1 Patches for mpatrol to support uClibc and MIPS full call stack tracing
2 by Dan Howell <dahowell@directv.com>
4 diff -urN mpatrol/src/config.h mpatrol-uclibc/src/config.h
5 --- mpatrol/src/config.h 2006-04-27 15:58:21.000000000 -0700
6 +++ mpatrol-uclibc/src/config.h 2006-05-05 20:32:58.000000000 -0700
7 @@ -795,6 +795,10 @@
8 */
10 #ifndef MP_INIT_SUPPORT
11 +/* Note that machine.c currently only implements MP_INIT_SUPPORT for
12 + * x86, 68k, 88k, and Sparc architechtures. */
13 +#if ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
14 + ARCH == ARCH_M88K || ARCH == ARCH_SPARC
15 #if SYSTEM == SYSTEM_DGUX || SYSTEM == SYSTEM_DRSNX || \
16 SYSTEM == SYSTEM_DYNIX || SYSTEM == SYSTEM_LINUX || \
17 SYSTEM == SYSTEM_SOLARIS || SYSTEM == SYSTEM_UNIXWARE
18 @@ -809,6 +813,9 @@
19 #else /* SYSTEM */
20 #define MP_INIT_SUPPORT 0
21 #endif /* SYSTEM */
22 +#else /* ARCH */
23 +#define MP_INIT_SUPPORT 0
24 +#endif
25 #endif /* MP_INIT_SUPPORT */
28 diff -urN mpatrol/src/inter.c mpatrol-uclibc/src/inter.c
29 --- mpatrol/src/inter.c 2002-01-08 12:13:59.000000000 -0800
30 +++ mpatrol-uclibc/src/inter.c 2006-05-17 18:02:04.000000000 -0700
31 @@ -79,12 +79,24 @@
33 #if TARGET == TARGET_UNIX
34 #if SYSTEM == SYSTEM_LINUX
35 +#ifndef __UCLIBC__
36 /* This contains a pointer to the environment variables for a process. If
37 * it is not set up yet then we must use sbrk() to allocate all memory since
38 * we can't initialise mpatrol until the environment variable can be read.
41 extern char **__environ;
42 +#else /* __UCLIBC__ */
43 +/* In uClibc, the dynamic loader calls malloc() and related functions,
44 + * and sets __environ before these calls, so we can't use it to determine
45 + * if we can initialize mpatrol. Instead, we use __progname, which is set
46 + * in __uClibc_main just before before uClibc transfers control to the
47 + * application's main() function (and static constructors, if any). Before
48 + * this, we must use sbrk() to allocate memory.
49 + */
51 +extern const char *__progname;
52 +#endif /* __UCLIBC__ */
53 #elif SYSTEM == SYSTEM_TRU64
54 /* The exception support library on Tru64 always allocates some memory from
55 * the heap in order to initialise the code address range tables. We need
56 @@ -118,7 +130,11 @@
58 #if TARGET == TARGET_UNIX
59 #if SYSTEM == SYSTEM_LINUX
60 +#ifndef __UCLIBC__
61 #define crt_initialised() (__environ)
62 +#else /* __UCLIBC__ */
63 +#define crt_initialised() (__progname)
64 +#endif /* __UCLIBC__ */
65 #elif SYSTEM == SYSTEM_TRU64
66 #define crt_initialised() (__exc_crd_list_head && init_flag)
67 #else /* SYSTEM */
68 @@ -306,7 +322,7 @@
69 alloctype t;
70 int c;
72 - if (memhead.fini || (memhead.astack.size == 0))
73 + if (memhead.fini || (memhead.astack.size == 0) || memhead.recur != 1)
74 return;
75 #if MP_FULLSTACK
76 /* Create the address nodes for the current call. This is not necessarily
77 @@ -1307,7 +1323,7 @@
78 loginfo v;
79 int j;
81 - if (!memhead.init || memhead.fini)
82 + if (!memhead.init || memhead.fini || memhead.recur != 0)
84 __mp_memset(p, c, l);
85 return p;
86 @@ -1371,7 +1387,7 @@
87 loginfo v;
88 int j;
90 - if (!memhead.init || memhead.fini)
91 + if (!memhead.init || memhead.fini || memhead.recur != 0)
92 if (f == AT_MEMCCPY)
94 if (r = __mp_memfind(p, l, &c, 1))
95 diff -ur mpatrol/src/machine.c mpatrol-uclibc/src/machine.c
96 --- mpatrol/src/machine.c 2002-01-08 12:13:59.000000000 -0800
97 +++ mpatrol-uclibc/src/machine.c 2006-06-07 15:11:20.000000000 -0700
98 @@ -217,6 +217,19 @@
99 .end __mp_stackpointer
102 +/* Obtain the frame pointer (s8) for the current function.
103 + */
105 + .text
106 + .globl __mp_framepointer
107 + .ent __mp_framepointer
108 +__mp_framepointer:
109 + .frame $29,0,$31
110 + move $2,$30
111 + j $31
112 + .end __mp_framepointer
115 /* Obtain the return address for the current function.
118 diff -urN mpatrol/src/memory.c mpatrol-uclibc/src/memory.c
119 --- mpatrol/src/memory.c 2002-01-08 12:13:59.000000000 -0800
120 +++ mpatrol-uclibc/src/memory.c 2006-05-12 18:12:39.000000000 -0700
121 @@ -47,7 +47,7 @@
122 #endif /* SYSTEM */
123 #include <setjmp.h>
124 #include <signal.h>
125 -#if MP_SIGINFO_SUPPORT
126 +#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
127 #include <siginfo.h>
128 #endif /* MP_SIGINFO_SUPPORT */
129 #include <fcntl.h>
130 diff -urN mpatrol/src/signals.c mpatrol-uclibc/src/signals.c
131 --- mpatrol/src/signals.c 2002-01-08 12:13:59.000000000 -0800
132 +++ mpatrol-uclibc/src/signals.c 2006-05-12 18:12:19.000000000 -0700
133 @@ -36,7 +36,7 @@
134 #include <stdlib.h>
135 #include <signal.h>
136 #if TARGET == TARGET_UNIX
137 -#if MP_SIGINFO_SUPPORT
138 +#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
139 #include <siginfo.h>
140 #endif /* MP_SIGINFO_SUPPORT */
141 #elif TARGET == TARGET_WINDOWS
142 diff -urN mpatrol/src/stack.c mpatrol-uclibc/src/stack.c
143 --- mpatrol/src/stack.c 2002-01-08 12:13:59.000000000 -0800
144 +++ mpatrol-uclibc/src/stack.c 2006-06-22 15:39:04.000000000 -0700
145 @@ -48,7 +48,7 @@
146 #else /* MP_LIBRARYSTACK_SUPPORT */
147 #if TARGET == TARGET_UNIX
148 #include <setjmp.h>
149 -#if MP_SIGINFO_SUPPORT
150 +#if MP_SIGINFO_SUPPORT && SYSTEM != SYSTEM_LINUX
151 #include <siginfo.h>
152 #endif /* MP_SIGINFO_SUPPORT */
153 #if SYSTEM == SYSTEM_DRSNX || SYSTEM == SYSTEM_SOLARIS
154 @@ -58,6 +58,17 @@
155 #define R_SP REG_SP
156 #endif /* R_SP */
157 #endif /* ARCH */
158 +#elif SYSTEM == SYSTEM_LINUX
159 +#if ARCH == ARCH_MIPS
160 +#include <linux/unistd.h>
161 +/* We need the ucontext defined in asm/ucontext.h, but sys/ucontext.h
162 + * has a conflicting definition of ucontext. So we'll trick the
163 + * preprocessor into letting the include file define a non-conflicting
164 + * name. */
165 +#define ucontext asm_ucontext
166 +#include <asm/ucontext.h>
167 +#undef ucontext
168 +#endif /* ARCH */
169 #endif /* SYSTEM */
170 #endif /* TARGET */
171 #endif /* MP_LIBRARYSTACK_SUPPORT */
172 @@ -122,6 +133,15 @@
173 #define SP_OFFSET 2 /* stack pointer offset has been set */
174 #define SP_LOWER 4 /* lower part of stack pointer offset has been set */
175 #define SP_UPPER 8 /* upper part of stack pointer offset has been set */
176 +#define BR_UNCOND 16 /* unconditional branch needs to be taken */
177 +#define BR_COND 32 /* conditional branch encountered */
178 +#define RA_NOFRAME 64 /* no frame - return address is in ra register */
179 +#define SP_IN_FP 128 /* stack pointer stored in frame pointer (s8) register */
181 +#if SYSTEM == SYSTEM_LINUX
182 +#define RA_SIGTRAMP 1 /* return address is a signal trampoline */
183 +#define RA_SIGRETURN 2 /* return address is in the signalled function */
184 +#endif /* SYSTEM */
185 #endif /* TARGET && ARCH */
186 #endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
188 @@ -152,6 +172,13 @@
189 #endif /* SYSTEM */
190 #endif /* SYSTEM */
191 #else /* MP_LIBRARYSTACK_SUPPORT */
192 +/* On some systems, such as those using uClibc, the signal() function may
193 + * call memcpy() or other memory related functions, so we need to guard
194 + * against recursion.
195 + */
197 +static unsigned char recursive;
199 static jmp_buf environment;
200 #if MP_SIGINFO_SUPPORT
201 static struct sigaction bushandler;
202 @@ -261,23 +288,41 @@
204 unwind(frameinfo *f)
206 - long p, s;
207 - unsigned long a, i, q;
208 + long p, m, s;
209 + unsigned long a, i, q, t, b, r;
210 unsigned short l, u;
212 s = -1;
213 - p = 0;
214 + p = m = 0;
215 q = 0xFFFFFFFF;
216 l = u = 0;
217 a = 0;
218 + t = b = 0;
219 /* Determine the current stack pointer and return address if we are
220 * initiating call stack traversal.
222 if (f->ra == 0)
224 f->sp = __mp_stackpointer();
225 + f->fp = __mp_framepointer();
226 f->ra = __mp_returnaddress();
228 +#if SYSTEM == SYSTEM_LINUX
229 + /* Handle signal frames.
230 + */
231 + if (f->ra & RA_SIGRETURN)
233 + /* in case of frameless function, get ra and sp from sigcontext */
234 + p = ((struct sigcontext *) f->sp)->sc_regs[31];
235 + f->fp = ((struct sigcontext *) f->sp)->sc_regs[30];
236 + f->sp = ((struct sigcontext *) f->sp)->sc_regs[29];
237 + a |= RA_NOFRAME;
239 + f->ra &= ~3;
240 +#endif
241 + /* Save initial code-reading starting point.
242 + */
243 + r = f->ra;
244 /* Search for the return address offset in the stack frame.
246 while (!((a & RA_OFFSET) && (a & SP_OFFSET)) && (f->ra < q))
247 @@ -294,6 +339,67 @@
248 s = 0;
249 a |= SP_OFFSET;
251 + else if (i == 0x03C0E821)
253 + /* move sp,s8 */
254 + a |= SP_IN_FP;
256 + else if ((i >> 28 == 0x1) || (i >> 26 == 0x01))
258 + /* branch */
259 + t = f->ra + ((signed short)(i & 0xFFFF) * 4) + 4;
260 + if ((i >> 16 == 0x1000) && !(a & BR_COND))
262 + /* unconditional branch, if no conditional branch could
263 + branch past this code */
264 + b = t;
265 + a |= BR_UNCOND;
267 + else
269 + /* conditional branch, ignore if previous conditional branch
270 + is further forwards */
271 + if ((t > b) && (t > f->ra))
273 + b = t;
274 + a |= BR_COND;
275 + /* can branch past an unconditional branch */
276 + if (b > q)
277 + q = 0xFFFFFFFF;
279 + else if (t < r)
281 + /* but if branching backwards, set reverse branch target to
282 + lowest address target encountered so far */
283 + r = t;
284 + /* ensure a loop back */
285 + q = 0xFFFFFFFF;
289 +#if SYSTEM == SYSTEM_LINUX
290 + else if (i == 0x0000000c)
292 + /* syscall - check for signal handler trampolines */
293 + if (*((unsigned long *) (f->ra - 4)) == 0x24020000 + __NR_sigreturn)
295 + /* li v0,__NR_sigreturn */
296 + /* get pointer to sigcontext */
297 + f->sp = f->ra + 4;
298 + f->ra = ((struct sigcontext *) f->sp)->sc_pc | RA_SIGRETURN;
299 + return 1;
301 + else if (*((unsigned long *) (f->ra - 4)) == 0x24020000 + __NR_rt_sigreturn)
303 + /* li v0,__NR_rt_sigreturn */
304 + /* get pointer to sigcontext */
305 + f->sp = f->ra + 4 +
306 + sizeof(struct siginfo) + offsetof(struct asm_ucontext, uc_mcontext);
307 + f->ra = ((struct sigcontext *) f->sp)->sc_pc | RA_SIGRETURN;
308 + return 1;
311 +#endif
312 else
313 switch (i >> 16)
315 @@ -319,6 +425,10 @@
316 u = i & 0xFFFF;
317 a |= SP_UPPER;
318 break;
319 + case 0x8FBE:
320 + /* lw s8,##(sp) */
321 + m = i & 0xFFFF;
322 + break;
323 case 0x8FBF:
324 /* lw ra,##(sp) */
325 p = i & 0xFFFF;
326 @@ -326,9 +436,52 @@
327 break;
329 f->ra += 4;
330 + /* Process branch instructions.
331 + */
332 + if (a & BR_COND)
334 + if (f->ra >= b)
336 + /* reached target of previous conditional branch */
337 + a &= ~BR_COND;
338 + b = 0;
341 + else if (a & BR_UNCOND)
342 + /* clear branch flag and process instruction in delay slot */
343 + a &= ~BR_UNCOND;
344 + else if (b != 0)
346 + /* now follow the unconditional branch */
347 + if (b < f->ra)
349 + /* avoid infinite loops */
350 + q = f->ra - 8;
351 + /* go back as far as possible */
352 + if (r < b)
353 + b = r;
355 + f->ra = b;
356 + b = 0;
359 if ((s == 0) && ((a & SP_LOWER) || (a & SP_UPPER)))
360 s = (u << 16) | l;
361 +#if SYSTEM == SYSTEM_LINUX
362 + if ((a & RA_NOFRAME) && !(a & RA_OFFSET) &&
363 + ((*((unsigned long *) (p - 8)) == 0x0320F809) ||
364 + (*((unsigned long *) (p - 8)) >> 16 == 0x0C10)))
366 + /* jalr ra,t9 or jal ## */
367 + /* f->sp already set */
368 + f->ra = p;
369 + return 1;
371 +#endif
372 + if (a & SP_IN_FP)
373 + f->sp = f->fp;
374 + if (m > 0)
375 + f->fp = ((unsigned long *) f->sp)[m >> 2];
376 if ((s > 0) && (i = ((unsigned long *) f->sp)[p >> 2]) &&
377 ((*((unsigned long *) (i - 8)) == 0x0320F809) ||
378 (*((unsigned long *) (i - 8)) >> 16 == 0x0C10)))
379 @@ -338,6 +491,19 @@
380 f->ra = i;
381 return 1;
383 +#if SYSTEM == SYSTEM_LINUX
384 + else if ((s > 0) && (i != 0) &&
385 + (*((unsigned long *) (i + 4)) == 0x0000000c) &&
386 + ((*((unsigned long *) i) == 0x24020000 + __NR_sigreturn) ||
387 + (*((unsigned long *) i) == 0x24020000 + __NR_rt_sigreturn)))
389 + /* li v0,__NR_sigreturn or __NR_rt_sigreturn ; syscall */
390 + /* signal trampoline */
391 + f->sp += s;
392 + f->ra = i | RA_SIGTRAMP;
393 + return 1;
395 +#endif
396 f->sp = f->ra = 0;
397 return 0;
399 @@ -573,16 +739,14 @@
401 #endif /* TARGET */
402 #else /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
403 -#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
404 - ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \
405 - ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \
406 - TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)
407 - /* This section is not complete in any way for the OS / processor
408 - * combinations it supports, as it is intended to be as portable as possible
409 - * without writing in assembler. In particular, optimised code is likely
410 - * to cause major problems for stack traversal on some platforms.
411 - */
412 #if TARGET == TARGET_UNIX
413 + /* On some systems, such as those using uClibc, the signal() function may
414 + * call memcpy() or other memory related functions, so we need to guard
415 + * against recursion here.
416 + */
417 + if (!recursive)
419 + recursive = 1;
420 #if MP_SIGINFO_SUPPORT
421 i.sa_flags = 0;
422 (void *) i.sa_handler = (void *) stackhandler;
423 @@ -597,6 +761,15 @@
424 __mp_newframe(p, p->first);
425 else
426 #endif /* TARGET */
427 +#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \
428 + ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \
429 + ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \
430 + TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)
431 + /* This section is not complete in any way for the OS / processor
432 + * combinations it supports, as it is intended to be as portable as possible
433 + * without writing in assembler. In particular, optimised code is likely
434 + * to cause major problems for stack traversal on some platforms.
435 + */
437 if (p->frame == NULL)
438 if (p->first == NULL)
439 @@ -640,32 +813,10 @@
440 r = 1;
443 -#if TARGET == TARGET_UNIX
444 -#if MP_SIGINFO_SUPPORT
445 - sigaction(SIGBUS, &bushandler, NULL);
446 - sigaction(SIGSEGV, &segvhandler, NULL);
447 -#else /* MP_SIGINFO_SUPPORT */
448 - signal(SIGBUS, bushandler);
449 - signal(SIGSEGV, segvhandler);
450 -#endif /* MP_SIGINFO_SUPPORT */
451 -#endif /* TARGET */
452 #elif TARGET == TARGET_UNIX && ARCH == ARCH_MIPS
453 /* For the MIPS architecture we perform code reading to determine the
454 * frame pointers and the return addresses.
456 -#if MP_SIGINFO_SUPPORT
457 - i.sa_flags = 0;
458 - (void *) i.sa_handler = (void *) stackhandler;
459 - sigfillset(&i.sa_mask);
460 - sigaction(SIGBUS, &i, &bushandler);
461 - sigaction(SIGSEGV, &i, &segvhandler);
462 -#else /* MP_SIGINFO_SUPPORT */
463 - bushandler = signal(SIGBUS, stackhandler);
464 - segvhandler = signal(SIGSEGV, stackhandler);
465 -#endif /* MP_SIGINFO_SUPPORT */
466 - if (setjmp(environment))
467 - __mp_newframe(p, p->first);
468 - else
470 if (p->frame == NULL)
471 unwind(&p->next);
472 @@ -673,6 +824,10 @@
474 p->frame = (void *) p->next.sp;
475 p->addr = (void *) (p->next.ra - 8);
476 +#if SYSTEM == SYSTEM_LINUX
477 + if (p->next.ra & (RA_SIGTRAMP|RA_SIGRETURN))
478 + p->addr = (void *) (p->next.ra & ~3);
479 +#endif /* SYSTEM */
480 r = 1;
482 else
483 @@ -681,6 +836,8 @@
484 p->addr = NULL;
487 +#endif /* TARGET && ARCH */
488 +#if TARGET == TARGET_UNIX
489 #if MP_SIGINFO_SUPPORT
490 sigaction(SIGBUS, &bushandler, NULL);
491 sigaction(SIGSEGV, &segvhandler, NULL);
492 @@ -688,7 +845,9 @@
493 signal(SIGBUS, bushandler);
494 signal(SIGSEGV, segvhandler);
495 #endif /* MP_SIGINFO_SUPPORT */
496 -#endif /* TARGET && ARCH */
497 + recursive = 0;
498 + } /* if (!bushandler) */
499 +#endif /* TARGET */
500 #endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */
501 return r;
503 diff -ur mpatrol/src/stack.h mpatrol-uclibc/src/stack.h
504 --- mpatrol/src/stack.h 2002-01-08 12:13:59.000000000 -0800
505 +++ mpatrol-uclibc/src/stack.h 2006-06-07 15:12:58.000000000 -0700
506 @@ -75,6 +75,7 @@
507 typedef struct frameinfo
509 unsigned int sp; /* stack pointer */
510 + unsigned int fp; /* frame pointer (s8) */
511 unsigned int ra; /* return address */
513 frameinfo;
514 diff -urN mpatrol/src/symbol.c mpatrol-uclibc/src/symbol.c
515 --- mpatrol/src/symbol.c 2002-01-08 12:13:59.000000000 -0800
516 +++ mpatrol-uclibc/src/symbol.c 2006-05-24 15:43:04.000000000 -0700
517 @@ -1157,7 +1157,7 @@
518 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
519 return 0;
521 - if (n == 0)
522 + if (n <= sizeof(asymbol *))
524 /* If we couldn't find the symbol table then it is likely that the file
525 * has been stripped. However, if the file was dynamically linked then
526 @@ -1172,7 +1172,7 @@
527 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
528 return 0;
530 - if (n == 0)
531 + if (n <= sizeof(asymbol *))
533 m = "missing symbol table";
534 if (a != NULL)
535 @@ -1893,6 +1893,17 @@
536 l = (dynamiclink *) *((unsigned long *) d->d_un.d_ptr + 1);
537 break;
539 +#if ARCH == ARCH_MIPS
540 + else if (d->d_tag == DT_MIPS_RLD_MAP)
542 + /* MIPS elf has DT_MIPS_RLD_MAP instead of DT_DEBUG. */
543 + if (!d->d_un.d_ptr || !(*(unsigned long **) d->d_un.d_ptr))
544 + l = NULL;
545 + else
546 + l = (dynamiclink *) *((*(unsigned long **) d->d_un.d_ptr) + 1);
547 + break;
549 +#endif /* ARCH */
550 /* We skip past the first item on the list since it represents the
551 * executable file, but we may wish to record the name of the file
552 * if we haven't already determined it.