From b4fc95efca1d031ccb672ed1eddfd9f3a8c2d6ae Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Mon, 26 Feb 2001 06:00:19 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@1030 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- SWIG/Tools/WAD/Include/wad.h | 24 +++ SWIG/Tools/WAD/Makefile | 2 +- SWIG/Tools/WAD/Python/type.c | 35 +++++ SWIG/Tools/WAD/Test/debug.c | 3 +- SWIG/Tools/WAD/Test/debug.i | 1 + SWIG/Tools/WAD/Test/debug.py | 3 + SWIG/Tools/WAD/Test/wpm.py | 76 ++++++---- SWIG/Tools/WAD/Wad/Makefile | 18 +-- SWIG/Tools/WAD/Wad/Makefile.in | 4 +- SWIG/Tools/WAD/Wad/init.c | 9 ++ SWIG/Tools/WAD/Wad/memory.c | 18 +++ SWIG/Tools/WAD/Wad/signal.c | 2 + SWIG/Tools/WAD/Wad/stab.c | 267 ++++++++++++++++++--------------- SWIG/Tools/WAD/Wad/stack.c | 15 ++ SWIG/Tools/WAD/Wad/string.c | 93 ++++++++++++ SWIG/Tools/WAD/Wad/vars.c | 134 ++++++++++++----- 16 files changed, 502 insertions(+), 202 deletions(-) create mode 100644 SWIG/Tools/WAD/Wad/string.c diff --git a/SWIG/Tools/WAD/Include/wad.h b/SWIG/Tools/WAD/Include/wad.h index cf17e41df..a1b466335 100644 --- a/SWIG/Tools/WAD/Include/wad.h +++ b/SWIG/Tools/WAD/Include/wad.h @@ -29,6 +29,16 @@ extern "C" { #endif + /* Core datatypes */ + + typedef int int32; + typedef unsigned uint32; + typedef short int16; + typedef unsigned short uint16; + typedef signed char int8; + typedef unsigned char uint8; + + #ifndef MAX_PATH #define MAX_PATH 1024 #endif @@ -41,6 +51,12 @@ extern int wad_memory_init(); extern void *wad_malloc(int nbytes); extern void wad_release_memory(); extern char *wad_strdup(const char *c); +extern void wad_memory_debug(); + + /* --- Low level string handling --- */ + +extern char *wad_string_lookup(char *s); +extern void wad_string_debug(); /* --- I/O, Debugging --- */ @@ -119,6 +135,9 @@ typedef struct WadLocal { #define WAD_TYPE_POINTER 11 #define WAD_TYPE_CHAR 12 +extern long wad_local_as_long(WadLocal *loc); +extern double wad_local_as_double(WadLocal *loc); + /* Data structure containing information about each stack frame */ typedef struct WadFrame { @@ -157,6 +176,9 @@ typedef struct WadFrame { int debug_nargs; /* Number of arguments */ WadLocal *debug_args; /* Arguments */ WadLocal *debug_lastarg; /* Last argument */ + int debug_nlocals; /* Number of locals */ + WadLocal *debug_locals; /* Local variables */ + WadLocal *debug_lastlocal; /* Last local */ /* Output strings */ char *debug_str; /* Debugging string */ @@ -213,6 +235,8 @@ extern void wad_debug_make_strings(WadFrame *f); #define DEBUG_STACK 0x800 #define DEBUG_UNWIND 0x1000 #define DEBUG_SIGNAL 0x2000 +#define DEBUG_STRING 0x4000 +#define DEBUG_MEMORY 0x8000 extern int wad_debug_mode; extern int wad_heap_overflow; diff --git a/SWIG/Tools/WAD/Makefile b/SWIG/Tools/WAD/Makefile index b32dba8c1..765e141f3 100644 --- a/SWIG/Tools/WAD/Makefile +++ b/SWIG/Tools/WAD/Makefile @@ -13,7 +13,7 @@ PYINCLUDE = -I/usr/local/include/python2.0 TCLINCLUDE = -I/usr/local/include # Location of your Perl installation -PERLINCLUDE = -I/usr/perl5/5.00503/sun4-solaris/CORE +PERLINCLUDE = -I/usr/lib/perl5/5.00503/i386-linux/CORE all: wad python tcl perl diff --git a/SWIG/Tools/WAD/Python/type.c b/SWIG/Tools/WAD/Python/type.c index 9bef16bd2..8886bff20 100644 --- a/SWIG/Tools/WAD/Python/type.c +++ b/SWIG/Tools/WAD/Python/type.c @@ -186,7 +186,42 @@ wadobject_getattr(wadobject *self, char *name) { return PyInt_FromLong(1); } + /* Put a check for local variables */ + { + int i; + for (i = 0; i < 2; i++) { + WadLocal *loc; + if (i == 0) loc = self->frame->debug_locals; + else loc = self->frame->debug_args; + while (loc) { + if (strcmp(name,loc->name) == 0) { + switch(loc->type) { + case WAD_TYPE_INT32: + case WAD_TYPE_INT16: + case WAD_TYPE_INT8: + return PyLong_FromLong(wad_local_as_long(loc)); + break; + case WAD_TYPE_UINT8: + case WAD_TYPE_UINT16: + case WAD_TYPE_UINT32: + return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc)); + break; + case WAD_TYPE_CHAR: + return Py_BuildValue("c", (char) (PyLong_FromLong(wad_local_as_long(loc)))); + break; + case WAD_TYPE_FLOAT: + case WAD_TYPE_DOUBLE: + return PyFloat_FromDouble(wad_local_as_double(loc)); + break; + default: + return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc)); + } + } + loc = loc->next; + } + } + } PyErr_SetString(PyExc_NameError,"Unknown attribute."); return NULL; diff --git a/SWIG/Tools/WAD/Test/debug.c b/SWIG/Tools/WAD/Test/debug.c index 114e42936..24dc65c90 100644 --- a/SWIG/Tools/WAD/Test/debug.c +++ b/SWIG/Tools/WAD/Test/debug.c @@ -67,6 +67,7 @@ void type_crash(int a, short b, char c, unsigned long d, float f, double g) { long ld; float lf; double lg; + long ll; la = a; lb = b; @@ -74,7 +75,7 @@ void type_crash(int a, short b, char c, unsigned long d, float f, double g) { ld = ld; lf = lf; lg = lg; - assert(a); + assert(0); } #ifdef NEED_MAIN diff --git a/SWIG/Tools/WAD/Test/debug.i b/SWIG/Tools/WAD/Test/debug.i index d1a5cefb9..1823161fc 100644 --- a/SWIG/Tools/WAD/Test/debug.i +++ b/SWIG/Tools/WAD/Test/debug.i @@ -6,3 +6,4 @@ extern int blowheap_crash(); extern int overflow_crash(); extern int abort_crash(int); extern int math_crash(int x, int y); +extern void type_crash(int, short, char, unsigned long, float, double); diff --git a/SWIG/Tools/WAD/Test/debug.py b/SWIG/Tools/WAD/Test/debug.py index 96db832a5..07d9453a8 100644 --- a/SWIG/Tools/WAD/Test/debug.py +++ b/SWIG/Tools/WAD/Test/debug.py @@ -30,3 +30,6 @@ elif name == "heap": debug.blowheap_crash() elif name == "overflow": debug.overflow_crash() +elif name == "type": + debug.type_crash(37,42, 'x', 420000, 3.14159, 2.1828) + diff --git a/SWIG/Tools/WAD/Test/wpm.py b/SWIG/Tools/WAD/Test/wpm.py index c9e1a6517..a8541953e 100644 --- a/SWIG/Tools/WAD/Test/wpm.py +++ b/SWIG/Tools/WAD/Test/wpm.py @@ -46,40 +46,47 @@ class wad_frame: def __init__(self,frame, n = 0): if isinstance(frame,types.TupleType): # A Python traceback object - self.file = frame[0] - self.line = frame[1] - self.name = frame[2] - self.argstr = frame[3] - self.frameno = n + self.__FILE__ = frame[0] + self.__LINE__ = frame[1] + self.__NAME__ = frame[2] + self.__ARGSTR__ = frame[3] + self.__FRAMENO__ = n # Make the debugging string - self.debugstr = "#%-3d [ Python ] in %s in %s, line %d" % (self.frameno, self.argstr, self.file, self.line) + self.__DEBUGSTR__ = "#%-3d [ Python ] in %s in %s, line %d" % (self.__FRAMENO__, self.__ARGSTR__, self.__FILE__, self.__LINE__) # Try to get source data - self.source = "%s, Line %d\n\n" % (self.file, self.line) - for i in range(self.line-2,self.line+3): - l = linecache.getline(self.file,i) + self.__SOURCE__ = "%s, Line %d\n\n" % (self.__FILE__, self.__LINE__) + for i in range(self.__LINE__-2,self.__LINE__+3): + l = linecache.getline(self.__FILE__,i) if not l: l = '\n' - if (i == self.line): - self.source += " => " + if (i == self.__LINE__): + self.__SOURCE__ += " => " else: - self.source += " " - self.source += l + self.__SOURCE__ += " " + self.__SOURCE__ += l + self.__frame__ = None elif hasattr(frame,"__WAD__"): # A WAD traceback object - self.file = frame.__FILE__ - self.line = frame.__LINE__ - self.name = frame.__NAME__ - self.debugstr = frame.__WHERE__ - self.source = frame.__SOURCE__ + self.__FILE__ = frame.__FILE__ + self.__LINE__ = frame.__LINE__ + self.__NAME__ = frame.__NAME__ + self.__DEBUGSTR__ = frame.__WHERE__ + self.__SOURCE__ = frame.__SOURCE__ + self.__frame__ = frame def __str__(self): - return self.debugstr.strip() + return self.__DEBUGSTR__.strip() + + def __getattr__(self,name): + if self.__frame__: + return getattr(self.__frame__,name) + raise AttributeError def output(self): print self - if self.source: - print "\n%s" % (self.source,) + if self.__SOURCE__: + print "\n%s" % (self.__SOURCE__) def wad_build_info(): @@ -170,16 +177,11 @@ class where_impl: for i in range(len(stack),0,-1): f = stack[i-1] print f - if (f.source): - last_source = f.source + if (f.__SOURCE__): + last_source = f.__SOURCE__ _last_level = i-1 if last_source: print "\n%s" % last_source return "" - def __getattr__(self,name): - try: - return getattr(frame,name) - except: - raise AttributeError def __getitem__(self,n): global _last_level, _cstack, _combined_stack @@ -252,14 +254,26 @@ class edit_impl: if not stack: return "" f = stack[_last_level] - e = os.getenv("EDITOR","emacs") - if f.file: - os.system("%s +%d %s" % (e,f.line,f.file)) + e = os.getenv("EDITOR","vi") + if f.__FILE__: + os.system("%s +%d %s" % (e,f.__LINE__,f.__FILE__)) return "" edit = edit_impl() e = edit +class var_impl: + def __getattr__(self,name): + if (w.cstack): + stack = _cstack + else: + stack = _combined_stack + + return getattr(stack[_last_level],name) + + +v = var_impl() + repr(w) diff --git a/SWIG/Tools/WAD/Wad/Makefile b/SWIG/Tools/WAD/Wad/Makefile index 9dbd94406..7557cf5b9 100644 --- a/SWIG/Tools/WAD/Wad/Makefile +++ b/SWIG/Tools/WAD/Wad/Makefile @@ -7,10 +7,10 @@ ####################################################################### # These are the files that make up the WAD core -WADSRCS = vars.c io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c -WADOBJS = vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o +WADSRCS = string.c vars.c io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c +WADOBJS = string.o vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o INCLUDE = -I../Include -I. $(SINCLUDE) -WADOPT = -DWAD_SOLARIS +WADOPT = -DWAD_LINUX # Location of your Python installation PYINCLUDE = -I/usr/local/include/python2.0 @@ -23,21 +23,21 @@ TCLSRCS = wadtcl.cxx TCLOBJS = wadtcl.o # Location of your Perl installation -PERLINCLUDE = -I/usr/perl5/5.00503/sun4-solaris/CORE +PERLINCLUDE = -I/usr/lib/perl5/5.00503/i386-linux/CORE PERLSRCS = wadpl.cxx PERLOBJS = wadpl.o # C Compiler -CC = cc -CFLAGS = # +CC = gcc +CFLAGS = #-fpic # C++ Compiler -CXX = CC -CXXFLAGS = #-Kpic +CXX = c++ +CXXFLAGS = #-fpic # Linking options CLINK = -CXXLINK = CC -G +CXXLINK = g++ -shared # AR AR = ar diff --git a/SWIG/Tools/WAD/Wad/Makefile.in b/SWIG/Tools/WAD/Wad/Makefile.in index 051324b8b..14beb0a79 100644 --- a/SWIG/Tools/WAD/Wad/Makefile.in +++ b/SWIG/Tools/WAD/Wad/Makefile.in @@ -6,8 +6,8 @@ ####################################################################### # These are the files that make up the WAD core -WADSRCS = vars.c io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c -WADOBJS = vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o +WADSRCS = string.c vars.c io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c +WADOBJS = string.o vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o INCLUDE = -I../Include -I. $(SINCLUDE) WADOPT = @WADOPT@ diff --git a/SWIG/Tools/WAD/Wad/init.c b/SWIG/Tools/WAD/Wad/init.c index 2c4671ec0..240533a82 100644 --- a/SWIG/Tools/WAD/Wad/init.c +++ b/SWIG/Tools/WAD/Wad/init.c @@ -75,10 +75,19 @@ void wad_init() { wad_debug_mode |= DEBUG_ONESHOT; } + if (getenv("WAD_DEBUG_STRING")) { + wad_debug_mode |= DEBUG_STRING; + } + + if (getenv("WAD_DEBUG_MEMORY")) { + wad_debug_mode |= DEBUG_MEMORY; + } + if (wad_debug_mode & DEBUG_INIT) { wad_printf("WAD: initializing\n"); } + if (!init) { wad_signal_init(); wad_object_reset(); diff --git a/SWIG/Tools/WAD/Wad/memory.c b/SWIG/Tools/WAD/Wad/memory.c index 6b113caac..053697460 100644 --- a/SWIG/Tools/WAD/Wad/memory.c +++ b/SWIG/Tools/WAD/Wad/memory.c @@ -144,3 +144,21 @@ char *wad_strdup(const char *c) { return t; } +/* ----------------------------------------------------------------------------- + * wad_memory_debug() + * ----------------------------------------------------------------------------- */ + +void wad_memory_debug() { + int total_alloc = 0; + int inuse = 0; + WadMemory *m; + if (wad_debug_mode & DEBUG_MEMORY) { + m = current; + while (m) { + total_alloc += (m->npages)*pagesize; + inuse += m->last; + m = m->next; + } + printf("WAD: memory allocated %d bytes (%d bytes used).\n", total_alloc, inuse); + } +} diff --git a/SWIG/Tools/WAD/Wad/signal.c b/SWIG/Tools/WAD/Wad/signal.c index 5a1be1c3f..65bfbfe0c 100644 --- a/SWIG/Tools/WAD/Wad/signal.c +++ b/SWIG/Tools/WAD/Wad/signal.c @@ -387,6 +387,8 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { wad_nlr_levels = 0; } + wad_string_debug(); + wad_memory_debug(); if (sig_callback) { (*sig_callback)(sig,origframe,retname); diff --git a/SWIG/Tools/WAD/Wad/stab.c b/SWIG/Tools/WAD/Wad/stab.c index c3eb487ee..4de27f554 100644 --- a/SWIG/Tools/WAD/Wad/stab.c +++ b/SWIG/Tools/WAD/Wad/stab.c @@ -43,54 +43,6 @@ typedef struct Stab { * We also need to keep a hash table of stabs types. * ----------------------------------------------------------------------------- */ -/* Hash table containing stab strings and such */ -typedef struct stringtype { - char *str; - struct stringtype *next; -} stringtype; - -#define STRING_HASH_SIZE 1023 - -static stringtype *strings[STRING_HASH_SIZE]; -static int strings_init = 0; - -static int shash(char *name) { - unsigned int h = 0; - int i; - for (i = 0; i < 8 && (*name); i++, name++) { - h = ((h << 5) + *name); - } - return (h % STRING_HASH_SIZE); -} - -static char * -string_lookup(char *s) { - int h; - int i; - stringtype *st; - - if (!strings_init) { - for (i = 0; i < STRING_HASH_SIZE; i++) { - strings[i] = 0; - } - strings_init = 1; - } - - h = shash(s); - st = strings[h]; - while (st) { - if (strcmp(st->str,s) == 0) return st->str; - st = st->next; - } - - /* Not found. Add the string to the hash table */ - st = (stringtype *) wad_malloc(sizeof(stringtype)); - st->str = wad_strdup(s); - st->next = strings[h]; - strings[h] = st; - return st->str; -} - typedef struct stabtype { char *name; char *value; @@ -173,7 +125,7 @@ static void type_add(char *name, char *value) { while (s) { if (strcmp(s->name,name) == 0) { if (strcmp(s->value,v)) { - s->value = string_lookup(v); + s->value = wad_string_lookup(v); } goto add_more; } @@ -185,8 +137,8 @@ static void type_add(char *name, char *value) { } else { deadnames[h] = s->next; } - s->name = string_lookup(name); - s->value = string_lookup(v); + s->name = wad_string_lookup(name); + s->value = wad_string_lookup(v); s->next = lnames[h]; s->visit = 0; lnames[h] = s; @@ -415,82 +367,58 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { if (s->n_type == N_LBRAC) { get_parms = 0; } - if (s->n_type == N_LSYM) { - stab_symbol(s,stabstr); - } - if (s->n_type == N_SLINE) { - get_parms = 0; - if (s->n_value <= offset) { - f->loc_line = s->n_desc; - } - } else if ((s->n_type == N_PSYM) || (s->n_type == N_RSYM)) { - if (get_parms) { - /* Parameter counting */ + /* Local variable declaration */ + + if (s->n_type == N_LSYM) { + /* This might be a local variable definition */ + /* printf("local: n_value = %d, offset = %d\n", s->n_value, offset);*/ + if (s->n_desc <= f->loc_line) + { + /* Okay. We can pay attention to it */ char *pname; char *c; int len; - WadLocal *arg; + WadLocal *arg, *a; pname = stabstr+s->n_strx; c = strchr(pname,':'); + if (*(c+1) != '(') continue; if (c) { len = (c-pname); } else { len = strlen(pname); } - /* Get type information */ - + /* printf("local\n"); */ stab_symbol(s,stabstr); - - /* Check if the argument was already used */ - /* In this case, the first stab simply identifies an argument. The second - one identifies its location for the debugger */ - - if (f->debug_args) { - /* Need to do some fix up for linux here */ - WadLocal *a = f->debug_args; - while (a) { - if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) { - /* We already saw this argument. Given a choice between a register and a stack - argument. We will choose the stack version */ - - if (a->loc == PARM_STACK) { - break; - } - /* Go ahead and use the new argument */ - if (s->n_type == N_RSYM) { - a->loc = PARM_REGISTER; - a->reg = s->n_value; - } else { - a->loc = PARM_STACK; - a->stack = s->n_value; - } - break; - } - a = a->next; + a = f->debug_locals; + while (a) { + if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) { + /* We already saw this argument. Given a choice between a register and a stack + argument. We will choose the stack version */ + a->loc = PARM_STACK; + a->stack = s->n_value; + break; } - if (a) continue; /* We got an argument match. Just skip to the next stab */ + a = a->next; } - + if (a) continue; /* We got an argument match. Just skip to the next stab */ arg = (WadLocal *) wad_malloc(sizeof(WadLocal)); - arg->name = (char *) wad_malloc(len+1); - strncpy(arg->name, pname, len); - arg->name[len] = 0; - if (s->n_type == N_RSYM) { - arg->loc = PARM_REGISTER; - arg->reg = s->n_value; - arg->stack = 0; - } else { - arg->loc = PARM_STACK; - arg->line = s->n_desc; - arg->stack = s->n_value; + { + char t = pname[len]; + pname[len] = 0; + arg->name = wad_string_lookup(pname); + pname[len] = t; } + arg->loc = PARM_STACK; + arg->line = s->n_desc; + arg->stack = s->n_value; arg->type = 0; arg->next = 0; { char tname[128]; char *t = tname; - c+=2; + + c+=1; while ((*c) && (*c != '=')) { *t++ = *c++; } @@ -501,17 +429,113 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { printf("type_resolve '%s' -> '%s' (%d)\n", tname, t, arg->type); } } - if (f->debug_args) { - f->debug_lastarg->next = arg; - f->debug_lastarg = arg; + if (f->debug_locals) { + f->debug_lastlocal->next = arg; + f->debug_lastlocal = arg; } else { - f->debug_args = arg; - f->debug_lastarg = arg; - f->debug_nargs= 0; + f->debug_locals = arg; + f->debug_lastlocal = arg; + f->debug_nlocals= 0; } - f->debug_nargs++; + f->debug_nlocals++; } } + + if (s->n_type == N_SLINE) { + get_parms = 0; + 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) { + /* Parameter counting */ + char *pname; + char *c; + int len; + WadLocal *arg; + pname = stabstr+s->n_strx; + c = strchr(pname,':'); + if (c) { + len = (c-pname); + } else { + len = strlen(pname); + } + /* Get type information */ + + stab_symbol(s,stabstr); + + /* Check if the argument was already used */ + /* In this case, the first stab simply identifies an argument. The second + one identifies its location for the debugger */ + + { + /* Need to do some fix up for linux here */ + WadLocal *a = f->debug_args; + while (a) { + if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) { + /* We already saw this argument. Given a choice between a register and a stack + argument. We will choose the stack version */ + + if (a->loc == PARM_STACK) { + break; + } + /* Go ahead and use the new argument */ + if (s->n_type == N_RSYM) { + a->loc = PARM_REGISTER; + a->reg = s->n_value; + } else { + a->loc = PARM_STACK; + a->stack = s->n_value; + } + break; + } + a = a->next; + } + if (a) continue; /* We got an argument match. Just skip to the next stab */ + } + + arg = (WadLocal *) wad_malloc(sizeof(WadLocal)); + { + char t = pname[len]; + pname[len] = 0; + arg->name = wad_string_lookup(pname); + pname[len] = t; + } + if (s->n_type == N_RSYM) { + arg->loc = PARM_REGISTER; + arg->reg = s->n_value; + arg->stack = 0; + } else { + arg->loc = PARM_STACK; + arg->line = s->n_desc; + arg->stack = s->n_value; + } + arg->type = 0; + arg->next = 0; + { + char tname[128]; + char *t = tname; + + c+=2; + while ((*c) && (*c != '=')) { + *t++ = *c++; + } + *t = 0; + t = type_resolve(tname); + arg->type = type_typecode(t); + if (wad_debug_mode & DEBUG_STABS) { + printf("type_resolve '%s' -> '%s' (%d)\n", tname, t, arg->type); + } + } + if (f->debug_args) { + f->debug_lastarg->next = arg; + f->debug_lastarg = arg; + } else { + f->debug_args = arg; + f->debug_lastarg = arg; + f->debug_nargs= 0; + } + f->debug_nargs++; + } } } @@ -560,11 +584,12 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { objfile[0] = 0; for (i = 0; i < ns; i++, s++) { - if (wad_debug_mode & DEBUG_STABS) { + /* 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); } + */ if (s->n_type == N_LSYM) { stab_symbol(s,stabstr); continue; @@ -617,16 +642,22 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { if (!f->sym_file || (strcmp(f->sym_file,lastfile) == 0)) { /* Go find debugging information for the function */ scan_function(s+1, stabstr, ns -i - 1, f); - f->loc_srcfile = wad_strdup(srcfile); - f->loc_objfile = wad_strdup(objfile); + f->loc_srcfile = wad_string_lookup(srcfile); + f->loc_objfile = wad_string_lookup(objfile); + /* f->loc_srcfile = wad_strdup(srcfile); + f->loc_objfile = wad_strdup(objfile); */ + return 1; } } } } if (found) { - f->loc_srcfile = wad_strdup(srcfile); - f->loc_objfile = wad_strdup(objfile); + f->loc_srcfile = wad_string_lookup(srcfile); + f->loc_objfile = wad_string_lookup(objfile); + /* f->loc_srcfile = wad_strdup(srcfile); + f->loc_objfile = wad_strdup(objfile); */ + } return found; } diff --git a/SWIG/Tools/WAD/Wad/stack.c b/SWIG/Tools/WAD/Wad/stack.c index 53b5c7192..743b31842 100644 --- a/SWIG/Tools/WAD/Wad/stack.c +++ b/SWIG/Tools/WAD/Wad/stack.c @@ -44,6 +44,9 @@ new_frame() { f->debug_nargs = -1; f->debug_args = 0; f->debug_lastarg = 0; + f->debug_nlocals = 0; + f->debug_locals = 0; + f->debug_lastlocal = 0; f->debug_str = 0; f->debug_srcstr = 0; @@ -227,6 +230,18 @@ void wad_stack_debug(WadFrame *frame) { } wad_printf(" ]\n"); + wad_printf(" debug_nlocal = %d\n", frame->debug_nlocals); + if (frame->debug_locals) { + int i = 0; + WadLocal *p = frame->debug_locals; + wad_printf(" debug_locals = [ \n"); + while (p) { + wad_printf(" loc[%d] : name = '%s', loc = %d, type = %d, stack = %d, reg = %d, line=%d, ptr=%x(%d)\n", i, p->name, p->loc, p->type, p->stack,p->reg,p->line,p->ptr,p->size); + p = p->next; + } + } + wad_printf(" ]\n"); + frame = frame->next; } } diff --git a/SWIG/Tools/WAD/Wad/string.c b/SWIG/Tools/WAD/Wad/string.c new file mode 100644 index 000000000..3e3abad59 --- /dev/null +++ b/SWIG/Tools/WAD/Wad/string.c @@ -0,0 +1,93 @@ +/* ----------------------------------------------------------------------------- + * string.c + * + * This file provides support for string storage in WAD. Since strings are + * used frequently in WAD, this file implements string interning and + * some lookup functions that can be used to return a previously stored + * string rather than making a new copy. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +#include "wad.h" + + +/* Hash table containing stab strings and such */ +typedef struct stringtype { + char *str; + struct stringtype *next; +} stringtype; + +#define STRING_HASH_SIZE 1013 + +static stringtype *strings[STRING_HASH_SIZE]; +static int strings_init = 0; + +static int shash(char *name) { + unsigned int h = 0; + char *c; + int i; + c = name; + for (i = 0; (i < 16) && (*c); i++, c++) { + h = ((h^~i) << 6) + *c; + } + return h % STRING_HASH_SIZE; +} + +char * +wad_string_lookup(char *s) { + int h; + int i; + stringtype *st; + + if (!strings_init) { + for (i = 0; i < STRING_HASH_SIZE; i++) { + strings[i] = 0; + } + strings_init = 1; + } + + h = shash(s); + st = strings[h]; + while (st) { + if (strcmp(st->str,s) == 0) return st->str; + st = st->next; + } + + /* Not found. Add the string to the hash table */ + st = (stringtype *) wad_malloc(sizeof(stringtype)); + st->str = wad_strdup(s); + st->next = strings[h]; + strings[h] = st; + return st->str; +} + +void wad_string_debug() { + if (wad_debug_mode & DEBUG_STRING) { + int maxdepth = 0; + int total = 0; + int stringlen = 0; + int i; + + for (i = 0; i < STRING_HASH_SIZE; i++) { + stringtype *s; + int c = 0; + s = strings[i]; + while (s) { + c++; + stringlen += strlen(s->str); + s = s->next; + } + /* wad_printf("WAD: stringhash[%d] = %d\n", i, c);*/ + if (c > maxdepth) maxdepth = c; + total += c; + } + wad_printf("WAD: nstrings = %d (%d bytes)\n", total, stringlen + total*sizeof(stringtype)); + wad_printf("WAD: maxdepth = %d\n", maxdepth); + } +} + + diff --git a/SWIG/Tools/WAD/Wad/vars.c b/SWIG/Tools/WAD/Wad/vars.c index 4991994eb..096576fc2 100644 --- a/SWIG/Tools/WAD/Wad/vars.c +++ b/SWIG/Tools/WAD/Wad/vars.c @@ -29,6 +29,7 @@ void wad_build_vars(WadFrame *f) { WadLocal *loc; int laststack = 0; WadLocal *lastloc = 0; + int n; stack = (char *) f->stack; if (f->next) { @@ -37,57 +38,45 @@ void wad_build_vars(WadFrame *f) { if (f->prev) { pstack = (char *) f->prev->stack; } - loc = f->debug_args; - while (loc) { - loc->ptr = 0; - if (loc->loc == PARM_STACK) { - if ((loc->stack >= 0) && (nstack)) { - loc->ptr = (void *) (nstack + loc->stack); - } else if (loc->stack < 0) { - loc->ptr = (void *) (stack + f->stack_size + loc->stack); + for (n = 0; n < 2; n++) { + if (n == 0) loc = f->debug_args; + else loc = f->debug_locals; + + while (loc) { + loc->ptr = 0; + if (loc->loc == PARM_STACK) { + if ((loc->stack >= 0) && (nstack)) { + loc->ptr = (void *) (nstack + loc->stack); + } else if (loc->stack < 0) { + loc->ptr = (void *) (stack + f->stack_size + loc->stack); + } + loc->size = sizeof(long); } - loc->size = sizeof(long); - } - if (loc->loc == PARM_REGISTER) { - /* Parameter is located in a register */ + if (loc->loc == PARM_REGISTER) { + /* Parameter is located in a register */ #ifdef WAD_SOLARIS - if ((loc->reg >= 24) && (loc->reg < 32)) { - /* Value is located in the %in registers. */ + if ((loc->reg >= 24) && (loc->reg < 32)) { + /* Value is located in the %in registers. */ loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); loc->size = sizeof(int); - } else if ((loc->reg >= 8) && (loc->reg < 16)) { - + } else if ((loc->reg >= 8) && (loc->reg < 16)) { + /* Value is located in the %on registers */ - if (nstack) { - loc->ptr = (void *) (stack + (loc->reg)*sizeof(int)); + if (nstack) { + loc->ptr = (void *) (stack + (loc->reg)*sizeof(int)); + loc->size = sizeof(int); + } + } else if ((loc->reg >= 16) && (loc->reg < 24)) { + /* Value has been placed in the %ln registers */ + loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); loc->size = sizeof(int); } - } else if ((loc->reg >= 16) && (loc->reg < 24)) { - /* Value has been placed in the %ln registers */ - loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); - loc->size = sizeof(int); +#endif } -#endif + loc = loc->next; } -#ifdef OLD - if (lastloc) { - /* Figure out the size */ - if (!lastloc->size) - lastloc->size = abs(loc->stack - lastloc->stack); - } - lastloc = loc; -#endif - - loc = loc->next; } -#ifdef OLD - /* If last size is not set. Assume that it is a word */ - if (lastloc && (!lastloc->size)) { - lastloc->size = 4; - } -#endif - } /* This function creates a formatted integer given a pointer, size, and sign flag */ @@ -194,6 +183,71 @@ char *wad_format_var(WadLocal *l) { return buffer; } +/* Convert a wad local variable to a long */ +long wad_local_as_long(WadLocal *loc) { + long value = 0; + int32 i32; + int16 i16; + int8 i8; + uint32 u32; + uint16 u16; + uint8 u8; + + switch(loc->type) { + case WAD_TYPE_INT32: + memcpy(&i32,loc->ptr,4); + value = (long) i32; + break; + case WAD_TYPE_UINT32: + memcpy(&u32,loc->ptr,4); + value = (long) u32; + break; + case WAD_TYPE_INT16: + memcpy(&i16,loc->ptr,2); + value = (long) i16; + break; + case WAD_TYPE_UINT16: + memcpy(&u16,loc->ptr,2); + value = (long) u16; + break; + case WAD_TYPE_INT8: + case WAD_TYPE_CHAR: + memcpy(&i8, loc->ptr,1); + value = (long) i8; + break; + case WAD_TYPE_UINT8: + memcpy(&u8, loc->ptr,1); + value = (long) u8; + break; + default: + memcpy(&u32,loc->ptr,4); + value = (long) u32; + } + return value; +} + + + +/* Convert a wad local variable to a long */ +double wad_local_as_double(WadLocal *loc) { + double value = 0; + float fval; + + switch(loc->type) { + case WAD_TYPE_DOUBLE: + memcpy(&value,loc->ptr,8); + break; + case WAD_TYPE_FLOAT: + memcpy(&fval,loc->ptr,4); + value = (double) fval; + break; + default: + value = 0; + } + return value; +} + +