*** empty log message ***

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@1030 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2001-02-26 06:00:19 +00:00
commit b4fc95efca
16 changed files with 502 additions and 202 deletions

View file

@ -29,6 +29,16 @@
extern "C" { extern "C" {
#endif #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 #ifndef MAX_PATH
#define MAX_PATH 1024 #define MAX_PATH 1024
#endif #endif
@ -41,6 +51,12 @@ extern int wad_memory_init();
extern void *wad_malloc(int nbytes); extern void *wad_malloc(int nbytes);
extern void wad_release_memory(); extern void wad_release_memory();
extern char *wad_strdup(const char *c); 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 --- */ /* --- I/O, Debugging --- */
@ -119,6 +135,9 @@ typedef struct WadLocal {
#define WAD_TYPE_POINTER 11 #define WAD_TYPE_POINTER 11
#define WAD_TYPE_CHAR 12 #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 */ /* Data structure containing information about each stack frame */
typedef struct WadFrame { typedef struct WadFrame {
@ -157,6 +176,9 @@ typedef struct WadFrame {
int debug_nargs; /* Number of arguments */ int debug_nargs; /* Number of arguments */
WadLocal *debug_args; /* Arguments */ WadLocal *debug_args; /* Arguments */
WadLocal *debug_lastarg; /* Last argument */ WadLocal *debug_lastarg; /* Last argument */
int debug_nlocals; /* Number of locals */
WadLocal *debug_locals; /* Local variables */
WadLocal *debug_lastlocal; /* Last local */
/* Output strings */ /* Output strings */
char *debug_str; /* Debugging string */ char *debug_str; /* Debugging string */
@ -213,6 +235,8 @@ extern void wad_debug_make_strings(WadFrame *f);
#define DEBUG_STACK 0x800 #define DEBUG_STACK 0x800
#define DEBUG_UNWIND 0x1000 #define DEBUG_UNWIND 0x1000
#define DEBUG_SIGNAL 0x2000 #define DEBUG_SIGNAL 0x2000
#define DEBUG_STRING 0x4000
#define DEBUG_MEMORY 0x8000
extern int wad_debug_mode; extern int wad_debug_mode;
extern int wad_heap_overflow; extern int wad_heap_overflow;

View file

@ -13,7 +13,7 @@ PYINCLUDE = -I/usr/local/include/python2.0
TCLINCLUDE = -I/usr/local/include TCLINCLUDE = -I/usr/local/include
# Location of your Perl installation # 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 all: wad python tcl perl

View file

@ -186,7 +186,42 @@ wadobject_getattr(wadobject *self, char *name) {
return PyInt_FromLong(1); return PyInt_FromLong(1);
} }
/* Put a check for local variables */ /* 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."); PyErr_SetString(PyExc_NameError,"Unknown attribute.");
return NULL; return NULL;

View file

@ -67,6 +67,7 @@ void type_crash(int a, short b, char c, unsigned long d, float f, double g) {
long ld; long ld;
float lf; float lf;
double lg; double lg;
long ll;
la = a; la = a;
lb = b; lb = b;
@ -74,7 +75,7 @@ void type_crash(int a, short b, char c, unsigned long d, float f, double g) {
ld = ld; ld = ld;
lf = lf; lf = lf;
lg = lg; lg = lg;
assert(a); assert(0);
} }
#ifdef NEED_MAIN #ifdef NEED_MAIN

View file

@ -6,3 +6,4 @@ extern int blowheap_crash();
extern int overflow_crash(); extern int overflow_crash();
extern int abort_crash(int); extern int abort_crash(int);
extern int math_crash(int x, int y); extern int math_crash(int x, int y);
extern void type_crash(int, short, char, unsigned long, float, double);

View file

@ -30,3 +30,6 @@ elif name == "heap":
debug.blowheap_crash() debug.blowheap_crash()
elif name == "overflow": elif name == "overflow":
debug.overflow_crash() debug.overflow_crash()
elif name == "type":
debug.type_crash(37,42, 'x', 420000, 3.14159, 2.1828)

View file

@ -46,40 +46,47 @@ class wad_frame:
def __init__(self,frame, n = 0): def __init__(self,frame, n = 0):
if isinstance(frame,types.TupleType): if isinstance(frame,types.TupleType):
# A Python traceback object # A Python traceback object
self.file = frame[0] self.__FILE__ = frame[0]
self.line = frame[1] self.__LINE__ = frame[1]
self.name = frame[2] self.__NAME__ = frame[2]
self.argstr = frame[3] self.__ARGSTR__ = frame[3]
self.frameno = n self.__FRAMENO__ = n
# Make the debugging string # 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 # Try to get source data
self.source = "%s, Line %d\n\n" % (self.file, self.line) self.__SOURCE__ = "%s, Line %d\n\n" % (self.__FILE__, self.__LINE__)
for i in range(self.line-2,self.line+3): for i in range(self.__LINE__-2,self.__LINE__+3):
l = linecache.getline(self.file,i) l = linecache.getline(self.__FILE__,i)
if not l: l = '\n' if not l: l = '\n'
if (i == self.line): if (i == self.__LINE__):
self.source += " => " self.__SOURCE__ += " => "
else: else:
self.source += " " self.__SOURCE__ += " "
self.source += l self.__SOURCE__ += l
self.__frame__ = None
elif hasattr(frame,"__WAD__"): elif hasattr(frame,"__WAD__"):
# A WAD traceback object # A WAD traceback object
self.file = frame.__FILE__ self.__FILE__ = frame.__FILE__
self.line = frame.__LINE__ self.__LINE__ = frame.__LINE__
self.name = frame.__NAME__ self.__NAME__ = frame.__NAME__
self.debugstr = frame.__WHERE__ self.__DEBUGSTR__ = frame.__WHERE__
self.source = frame.__SOURCE__ self.__SOURCE__ = frame.__SOURCE__
self.__frame__ = frame
def __str__(self): 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): def output(self):
print self print self
if self.source: if self.__SOURCE__:
print "\n%s" % (self.source,) print "\n%s" % (self.__SOURCE__)
def wad_build_info(): def wad_build_info():
@ -170,16 +177,11 @@ class where_impl:
for i in range(len(stack),0,-1): for i in range(len(stack),0,-1):
f = stack[i-1] f = stack[i-1]
print f print f
if (f.source): if (f.__SOURCE__):
last_source = f.source last_source = f.__SOURCE__
_last_level = i-1 _last_level = i-1
if last_source: print "\n%s" % last_source if last_source: print "\n%s" % last_source
return "" return ""
def __getattr__(self,name):
try:
return getattr(frame,name)
except:
raise AttributeError
def __getitem__(self,n): def __getitem__(self,n):
global _last_level, _cstack, _combined_stack global _last_level, _cstack, _combined_stack
@ -252,14 +254,26 @@ class edit_impl:
if not stack: if not stack:
return "" return ""
f = stack[_last_level] f = stack[_last_level]
e = os.getenv("EDITOR","emacs") e = os.getenv("EDITOR","vi")
if f.file: if f.__FILE__:
os.system("%s +%d %s" % (e,f.line,f.file)) os.system("%s +%d %s" % (e,f.__LINE__,f.__FILE__))
return "" return ""
edit = edit_impl() edit = edit_impl()
e = edit 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) repr(w)

View file

@ -7,10 +7,10 @@
####################################################################### #######################################################################
# These are the files that make up the WAD core # 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 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 = vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o 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) INCLUDE = -I../Include -I. $(SINCLUDE)
WADOPT = -DWAD_SOLARIS WADOPT = -DWAD_LINUX
# Location of your Python installation # Location of your Python installation
PYINCLUDE = -I/usr/local/include/python2.0 PYINCLUDE = -I/usr/local/include/python2.0
@ -23,21 +23,21 @@ TCLSRCS = wadtcl.cxx
TCLOBJS = wadtcl.o TCLOBJS = wadtcl.o
# Location of your Perl installation # 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 PERLSRCS = wadpl.cxx
PERLOBJS = wadpl.o PERLOBJS = wadpl.o
# C Compiler # C Compiler
CC = cc CC = gcc
CFLAGS = # CFLAGS = #-fpic
# C++ Compiler # C++ Compiler
CXX = CC CXX = c++
CXXFLAGS = #-Kpic CXXFLAGS = #-fpic
# Linking options # Linking options
CLINK = CLINK =
CXXLINK = CC -G CXXLINK = g++ -shared
# AR # AR
AR = ar AR = ar

View file

@ -6,8 +6,8 @@
####################################################################### #######################################################################
# These are the files that make up the WAD core # 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 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 = vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o 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) INCLUDE = -I../Include -I. $(SINCLUDE)
WADOPT = @WADOPT@ WADOPT = @WADOPT@

View file

@ -75,10 +75,19 @@ void wad_init() {
wad_debug_mode |= DEBUG_ONESHOT; 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) { if (wad_debug_mode & DEBUG_INIT) {
wad_printf("WAD: initializing\n"); wad_printf("WAD: initializing\n");
} }
if (!init) { if (!init) {
wad_signal_init(); wad_signal_init();
wad_object_reset(); wad_object_reset();

View file

@ -144,3 +144,21 @@ char *wad_strdup(const char *c) {
return t; 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);
}
}

View file

@ -387,6 +387,8 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
wad_nlr_levels = 0; wad_nlr_levels = 0;
} }
wad_string_debug();
wad_memory_debug();
if (sig_callback) { if (sig_callback) {
(*sig_callback)(sig,origframe,retname); (*sig_callback)(sig,origframe,retname);

View file

@ -43,54 +43,6 @@ typedef struct Stab {
* We also need to keep a hash table of stabs types. * 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 { typedef struct stabtype {
char *name; char *name;
char *value; char *value;
@ -173,7 +125,7 @@ static void type_add(char *name, char *value) {
while (s) { while (s) {
if (strcmp(s->name,name) == 0) { if (strcmp(s->name,name) == 0) {
if (strcmp(s->value,v)) { if (strcmp(s->value,v)) {
s->value = string_lookup(v); s->value = wad_string_lookup(v);
} }
goto add_more; goto add_more;
} }
@ -185,8 +137,8 @@ static void type_add(char *name, char *value) {
} else { } else {
deadnames[h] = s->next; deadnames[h] = s->next;
} }
s->name = string_lookup(name); s->name = wad_string_lookup(name);
s->value = string_lookup(v); s->value = wad_string_lookup(v);
s->next = lnames[h]; s->next = lnames[h];
s->visit = 0; s->visit = 0;
lnames[h] = s; lnames[h] = s;
@ -415,82 +367,58 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) {
if (s->n_type == N_LBRAC) { if (s->n_type == N_LBRAC) {
get_parms = 0; get_parms = 0;
} }
if (s->n_type == N_LSYM) {
stab_symbol(s,stabstr);
}
if (s->n_type == N_SLINE) { /* Local variable declaration */
get_parms = 0;
if (s->n_value <= offset) { if (s->n_type == N_LSYM) {
f->loc_line = s->n_desc; /* This might be a local variable definition */
} /* printf("local: n_value = %d, offset = %d\n", s->n_value, offset);*/
} else if ((s->n_type == N_PSYM) || (s->n_type == N_RSYM)) { if (s->n_desc <= f->loc_line)
if (get_parms) { {
/* Parameter counting */ /* Okay. We can pay attention to it */
char *pname; char *pname;
char *c; char *c;
int len; int len;
WadLocal *arg; WadLocal *arg, *a;
pname = stabstr+s->n_strx; pname = stabstr+s->n_strx;
c = strchr(pname,':'); c = strchr(pname,':');
if (*(c+1) != '(') continue;
if (c) { if (c) {
len = (c-pname); len = (c-pname);
} else { } else {
len = strlen(pname); len = strlen(pname);
} }
/* Get type information */ /* printf("local\n"); */
stab_symbol(s,stabstr); stab_symbol(s,stabstr);
a = f->debug_locals;
/* Check if the argument was already used */ while (a) {
/* In this case, the first stab simply identifies an argument. The second if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) {
one identifies its location for the debugger */ /* We already saw this argument. Given a choice between a register and a stack
argument. We will choose the stack version */
if (f->debug_args) { a->loc = PARM_STACK;
/* Need to do some fix up for linux here */ a->stack = s->n_value;
WadLocal *a = f->debug_args; break;
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 */ a = a->next;
} }
if (a) continue; /* We got an argument match. Just skip to the next stab */
arg = (WadLocal *) wad_malloc(sizeof(WadLocal)); arg = (WadLocal *) wad_malloc(sizeof(WadLocal));
arg->name = (char *) wad_malloc(len+1); {
strncpy(arg->name, pname, len); char t = pname[len];
arg->name[len] = 0; pname[len] = 0;
if (s->n_type == N_RSYM) { arg->name = wad_string_lookup(pname);
arg->loc = PARM_REGISTER; pname[len] = t;
arg->reg = s->n_value;
arg->stack = 0;
} else {
arg->loc = PARM_STACK;
arg->line = s->n_desc;
arg->stack = s->n_value;
} }
arg->loc = PARM_STACK;
arg->line = s->n_desc;
arg->stack = s->n_value;
arg->type = 0; arg->type = 0;
arg->next = 0; arg->next = 0;
{ {
char tname[128]; char tname[128];
char *t = tname; char *t = tname;
c+=2;
c+=1;
while ((*c) && (*c != '=')) { while ((*c) && (*c != '=')) {
*t++ = *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); printf("type_resolve '%s' -> '%s' (%d)\n", tname, t, arg->type);
} }
} }
if (f->debug_args) { if (f->debug_locals) {
f->debug_lastarg->next = arg; f->debug_lastlocal->next = arg;
f->debug_lastarg = arg; f->debug_lastlocal = arg;
} else { } else {
f->debug_args = arg; f->debug_locals = arg;
f->debug_lastarg = arg; f->debug_lastlocal = arg;
f->debug_nargs= 0; 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; objfile[0] = 0;
for (i = 0; i < ns; i++, s++) { 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, 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); stabstr+s->n_strx);
} }
*/
if (s->n_type == N_LSYM) { if (s->n_type == N_LSYM) {
stab_symbol(s,stabstr); stab_symbol(s,stabstr);
continue; 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)) { if (!f->sym_file || (strcmp(f->sym_file,lastfile) == 0)) {
/* Go find debugging information for the function */ /* Go find debugging information for the function */
scan_function(s+1, stabstr, ns -i - 1, f); scan_function(s+1, stabstr, ns -i - 1, f);
f->loc_srcfile = wad_strdup(srcfile); f->loc_srcfile = wad_string_lookup(srcfile);
f->loc_objfile = wad_strdup(objfile); f->loc_objfile = wad_string_lookup(objfile);
/* f->loc_srcfile = wad_strdup(srcfile);
f->loc_objfile = wad_strdup(objfile); */
return 1; return 1;
} }
} }
} }
} }
if (found) { if (found) {
f->loc_srcfile = wad_strdup(srcfile); f->loc_srcfile = wad_string_lookup(srcfile);
f->loc_objfile = wad_strdup(objfile); f->loc_objfile = wad_string_lookup(objfile);
/* f->loc_srcfile = wad_strdup(srcfile);
f->loc_objfile = wad_strdup(objfile); */
} }
return found; return found;
} }

View file

@ -44,6 +44,9 @@ new_frame() {
f->debug_nargs = -1; f->debug_nargs = -1;
f->debug_args = 0; f->debug_args = 0;
f->debug_lastarg = 0; f->debug_lastarg = 0;
f->debug_nlocals = 0;
f->debug_locals = 0;
f->debug_lastlocal = 0;
f->debug_str = 0; f->debug_str = 0;
f->debug_srcstr = 0; f->debug_srcstr = 0;
@ -227,6 +230,18 @@ void wad_stack_debug(WadFrame *frame) {
} }
wad_printf(" ]\n"); 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; frame = frame->next;
} }
} }

View file

@ -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);
}
}

View file

@ -29,6 +29,7 @@ void wad_build_vars(WadFrame *f) {
WadLocal *loc; WadLocal *loc;
int laststack = 0; int laststack = 0;
WadLocal *lastloc = 0; WadLocal *lastloc = 0;
int n;
stack = (char *) f->stack; stack = (char *) f->stack;
if (f->next) { if (f->next) {
@ -37,57 +38,45 @@ void wad_build_vars(WadFrame *f) {
if (f->prev) { if (f->prev) {
pstack = (char *) f->prev->stack; pstack = (char *) f->prev->stack;
} }
loc = f->debug_args;
while (loc) { for (n = 0; n < 2; n++) {
loc->ptr = 0; if (n == 0) loc = f->debug_args;
if (loc->loc == PARM_STACK) { else loc = f->debug_locals;
if ((loc->stack >= 0) && (nstack)) {
loc->ptr = (void *) (nstack + loc->stack); while (loc) {
} else if (loc->stack < 0) { loc->ptr = 0;
loc->ptr = (void *) (stack + f->stack_size + loc->stack); 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 #ifdef WAD_SOLARIS
if ((loc->reg >= 24) && (loc->reg < 32)) { if ((loc->reg >= 24) && (loc->reg < 32)) {
/* Value is located in the %in registers. */ /* Value is located in the %in registers. */
loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int));
loc->size = 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 */ /* Value is located in the %on registers */
if (nstack) { if (nstack) {
loc->ptr = (void *) (stack + (loc->reg)*sizeof(int)); 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); loc->size = sizeof(int);
} }
} else if ((loc->reg >= 16) && (loc->reg < 24)) { #endif
/* Value has been placed in the %ln registers */
loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int));
loc->size = sizeof(int);
} }
#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 */ /* 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; 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;
}