From 22cbb1b6030e0b12d677dadd12d94ea4ec52915a Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Sun, 25 Feb 2001 23:31:30 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@1029 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- SWIG/Tools/WAD/Include/wad.h | 25 ++-- SWIG/Tools/WAD/Python/python.c | 2 +- SWIG/Tools/WAD/Python/type.c | 2 + SWIG/Tools/WAD/Test/debug.c | 18 +++ SWIG/Tools/WAD/Wad/Makefile | 14 +-- SWIG/Tools/WAD/Wad/signal.c | 4 +- SWIG/Tools/WAD/Wad/stab.c | 213 ++++++++++++++++++++++++++++++--- SWIG/Tools/WAD/Wad/vars.c | 114 +++++++++++++----- 8 files changed, 326 insertions(+), 66 deletions(-) diff --git a/SWIG/Tools/WAD/Include/wad.h b/SWIG/Tools/WAD/Include/wad.h index e1a16431c..cf17e41df 100644 --- a/SWIG/Tools/WAD/Include/wad.h +++ b/SWIG/Tools/WAD/Include/wad.h @@ -105,18 +105,19 @@ typedef struct WadLocal { /* Type codes for local variables */ -#define TYPE_UNKNOWN 0 -#define TYPE_INT32 1 -#define TYPE_INT16 2 -#define TYPE_INT8 3 -#define TYPE_INT64 4 -#define TYPE_UINT32 5 -#define TYPE_UINT16 6 -#define TYPE_UINT8 7 -#define TYPE_UINT64 8 -#define TYPE_FLOAT 9 -#define TYPE_DOUBLE 10 -#define TYPE_POINTER 11 +#define WAD_TYPE_UNKNOWN 0 +#define WAD_TYPE_INT32 1 +#define WAD_TYPE_INT16 2 +#define WAD_TYPE_INT8 3 +#define WAD_TYPE_INT64 4 +#define WAD_TYPE_UINT32 5 +#define WAD_TYPE_UINT16 6 +#define WAD_TYPE_UINT8 7 +#define WAD_TYPE_UINT64 8 +#define WAD_TYPE_FLOAT 9 +#define WAD_TYPE_DOUBLE 10 +#define WAD_TYPE_POINTER 11 +#define WAD_TYPE_CHAR 12 /* Data structure containing information about each stack frame */ diff --git a/SWIG/Tools/WAD/Python/python.c b/SWIG/Tools/WAD/Python/python.c index ed09e98fe..cd2de0477 100644 --- a/SWIG/Tools/WAD/Python/python.c +++ b/SWIG/Tools/WAD/Python/python.c @@ -105,7 +105,7 @@ static void handler(int signo, WadFrame *frame, char *ret) { WadFrame *fline = 0; char *srcstr = 0; - printf("python handler.\n"); + /* printf("python handler.\n"); */ if (!ret) { wad_default_callback(signo, frame, ret); return; diff --git a/SWIG/Tools/WAD/Python/type.c b/SWIG/Tools/WAD/Python/type.c index 24b20d338..9bef16bd2 100644 --- a/SWIG/Tools/WAD/Python/type.c +++ b/SWIG/Tools/WAD/Python/type.c @@ -186,6 +186,8 @@ wadobject_getattr(wadobject *self, char *name) { return PyInt_FromLong(1); } + /* Put a check for local variables */ + 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 c7826c067..114e42936 100644 --- a/SWIG/Tools/WAD/Test/debug.c +++ b/SWIG/Tools/WAD/Test/debug.c @@ -60,6 +60,22 @@ int math_crash(int x, int y) { return x/y; } +void type_crash(int a, short b, char c, unsigned long d, float f, double g) { + int la; + short lb; + char lc; + long ld; + float lf; + double lg; + + la = a; + lb = b; + lc = c; + ld = ld; + lf = lf; + lg = lg; + assert(a); +} #ifdef NEED_MAIN @@ -94,6 +110,8 @@ int main(int argc, char **argv) { blowheap_crash(); } else if (strcmp(argv[1],"overflow") == 0) { overflow_crash(); + } else if (strcmp(argv[1],"type") == 0) { + type_crash(0,2,'x',420000,3.14159,2.1828); } } diff --git a/SWIG/Tools/WAD/Wad/Makefile b/SWIG/Tools/WAD/Wad/Makefile index 30275f3fd..9dbd94406 100644 --- a/SWIG/Tools/WAD/Wad/Makefile +++ b/SWIG/Tools/WAD/Wad/Makefile @@ -10,7 +10,7 @@ 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 INCLUDE = -I../Include -I. $(SINCLUDE) -WADOPT = -DWAD_LINUX +WADOPT = -DWAD_SOLARIS # 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/lib/perl5/5.00503/i386-linux/CORE +PERLINCLUDE = -I/usr/perl5/5.00503/sun4-solaris/CORE PERLSRCS = wadpl.cxx PERLOBJS = wadpl.o # C Compiler -CC = gcc -CFLAGS = #-fpic +CC = cc +CFLAGS = # # C++ Compiler -CXX = c++ -CXXFLAGS = #-fpic +CXX = CC +CXXFLAGS = #-Kpic # Linking options CLINK = -CXXLINK = g++ -shared +CXXLINK = CC -G # AR AR = ar diff --git a/SWIG/Tools/WAD/Wad/signal.c b/SWIG/Tools/WAD/Wad/signal.c index e09f084ab..5a1be1c3f 100644 --- a/SWIG/Tools/WAD/Wad/signal.c +++ b/SWIG/Tools/WAD/Wad/signal.c @@ -261,6 +261,8 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { context = (ucontext_t *) vcontext; + wad_printf("WAD: Collecting debugging information...\n"); + /* Read the segments */ if (wad_segment_read() < 0) { wad_printf("WAD: Unable to read segment map\n"); @@ -268,7 +270,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { } if (wad_debug_mode & DEBUG_SIGNAL) { - printf("WAD: siginfo = %x, context = %x\n", si, vcontext); + wad_printf("WAD: siginfo = %x, context = %x\n", si, vcontext); } current_brk = (long) sbrk(0); diff --git a/SWIG/Tools/WAD/Wad/stab.c b/SWIG/Tools/WAD/Wad/stab.c index 19829eb21..c3eb487ee 100644 --- a/SWIG/Tools/WAD/Wad/stab.c +++ b/SWIG/Tools/WAD/Wad/stab.c @@ -43,33 +43,99 @@ 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; struct stabtype *next; + int visit; } stabtype; #define HASH_SIZE 113 static int stab_type_init = 0; -static stabtype *lnames[HASH_SIZE]; /* Hash of local names */ +static stabtype *lnames[HASH_SIZE]; /* Hash of local names */ +static stabtype *deadnames[HASH_SIZE]; /* Hash of dead names */ /* Initialize the hash table */ static void init_hash() { int i; + stabtype *s, *sp = 0; + for (i = 0; i < HASH_SIZE; i++) { + if (stab_type_init) { + /* Add stabs to dead list */ + s = lnames[i]; + sp = 0; + while (s) { + sp = s; + s = s->next; + } + if (sp) { + sp->next = deadnames[i]; + deadnames[i] = lnames[i]; + } + } lnames[i] = 0; } + stab_type_init = 1; } static int thash(char *name) { unsigned int h = 0; int i; for (i = 0; i < 8 && (*name); i++, name++) { - h = ((h << 7) + *name) % HASH_SIZE; + h = ((h << 7) + *name); } - return h; + return (h % HASH_SIZE); } /* Add a symbol to the hash */ @@ -106,18 +172,23 @@ static void type_add(char *name, char *value) { s = lnames[h]; while (s) { if (strcmp(s->name,name) == 0) { - if (strcmp(s->value,v) == 0) { - return; + if (strcmp(s->value,v)) { + s->value = string_lookup(v); } - s->value = (char *) wad_strdup(v); goto add_more; } s = s->next; } - s = (stabtype *) wad_malloc(sizeof(stabtype)); - s->name = wad_strdup(name); - s->value = wad_strdup(v); + s = deadnames[h]; + if (!s) { + s = (stabtype *) wad_malloc(sizeof(stabtype)); + } else { + deadnames[h] = s->next; + } + s->name = string_lookup(name); + s->value = string_lookup(v); s->next = lnames[h]; + s->visit = 0; lnames[h] = s; /* Now take a look at the value. If it is contains other types, we might be able to define more stuff */ @@ -137,13 +208,114 @@ char *type_resolve(char *name) { s = lnames[h]; while(s) { if (strcmp(s->name,name) == 0) { - return type_resolve(s->value); + if (!s->visit) { + char *c; + /* The visit flag is set so that we don't get in infinite loops */ + s->visit = 1; + c = type_resolve(s->value); + s->visit = 0; + return c; + } else { + return name; + } } s = s->next; } return name; } +/* This function tries to resolve base stabs types into a machine equivalent */ +static +int type_typecode(char *name) { + char *range; + + if (name[0] == '*') { + return WAD_TYPE_POINTER; + } + + range = strchr(name,';'); + if (!range) return WAD_TYPE_UNKNOWN; + range++; + + if (name[0] == 'r') { + /* GNU-style range specifiers */ + if ( + (strcmp(range,"0000000000000;0037777777777;") == 0) + ) { + return WAD_TYPE_UINT32; + } + if ( + (strcmp(range,"0020000000000;0017777777777;") == 0) + ) { + return WAD_TYPE_INT32; + } + if ( + (strcmp(range,"-32768;32767;") == 0) + ) { + return WAD_TYPE_INT16; + } + if ( + (strcmp(range,"0;65535;") == 0) + ) { + return WAD_TYPE_UINT16; + } + if ( + (strcmp(range,"0;127;") == 0) + ) { + return WAD_TYPE_CHAR; + } + if ( + (strcmp(range,"-128;127;") == 0) + ) { + return WAD_TYPE_INT8; + } + if ( + (strcmp(range,"0;255;") == 0) + ) { + return WAD_TYPE_UINT8; + } + if ( + (strcmp(range,"4;0;") == 0) + ) { + return WAD_TYPE_FLOAT; + } + if ( + (strcmp(range,"8;0;") == 0) + ) { + return WAD_TYPE_DOUBLE; + } + } + /* Traditional built-in types */ + if (strcmp(name,"bs4;0;32;") == 0) { + return WAD_TYPE_INT32; + } + if (strcmp(name,"bs2;0;16;") == 0) { + return WAD_TYPE_INT16; + } + if (strcmp(name,"bs1;0;8;") == 0) { + return WAD_TYPE_INT8; + } + if (strcmp(name,"bsc1;0;8;") == 0) { + return WAD_TYPE_CHAR; + } + if (strcmp(name,"bu4;0;32;") == 0) { + return WAD_TYPE_UINT32; + } + if (strcmp(name,"bu2;0;16;") == 0) { + return WAD_TYPE_UINT16; + } + if (strcmp(name,"bu1;0;8;") == 0) { + return WAD_TYPE_UINT8; + } + if (strcmp(name,"R1;4;") == 0) { + return WAD_TYPE_FLOAT; + } + if (strcmp(name,"R2;8;") == 0) { + return WAD_TYPE_DOUBLE; + } + return WAD_TYPE_UNKNOWN; +} + static void types_print() { stabtype *s; int i; @@ -249,7 +421,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)) { @@ -323,7 +495,11 @@ scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { *t++ = *c++; } *t = 0; - /* printf("type_resolve '%s' -> '%s'\n", tname, type_resolve(tname));*/ + 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; @@ -361,13 +537,19 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { int slen; int i; int found = 0; + int filefound = 0; + char *file, *lastfile = 0; int chk = 0; WadLocal *arg; 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(); + if (!f->sym_name) return 0; s = (Stab *) sp; /* Stabs data */ @@ -378,11 +560,11 @@ 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; @@ -420,6 +602,7 @@ wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { /* We're going to check for a file match. Maybe we're looking for a local symbol */ if (f->sym_file && strcmp(f->sym_file,file) == 0) { + filefound = 1; found = 1; } lastfile = file; diff --git a/SWIG/Tools/WAD/Wad/vars.c b/SWIG/Tools/WAD/Wad/vars.c index 11b455f13..4991994eb 100644 --- a/SWIG/Tools/WAD/Wad/vars.c +++ b/SWIG/Tools/WAD/Wad/vars.c @@ -90,51 +90,105 @@ void wad_build_vars(WadFrame *f) { } +/* This function creates a formatted integer given a pointer, size, and sign flag */ +static +char *wad_format_int(char *ptr, int nbytes, int sgn) { + static char fmt[128]; + unsigned char *s; + int incr; + unsigned long value = 0; + int i; + +#ifdef WAD_LITTLE_ENDIAN + s = (unsigned char *) (ptr + nbytes - 1); + incr = -1; +#else + s = (unsigned char *) (ptr); + incr = +1; +#endif + for (i = 0; i < nbytes; i++, s += incr) { + value = (value << 8) + *s; + } + if (sgn) { + sprintf(fmt,"%ld", (long) value); + } else { + sprintf(fmt,"%lu", value); + } + return fmt; +} + /* Try to make a formatted version of a local */ char *wad_format_var(WadLocal *l) { static char hexdigits[] = "0123456789abcdef"; static char buffer[1024]; + double dval; + float fval; buffer[0] = 0; switch(l->type) { - case TYPE_UNKNOWN: + case WAD_TYPE_INT32: + strcpy(buffer,wad_format_int(l->ptr,4,1)); + break; + case WAD_TYPE_UINT32: + strcpy(buffer,wad_format_int(l->ptr,4,0)); + break; + case WAD_TYPE_INT16: + strcpy(buffer,wad_format_int(l->ptr,2,1)); + break; + case WAD_TYPE_UINT16: + strcpy(buffer,wad_format_int(l->ptr,2,0)); + break; + case WAD_TYPE_INT8: + strcpy(buffer,wad_format_int(l->ptr,1,1)); + break; + case WAD_TYPE_UINT8: + strcpy(buffer,wad_format_int(l->ptr,1,0)); + break; + case WAD_TYPE_CHAR: + sprintf(buffer,"'%c'", *((char *)l->ptr)); + break; + case WAD_TYPE_FLOAT: + memcpy(&fval,l->ptr,sizeof(float)); + sprintf(buffer,"%g",fval); + break; + case WAD_TYPE_DOUBLE: + memcpy(&dval,l->ptr,sizeof(double)); + sprintf(buffer,"%g",dval); + break; + case WAD_TYPE_UNKNOWN: + case WAD_TYPE_POINTER: default: - /* Hmmm. Unknown data type. We'll just dump out digits */ + /* Hmmm. Unknown data type. We'll just treat it as a word */ if (l->ptr) { - if (l->size <= 8) { - int incr,i; - int b; - int leading = 1; - char *c; - char *ptr; + int incr,i; + int b; + int leading = 1; + char *c; + char *ptr; #ifdef WAD_LITTLE_ENDIAN - ptr = ((char *) l->ptr) + l->size - 1; - incr = -1; + ptr = ((char *) l->ptr) + 3; + incr = -1; #else - ptr = (char *) l->ptr; - incr =1 ; + ptr = (char *) l->ptr; + incr =1 ; #endif - strcat(buffer,"0x"); - c = buffer+2; - /* for (i = 0; i < l->size; i++) { */ - for (i = 0; i < 4; i++) { - b = (int) *ptr; - if (!leading || (b)) { - if (!leading || (b & 0xf0)) - *(c++) = hexdigits[(b & 0xf0) >> 4]; - *(c++) = hexdigits[(b & 0xf)]; - leading = 0; - } - ptr += incr; + strcat(buffer,"0x"); + c = buffer+2; + for (i = 0; i < 4; i++) { + b = (int) *ptr; + if (!leading || (b)) { + if (!leading || (b & 0xf0)) + *(c++) = hexdigits[(b & 0xf0) >> 4]; + *(c++) = hexdigits[(b & 0xf)]; + leading = 0; } - if (leading) - *(c++) = '0'; - - *c = 0; - } else { - sprintf(buffer,"unknown(%d bytes)", l->size); + ptr += incr; } + if (leading) + *(c++) = '0'; + + *c = 0; } } return buffer;