diff --git a/Tools/WAD/Include/wad.h b/Tools/WAD/Include/wad.h index 7426d396f..3bbcf668a 100644 --- a/Tools/WAD/Include/wad.h +++ b/Tools/WAD/Include/wad.h @@ -89,9 +89,9 @@ extern void wad_elf_debug(WadObjectFile *wo); typedef struct WadParm { char name[64]; - int loc; - int type; - int value; + int loc; /* Location: register or stack */ + int type; /* Argument type */ + int value; /* Argument position from stabs */ } WadParm; /* Debugging information */ @@ -176,6 +176,7 @@ extern WadReturnFunc *wad_check_return(const char *name); #define DEBUG_INIT 0x100 #define DEBUG_NOSTACK 0x200 #define DEBUG_ONESHOT 0x400 +#define DEBUG_STACK 0x800 extern int wad_debug_mode; diff --git a/Tools/WAD/Wad/default.c b/Tools/WAD/Wad/default.c index 7d0c4eddf..9d45777e6 100644 --- a/Tools/WAD/Wad/default.c +++ b/Tools/WAD/Wad/default.c @@ -27,16 +27,12 @@ char *wad_arg_string(WadFrame *frame) { int i; WadFrame *nf; -#ifdef WAD_LINUX - strcat(str,""); - return str; -#endif - - if (frame->size) + if (frame->size) { nf = (WadFrame *) (((char *) frame) + frame->size); - else + if (nf->size == 0) nf = 0; + } else { nf = 0; - + } if (nf) nextstack = STACK(nf); else @@ -45,17 +41,25 @@ char *wad_arg_string(WadFrame *frame) { str[0] = 0; stack = STACK(frame); +#ifdef WAD_LINUX + if (!nf) { + return ""; + } +#endif + if (frame->nargs < 0) { - /* No argument information is available. In this case - we will simply dump the %in registers. (assuming we can - find them) */ + /* No argument information is available. If we are on SPARC, we'll dump + the %in registers since these usually hold input parameters. On + Linux, we do nothing */ +#ifdef WAD_SOLARIS for (i = 0; i < 6; i++) { sprintf(temp,"0x%x", stack[8+i]); strcat(str,temp); if (i < 5) strcat(str,","); } +#endif } else { /* We were able to get some argument information out the debugging table */ wp = ARGUMENTS(frame); @@ -80,6 +84,7 @@ char *wad_arg_string(WadFrame *frame) { } } } else if (wp->loc == PARM_REGISTER) { +#ifdef WAD_SOLARIS if ((wp->value >= 24) && (wp->value < 32)) { /* Value is located in the %in registers */ sprintf(temp,"0x%x", stack[wp->value - 16]); @@ -93,6 +98,10 @@ char *wad_arg_string(WadFrame *frame) { sprintf(temp,"0x%x", frame->regs[wp->value - 16]); strcat(str,temp); } +#endif +#ifdef WAD_LINUX + strcat(str,"?"); +#endif } if (i < (frame->nargs-1)) strcat(str,","); } diff --git a/Tools/WAD/Wad/init.c b/Tools/WAD/Wad/init.c index ff8ff77ef..380c20d32 100644 --- a/Tools/WAD/Wad/init.c +++ b/Tools/WAD/Wad/init.c @@ -54,6 +54,10 @@ void wad_init() { wad_debug_mode |= DEBUG_INIT; } + if (getenv("WAD_DEBUG_STACK")) { + wad_debug_mode |= DEBUG_STACK; + } + if (getenv("WAD_NOSTACK")) { wad_debug_mode |= DEBUG_NOSTACK; } diff --git a/Tools/WAD/Wad/signal.c b/Tools/WAD/Wad/signal.c index 4f6e3c54b..b5f430a14 100644 --- a/Tools/WAD/Wad/signal.c +++ b/Tools/WAD/Wad/signal.c @@ -133,7 +133,36 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { /* We're really hosed here */ return; } - + + if (wad_debug_mode & DEBUG_STACK) { + /* Walk the exception frames and try to find a return point */ + framedata = (char *) frame; + + while (frame->size) { + int i; + WadParm *p; + /* Print out detailed stack trace information */ + printf("::: Stack frame - 0x%08x :::\n", frame); + printf(" sp = %x\n", frame->sp); + printf(" fp = %x\n", frame->fp); + printf(" size = %x\n", frame->stack_size); + printf(" pc = %x\n", frame->pc); + printf(" symbol = '%s'\n", SYMBOL(frame)); + printf(" srcfile = '%s'\n", SRCFILE(frame)); + printf(" objfile = '%s'\n", OBJFILE(frame)); + printf(" numargs = %d\n", frame->nargs); + printf(" arguments [\n"); + p = ARGUMENTS(frame); + for (i = 0; i < frame->nargs; i++, p++) { + printf(" arg[%d] : name = '%s', loc = %d, type = %d, value = %d\n", i, p->name, p->loc, p->type, p->value); + } + printf(" ]\n"); + framedata = framedata + frame->size; + frame = (WadFrame *) framedata; + } + frame = origframe; + } + /* Walk the exception frames and try to find a return point */ framedata = (char *) frame; diff --git a/Tools/WAD/Wad/stab.c b/Tools/WAD/Wad/stab.c index df1273f2b..b8b0f7949 100644 --- a/Tools/WAD/Wad/stab.c +++ b/Tools/WAD/Wad/stab.c @@ -158,18 +158,36 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon one identifies its location for the debugger */ if (debug->nargs > 0) { - if (strcmp(debug->parms[debug->nargs-1].name, pname) == 0) - debug->nargs--; + /* Need to do some fix up for linux here */ + int i; + for (i = 0; i < debug->nargs; i++) { + if ((strncmp(debug->parms[i].name, pname,len) == 0) && (strlen(debug->parms[i].name) == len)) { + /* We already saw this argument. Given a choice between a register and a stack + argument. We will choose the stack version */ + if (debug->parms[i].loc == PARM_STACK) { + break; + } + /* Go ahead and use the new argument */ + if (s->n_type == 0x40) + debug->parms[i].loc = PARM_REGISTER; + else + debug->parms[i].loc = PARM_STACK; + debug->parms[i].value = s->n_value; + break; + } + } + if (i < debug->nargs) continue; /* We got an argument match. Just skip to next stab */ } + strncpy(debug->parms[debug->nargs].name,pname,len); debug->parms[debug->nargs].name[len] = 0; - if (s->n_type == 0x40) debug->parms[debug->nargs].loc = PARM_REGISTER; else debug->parms[debug->nargs].loc = PARM_STACK; debug->parms[debug->nargs].value = s->n_value; + debug->parms[debug->nargs].type = 0; /* Not used yet */ debug->nargs++; } } diff --git a/Tools/WAD/Wad/stack.c b/Tools/WAD/Wad/stack.c index 2ecaaaed9..ea43fa7e0 100644 --- a/Tools/WAD/Wad/stack.c +++ b/Tools/WAD/Wad/stack.c @@ -177,6 +177,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) { firstframe = 0; /* Determine stack frame size */ p_lastsp = p_sp; + stack_unwind(&p_sp, &p_pc, &p_fp); if (p_sp) { @@ -190,7 +191,9 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) { #endif } /* Set the frame pointer and stack size */ - frame.fp = p_sp; + + /* frame.fp = p_sp; */ + frame.fp = p_sp; frame.stack_size = stacksize; /* Build the exception frame object we'll write */ @@ -215,6 +218,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) { frame.src_off = frame.sym_off + symsize; frame.obj_off = frame.src_off + srcsize; } + write(ffile,&frame,sizeof(WadFrame)); /* Write the argument data */ if (argsize > 0) { @@ -315,3 +319,4 @@ long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) { *error = -1; return 0; } +