diff --git a/Tools/WAD/Include/wad.h b/Tools/WAD/Include/wad.h index 0c457c440..82da49f51 100644 --- a/Tools/WAD/Include/wad.h +++ b/Tools/WAD/Include/wad.h @@ -107,6 +107,7 @@ typedef struct WadObjectFile { extern void wad_object_reset(); extern WadObjectFile *wad_object_load(const char *path); +extern int wad_file_check(void *); #define SYM_LOCAL 1 #define SYM_GLOBAL 2 diff --git a/Tools/WAD/Wad/default.c b/Tools/WAD/Wad/default.c index 22656e56b..2fd393c30 100644 --- a/Tools/WAD/Wad/default.c +++ b/Tools/WAD/Wad/default.c @@ -71,7 +71,7 @@ char *wad_arg_string(WadFrame *frame) { #ifdef WAD_SOLARIS for (i = 0; i < 6; i++) { wad_strcat(str,"0x"); - wad_strcat(str,wad_format_hex(stack[8+1],0)); + wad_strcat(str,wad_format_hex((unsigned long) stack[8+i],0)); if (i < 5) wad_strcat(str,","); } diff --git a/Tools/WAD/Wad/elf.c b/Tools/WAD/Wad/elf.c index 897b27b77..334133d80 100644 --- a/Tools/WAD/Wad/elf.c +++ b/Tools/WAD/Wad/elf.c @@ -317,6 +317,7 @@ wad_elf_debug_info(WadFrame *f) { stab = wad_elf_section_data(f->object,nstab); stabsize = wad_elf_section_size(f->object,nstab); stabstr = (char *) wad_elf_section_data(f->object,nstabstr); + if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; } @@ -327,18 +328,22 @@ wad_elf_debug_info(WadFrame *f) { stab = wad_elf_section_data(f->object,nstabexcl); stabsize = wad_elf_section_size(f->object, nstabexcl); stabstr = (char *) wad_elf_section_data(f->object, nstabexclstr); + if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; } /* Look in the .stab.index section. A Solaris oddity? */ if (nstabindex > 0) { + stab = wad_elf_section_data(f->object,nstabindex); stabsize = wad_elf_section_size(f->object, nstabindex); stabstr = (char *) wad_elf_section_data(f->object, nstabindexstr); + if (wad_search_stab(stab,stabsize,stabstr, f)) { - WadObjectFile *wo1, *wold; /* Hmmm. Might be in a different file */ + WadObjectFile *wo1, *wold; char objfile[MAX_PATH]; + /* printf("DEBUG %s\n", f->sym_name); */ wad_strcpy(objfile, f->loc_objfile); wo1 = wad_object_load(objfile); if (wo1) { @@ -407,11 +412,11 @@ wad_find_symbol(WadFrame *f) { void wad_find_debug(WadFrame *f) { - if (f->debug_check) return; + /* if (f->debug_check) return; */ if (f->object) { wad_elf_debug_info(f); } - f->debug_check = 1; + /* f->debug_check = 1; */ } diff --git a/Tools/WAD/Wad/io.c b/Tools/WAD/Wad/io.c index 37546e400..ab641f553 100644 --- a/Tools/WAD/Wad/io.c +++ b/Tools/WAD/Wad/io.c @@ -30,18 +30,21 @@ rely upon malloc() and related functions */ char *wad_format_hex(unsigned long u, int leading) { - static char digits[] = "0123456789abcdef"; static char result[64]; int i; char *c; c = &result[63]; *c = 0; - for (i = 0; i < (sizeof(unsigned long) << 1); i++) { - int digit; - if (!u || leading) { - digit = u & 0xf; - *(--c) = digits[digit]; + for (i = 0; i < (sizeof(unsigned long)*2); i++) { + int d; + d = (int) (u & 0xf); + c--; + if (d < 10) { + *c = '0' + d; + } else { + *c = 'a' + (d-10); } + if (!u && !leading) break; u = u >> 4; } return c; diff --git a/Tools/WAD/Wad/object.c b/Tools/WAD/Wad/object.c index f25c2e442..b12d725db 100644 --- a/Tools/WAD/Wad/object.c +++ b/Tools/WAD/Wad/object.c @@ -276,3 +276,23 @@ void wad_find_object(WadFrame *f) { f->object = wad_object_load(f->segment->mappath); } } + +/* ----------------------------------------------------------------------------- + * wad_file_check(void *addr) + * + * Given an address, this function checks to see if it corresponds to a file + * we already mapped. + * ----------------------------------------------------------------------------- */ + +int +wad_file_check(void *addr) { + WadFile *f = wad_files; + while (f) { + if ((((char *) f->addr) <= ((char *) addr)) && + (((char *) addr) < (((char *) f->addr) + f->size))) { + return 1; + } + f = f->next; + } + return 0; +} diff --git a/Tools/WAD/Wad/segment.c b/Tools/WAD/Wad/segment.c index 2cac7b3e0..489b1e856 100644 --- a/Tools/WAD/Wad/segment.c +++ b/Tools/WAD/Wad/segment.c @@ -155,8 +155,10 @@ wad_segment_read() { while (1) { s = (WadSegment *) wad_malloc(sizeof(WadSegment)); + skip: n = segment_read(fs,s); if (n <= 0) break; + if (wad_file_check(s->vaddr)) goto skip; /* Skip files we already loaded */ s->next = 0; if (!lasts) { segments = s; diff --git a/Tools/WAD/Wad/signal.c b/Tools/WAD/Wad/signal.c index 5be51d6d3..2f789ea9d 100644 --- a/Tools/WAD/Wad/signal.c +++ b/Tools/WAD/Wad/signal.c @@ -435,6 +435,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { void wad_signal_init() { struct sigaction newvec; static stack_t sigstk; + static int initstack = 0; if (wad_debug_mode & DEBUG_INIT) { wad_printf("WAD: Initializing signal handler.\n"); @@ -442,15 +443,19 @@ void wad_signal_init() { /* This is buggy in Linux and threads. disabled by default */ #ifndef WAD_LINUX - /* Set up an alternative stack */ - sigstk.ss_sp = (char *) wad_sig_stack; - sigstk.ss_size = STACK_SIZE; - sigstk.ss_flags = 0; - if (!(wad_debug_mode & DEBUG_NOSTACK)) { - if (sigaltstack(&sigstk, (stack_t*)0) < 0) { - perror("sigaltstack"); + if (!initstack) { + /* Set up an alternative stack */ + + sigstk.ss_sp = (char *) wad_sig_stack; + sigstk.ss_size = STACK_SIZE; + sigstk.ss_flags = 0; + if (!(wad_debug_mode & DEBUG_NOSTACK)) { + if (sigaltstack(&sigstk, (stack_t*)0) < 0) { + perror("sigaltstack"); + } } + initstack=1; } #endif diff --git a/Tools/WAD/Wad/stab.c b/Tools/WAD/Wad/stab.c index dbb80e69c..54c712af8 100644 --- a/Tools/WAD/Wad/stab.c +++ b/Tools/WAD/Wad/stab.c @@ -45,7 +45,7 @@ typedef struct Stab { #define N_LSYM 0x80 /* Local symbol */ #define N_PSYM 0xa0 /* Parameter */ #define N_LBRAC 0xc0 /* Left brace */ - +#define N_RBRAC 0xe0 /* Right brace */ /* ----------------------------------------------------------------------------- * stabs type handler @@ -359,6 +359,7 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { int i; unsigned long offset; int get_parms = 1; + int nbrace = 0; offset = f->pc - f->sym_base; if (wad_debug_mode & DEBUG_STABS) { @@ -372,13 +373,17 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { } - if ((s->n_type == N_UNDF) || (s->n_type == N_SO) || (s->n_type == N_FUN) || + if ((s->n_type == N_UNDF) || (s->n_type == N_SO) || /* (s->n_type == N_FUN) || */ (s->n_type == N_OBJ)) return i; if (s->n_type == N_LBRAC) { + nbrace++; get_parms = 0; } - + if (s->n_type == N_RBRAC) { + nbrace--; + if (nbrace <= 0) return i; + } /* Local variable declaration */ if (s->n_type == N_LSYM) { @@ -454,7 +459,7 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { if (s->n_type == N_SLINE) { get_parms = 0; - if (s->n_value < offset) { + if (s->n_value <= offset) { f->loc_line = s->n_desc; } } else if (((s->n_type == N_PSYM) || (s->n_type == N_RSYM)) && get_parms) { @@ -577,7 +582,6 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { char srcfile[MAX_PATH]; char objfile[MAX_PATH]; - /* It appears to be necessary to clear the types table on each new stabs section */ init_hash(); @@ -592,8 +596,8 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { for (i = 0; i < ns; i++, s++) { if (wad_debug_mode & DEBUG_STABS) { - wad_printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, - stabstr+s->n_strx); + /* wad_printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, + stabstr+s->n_strx); */ } if (s->n_type == N_LSYM) { @@ -604,8 +608,9 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { /* New stabs section. We need to be a little careful here. Do a recursive search of the subsection. */ - /* if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, f)) return 1; */ - wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, f); + if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, f)) { + return 1; + } /* On solaris, each stabs section seems to increment the stab string pointer. On Linux, the linker seems to do a certain amount of optimization that results in a single @@ -644,31 +649,15 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { } wad_strcat(objfile,stabstr+s->n_strx); } else if (s->n_type == N_FUN) { - - /* Due to the bogosity and performance issues of managing stabs types, we are going to check - the current frame as well as all remaining unchecked stack frames for a match. Generally, - it is much faster for us to scan the stabs data once checking N stack frames than it - is to check N stack frames, scanning the stabs data each time. - */ - - WadFrame *g; - g = f; - while (g) { - if ((!g->sym_name) || (g->debug_check)) { - g = g->next; - continue; - } - if (match_stab_symbol(g->sym_name, stabstr+s->n_strx, g->sym_nlen)) { - if (!g->sym_file || (strcmp(g->sym_file,lastfile) == 0)) { + if (match_stab_symbol(f->sym_name, stabstr+s->n_strx, f->sym_nlen)) { + if (!f->sym_file || (strcmp(f->sym_file,lastfile) == 0)) { int n; /* Go find debugging information for the function */ - n = scan_function(s+1, stabstr, ns -i - 1, g); - g->loc_srcfile = wad_string_lookup(srcfile); - g->loc_objfile = wad_string_lookup(objfile); - g->debug_check = 1; + n = scan_function(s+1, stabstr, ns -i - 1, f); + f->loc_srcfile = wad_string_lookup(srcfile); + f->loc_objfile = wad_string_lookup(objfile); + return 1; } - } - g = g->next; } } }