*** 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:
parent
22cbb1b603
commit
b4fc95efca
16 changed files with 502 additions and 202 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
93
SWIG/Tools/WAD/Wad/string.c
Normal file
93
SWIG/Tools/WAD/Wad/string.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue