Linux stuff

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@951 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-11-23 22:26:33 +00:00
commit 344fa26627
12 changed files with 217 additions and 39 deletions

View file

@ -172,6 +172,10 @@ extern WadReturnFunc *wad_check_return(const char *name);
#define DEBUG_FILE 0x10 #define DEBUG_FILE 0x10
#define DEBUG_HOLD 0x20 #define DEBUG_HOLD 0x20
#define DEBUG_RETURN 0x40 #define DEBUG_RETURN 0x40
#define DEBUG_SYMBOL_SEARCH 0x80
#define DEBUG_INIT 0x100
#define DEBUG_NOSTACK 0x200
#define DEBUG_ONESHOT 0x400
extern int wad_debug_mode; extern int wad_debug_mode;

View file

@ -1,23 +1,24 @@
SRCS = return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c SRCS = return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
OBJS = return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o main.o OBJS = return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o
INCLUDE = -I../Include -I. INCLUDE = -I../Include -I.
OPT = -DWAD_SOLARIS OPT = -DWAD_SOLARIS
LIBS = LIBS =
PYINCLUDE = -I/usr/local/include/python2.0 #PYINCLUDE = -I/usr/local/include/python2.0
PYINCLUDE = -I/usr/local/include/python1.5
TCLINCLUDE = -I/usr/local/include TCLINCLUDE = -I/usr/local/include
all:: all::
CC -Kpic -c $(OPT) $(INCLUDE) main.cxx CC -Kpic -c $(OPT) $(INCLUDE) main.cxx
cc -c $(OPT) $(INCLUDE) $(SRCS) cc -c $(OPT) $(INCLUDE) $(SRCS)
CC -G $(OBJS) -o libwad.so $(LIBS) CC -G $(OBJS) main.o -o libwad.so $(LIBS)
cp libwad.so .. cp libwad.so ..
python:: python::
cc -c $(OPT) $(INCLUDE) $(SRCS) cc -c $(OPT) $(INCLUDE) $(SRCS)
CC -Kpic -c $(INCLUDE) $(PYINCLUDE) wadpy.cxx CC -Kpic -c $(INCLUDE) $(PYINCLUDE) wadpy.cxx
CC -G $(OBJS) wadpy.o -o libwadpy.so $(LIBS) CC -G $(OBJS) main.o wadpy.o -o libwadpy.so $(LIBS)
cp libwadpy.so .. cp libwadpy.so ..
tcl:: tcl::
@ -28,7 +29,19 @@ tcl::
cp libwadtcl.so .. cp libwadtcl.so ..
linux:: linux::
cc -DWAD_LINUX $(INCLUDE) segment.c init.c debug.c g++ -fpic -c -DWAD_LINUX $(INCLUDE) main.cxx
gcc -g -c -DWAD_LINUX $(INCLUDE) $(SRCS)
g++ -shared $(OBJS) main.o -o libwad.so $(LIBS)
cp libwad.so ..
linux-python::
gcc -c -DWAD_LINUX $(INCLUDE) $(SRCS)
g++ -fpic -c -DWAD_LINUX $(INCLUDE) $(PYINCLUDE) wadpy.cxx
g++ -shared $(OBJS) wadpy.o -o libwadpy.so $(LIBS)
cp libwadpy.so ..
linux2::
cc -DWAD_LINUX $(INCLUDE) signal.c stack.c default.c demangle.c return.c stab.c elf.c object.c segment.c init.c debug.c
debug:: debug::
cc -g debug.c $(INCLUDE) -L. -R. -lwad cc -g debug.c $(INCLUDE) -L. -R. -lwad

View file

@ -27,6 +27,11 @@ char *wad_arg_string(WadFrame *frame) {
int i; int i;
WadFrame *nf; WadFrame *nf;
#ifdef WAD_LINUX
strcat(str,"");
return str;
#endif
if (frame->size) if (frame->size)
nf = (WadFrame *) (((char *) frame) + frame->size); nf = (WadFrame *) (((char *) frame) + frame->size);
else else
@ -97,6 +102,7 @@ char *wad_arg_string(WadFrame *frame) {
char *wad_strip_dir(char *name) { char *wad_strip_dir(char *name) {
char *c; char *c;
/* printf("strip: '%s'\n", name); */
c = name + strlen(name); c = name + strlen(name);
while (c != name) { while (c != name) {
if (*c == '/') { if (*c == '/') {
@ -202,7 +208,14 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
printf(" in '%s'", wad_strip_dir(fd+f->src_off)); printf(" in '%s'", wad_strip_dir(fd+f->src_off));
if (f->line_number > 0) { if (f->line_number > 0) {
printf(", line %d", f->line_number); printf(", line %d", f->line_number);
fline = f; {
int fd;
fd = open(SRCFILE(f), O_RDONLY);
if (fd > 0) {
fline = f;
}
close(fd);
}
} }
} else { } else {
if (strlen(fd+f->obj_off)) { if (strlen(fd+f->obj_off)) {

View file

@ -224,9 +224,9 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
vaddr = (unsigned long) ptr; vaddr = (unsigned long) ptr;
nsymtab = wad_elf_section_byname(wo,".symtab"); nsymtab = wad_elf_section_byname(wo,".symtab");
if (nsymtab < 0) return 0; if (nsymtab < 0) goto dynsym;
nstrtab = wad_elf_section_byname(wo,".strtab"); nstrtab = wad_elf_section_byname(wo,".strtab");
if (nstrtab < 0) return 0; if (nstrtab < 0) goto dynsym;
symtab_size = wad_elf_section_size(wo,nsymtab); symtab_size = wad_elf_section_size(wo,nsymtab);
sym = (Elf32_Sym *) wad_elf_section_data(wo,nsymtab); sym = (Elf32_Sym *) wad_elf_section_data(wo,nsymtab);
@ -239,7 +239,15 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) { if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) {
localfile = name; localfile = name;
} }
if (((base + sym[i].st_value) <= vaddr) && (vaddr < (base+sym[i].st_value + sym[i].st_size))) { if (wad_debug_mode & DEBUG_SYMBOL_SEARCH) {
printf("%x(%x): %s %x + %x, %x, %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size, sym[i].st_info, sym[i].st_shndx);
}
if (((base + sym[i].st_value) <= vaddr) && (vaddr <= (base+sym[i].st_value + sym[i].st_size))) {
#ifdef WAD_LINUX
/* If the section index is 0, the symbol is undefined */
if (sym[i].st_shndx == 0) continue;
#endif
ws->value = sym[i].st_value; ws->value = sym[i].st_value;
if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) { if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) {
ws->file = localfile; ws->file = localfile;
@ -250,9 +258,10 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
ws->name = name; ws->name = name;
return name; return name;
} }
} }
dynsym:
/* If we didn't find it in the .symtab section. Maybe it's in the .dynsym, .dynstr section */ /* If we didn't find it in the .symtab section. Maybe it's in the .dynsym, .dynstr section */
nsymtab = wad_elf_section_byname(wo,".dynsym"); nsymtab = wad_elf_section_byname(wo,".dynsym");
@ -271,8 +280,14 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) { if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) {
localfile = name; localfile = name;
} }
/* printf("%x(%x): %s %x + %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size); */ if (wad_debug_mode & DEBUG_SYMBOL_SEARCH) {
if (((base + sym[i].st_value) <= vaddr) && (vaddr < (base+sym[i].st_value + sym[i].st_size))) { printf("%x(%x): %s %x + %x, %x, %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size, sym[i].st_info, sym[i].st_shndx);
}
if (((base + sym[i].st_value) <= vaddr) && (vaddr <= (base+sym[i].st_value + sym[i].st_size))) {
#ifdef WAD_LINUX
/* If the section index is 0, the symbol is undefined */
if (sym[i].st_shndx == 0) continue;
#endif
ws->value = sym[i].st_value; ws->value = sym[i].st_value;
if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) { if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) {
ws->file = localfile; ws->file = localfile;

View file

@ -46,11 +46,29 @@ void wad_init() {
wad_debug_mode |= DEBUG_RETURN; wad_debug_mode |= DEBUG_RETURN;
} }
#ifndef WAD_LINUX if (getenv("WAD_DEBUG_SYMBOL_SEARCH")) {
wad_debug_mode |= DEBUG_SYMBOL_SEARCH;
}
if (getenv("WAD_DEBUG_INIT")) {
wad_debug_mode |= DEBUG_INIT;
}
if (getenv("WAD_NOSTACK")) {
wad_debug_mode |= DEBUG_NOSTACK;
}
if (getenv("WAD_ONESHOT")) {
wad_debug_mode |= DEBUG_ONESHOT;
}
if (wad_debug_mode & DEBUG_INIT) {
printf("WAD: initializing\n");
}
if (!init) { if (!init) {
wad_signal_init(); wad_signal_init();
wad_object_init(); wad_object_init();
} }
#endif
init = 1; init = 1;
} }

View file

@ -11,10 +11,14 @@
* See the file LICENSE for information on usage and redistribution. * See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static char linux_firstsegment[1024];
static int linux_first = 1;
static FILE * static FILE *
segment_open() { segment_open() {
FILE *f; FILE *f;
f = fopen("/proc/self/maps", "r"); f = fopen("/proc/self/maps", "r");
linux_first =1;
return f; return f;
} }
@ -38,7 +42,7 @@ segment_read(FILE *fs, WadSegment *s)
21 : p 21 : p
23-31 : Offset 23-31 : Offset
49- : Filename */ 49- : Filename */
len = strlen(pbuffer); len = strlen(pbuffer);
pbuffer[8] = 0; pbuffer[8] = 0;
pbuffer[17] = 0; pbuffer[17] = 0;
@ -49,10 +53,18 @@ segment_read(FILE *fs, WadSegment *s)
strcpy(s->mapname, pbuffer+49); strcpy(s->mapname, pbuffer+49);
strcpy(s->mappath, pbuffer+49); strcpy(s->mappath, pbuffer+49);
} }
if (linux_first) {
strcpy(linux_firstsegment, s->mappath);
linux_first = 0;
}
s->vaddr = (char *) strtoul(pbuffer,NULL,16); s->vaddr = (char *) strtoul(pbuffer,NULL,16);
s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr); s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr);
s->offset = strtoul(pbuffer+23,NULL,16); s->offset = strtoul(pbuffer+23,NULL,16);
s->base = s->vaddr; if (strcmp(linux_firstsegment, s->mappath) == 0) {
s->base = 0;
} else {
s->base = s->vaddr;
}
s++; s++;
return 1; return 1;
} }

View file

@ -29,7 +29,7 @@ void wad_set_return(const char *name, long value) {
} }
void wad_set_returns(WadReturnFunc *rf) { void wad_set_returns(WadReturnFunc *rf) {
int i; int i = 0;
while (strlen(rf[i].name)) { while (strlen(rf[i].name)) {
wad_set_return(rf[i].name, rf[i].value); wad_set_return(rf[i].name, rf[i].value);
i++; i++;

View file

@ -99,7 +99,7 @@ wad_segment_read() {
s->size = ws.size; s->size = ws.size;
s->offset = ws.offset; s->offset = ws.offset;
if (wad_debug_mode & DEBUG_SEGMENT) { if (wad_debug_mode & DEBUG_SEGMENT) {
printf("wad_segment: read : %08x-%08x in %s\n", s->vaddr, ((char *) s->vaddr) + s->size, s->mappath); printf("wad_segment: read : %08x-%08x, base=%x in %s\n", s->vaddr, ((char *) s->vaddr) + s->size, s->base, s->mappath);
} }
s++; s++;
} }

View file

@ -29,7 +29,7 @@ void wad_set_callback(void (*s)(int,WadFrame *,char *ret)) {
normally. */ normally. */
static int nlr_levels = 0; static int nlr_levels = 0;
static int *volatile nlr_p = &nlr_levels; static volatile int *volatile nlr_p = &nlr_levels;
static long nlr_value = 0; static long nlr_value = 0;
/* Set the return value from another module */ /* Set the return value from another module */
@ -37,6 +37,7 @@ void wad_set_return_value(long value) {
nlr_value = value; nlr_value = value;
} }
#ifdef WAD_SOLARIS
static void nonlocalret() { static void nonlocalret() {
long a; long a;
@ -65,15 +66,32 @@ static void nonlocalret() {
asm("restore"); asm("restore");
asm(".size _returnsignal,(.-_returnsignal)"); asm(".size _returnsignal,(.-_returnsignal)");
} }
#endif
#ifdef WAD_LINUX
static void nonlocalret() {
asm("_returnsignal:");
while (*nlr_p > 0) {
(*nlr_p)--;
asm("leave");
}
asm("movl nlr_value, %eax");
asm("leave");
asm("ret");
}
#endif
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
greg_t *pc; greg_t *pc;
greg_t *npc; greg_t *npc;
greg_t *sp; greg_t *sp;
greg_t *fp;
unsigned long addr; unsigned long addr;
ucontext_t *context; ucontext_t *context;
unsigned long p_sp; /* process stack pointer */ unsigned long p_sp; /* process stack pointer */
unsigned long p_pc; /* Process program counter */ unsigned long p_pc; /* Process program counter */
unsigned long p_fp; /* Process frame pointer */
int nlevels = 0; int nlevels = 0;
int found = 0; int found = 0;
void _returnsignal(); void _returnsignal();
@ -86,15 +104,30 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
context = (ucontext_t *) vcontext; context = (ucontext_t *) vcontext;
/* Get some information about the current context */ /* Get some information about the current context */
#ifdef WAD_SOLARIS
pc = &((context->uc_mcontext).gregs[REG_PC]); pc = &((context->uc_mcontext).gregs[REG_PC]);
npc = &((context->uc_mcontext).gregs[REG_nPC]); npc = &((context->uc_mcontext).gregs[REG_nPC]);
sp = &((context->uc_mcontext).gregs[REG_SP]); sp = &((context->uc_mcontext).gregs[REG_SP]);
#endif
#ifdef WAD_LINUX
sp = &((context->uc_mcontext).gregs[ESP]); /* Top of stack */
fp = &((context->uc_mcontext).gregs[EBP]); /* Stack base - frame pointer */
pc = &((context->uc_mcontext).gregs[EIP]); /* Current instruction */
/* printf("&sp = %x, &pc = %x\n", sp, pc); */
#endif
/* Get some information out of the signal handler stack */ /* Get some information out of the signal handler stack */
addr = (unsigned long) si->si_addr; addr = (unsigned long) si->si_addr;
p_pc = (unsigned long) (*pc); p_pc = (unsigned long) (*pc);
p_sp = (unsigned long) (*sp); p_sp = (unsigned long) (*sp);
frame = wad_stack_trace(p_pc, p_sp, 0); #ifdef WAD_LINUX
p_fp = (unsigned long) (*fp);
/* printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp); */
#endif
frame = wad_stack_trace(p_pc, p_sp, p_fp);
origframe =frame; origframe =frame;
if (!frame) { if (!frame) {
/* We're really hosed here */ /* We're really hosed here */
@ -144,7 +177,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
if (nlr_levels > 0) { if (nlr_levels > 0) {
*(pc) = (greg_t) _returnsignal; *(pc) = (greg_t) _returnsignal;
#ifdef WAD_SOLARIS
*(npc) = *(pc) + 4; *(npc) = *(pc) + 4;
#endif
return; return;
} }
exit(1); exit(1);
@ -160,12 +195,19 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
void wad_signal_init() { void wad_signal_init() {
struct sigaction newvec; struct sigaction newvec;
static stack_t sigstk; static stack_t sigstk;
if (wad_debug_mode & DEBUG_INIT) {
printf("WAD: Initializing signal handler.\n");
}
/* Set up an alternative stack */ /* Set up an alternative stack */
sigstk.ss_sp = (char *) wad_sig_stack; sigstk.ss_sp = (char *) wad_sig_stack;
sigstk.ss_size = STACK_SIZE; sigstk.ss_size = STACK_SIZE;
sigstk.ss_flags = 0; sigstk.ss_flags = 0;
if (sigaltstack(&sigstk, (stack_t*)0) < 0) { if (!(wad_debug_mode & DEBUG_NOSTACK)) {
perror("sigaltstack"); if (sigaltstack(&sigstk, (stack_t*)0) < 0) {
perror("sigaltstack");
}
} }
sigemptyset(&newvec.sa_mask); sigemptyset(&newvec.sa_mask);
sigaddset(&newvec.sa_mask, SIGSEGV); sigaddset(&newvec.sa_mask, SIGSEGV);
@ -173,11 +215,24 @@ void wad_signal_init() {
sigaddset(&newvec.sa_mask, SIGABRT); sigaddset(&newvec.sa_mask, SIGABRT);
sigaddset(&newvec.sa_mask, SIGILL); sigaddset(&newvec.sa_mask, SIGILL);
sigaddset(&newvec.sa_mask, SIGFPE); sigaddset(&newvec.sa_mask, SIGFPE);
newvec.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESETHAND; newvec.sa_flags = SA_SIGINFO;
if (wad_debug_mode & DEBUG_ONESHOT) {
newvec.sa_flags |= SA_RESETHAND;
}
if (!(wad_debug_mode & DEBUG_NOSTACK)) {
newvec.sa_flags |= SA_ONSTACK;
}
newvec.sa_sigaction = ((void (*)(int,siginfo_t *, void *)) wad_signalhandler); newvec.sa_sigaction = ((void (*)(int,siginfo_t *, void *)) wad_signalhandler);
sigaction(SIGSEGV, &newvec, NULL); if (sigaction(SIGSEGV, &newvec, NULL) < 0) goto werror;
sigaction(SIGBUS, &newvec, NULL); if (sigaction(SIGBUS, &newvec, NULL) < 0) goto werror;
sigaction(SIGABRT, &newvec, NULL); if (sigaction(SIGABRT, &newvec, NULL) < 0) goto werror;
sigaction(SIGFPE, &newvec, NULL); if (sigaction(SIGFPE, &newvec, NULL) < 0) goto werror;
sigaction(SIGILL, &newvec, NULL); if (sigaction(SIGILL, &newvec, NULL) < 0) goto werror;
return;
werror:
printf("WAD: Couldn't install signal handler!\n");
} }

View file

@ -19,7 +19,7 @@ typedef struct Stab {
unsigned n_strx; /* index into file string table */ unsigned n_strx; /* index into file string table */
unsigned char n_type; /* type flag (N_TEXT,..) */ unsigned char n_type; /* type flag (N_TEXT,..) */
char n_other; /* used by N_SLINE stab */ char n_other; /* used by N_SLINE stab */
short n_desc; /* see stabs documentation */ unsigned short n_desc; /* see stabs documentation */
unsigned n_value; /* value of symbol (or sdb offset) */ unsigned n_value; /* value of symbol (or sdb offset) */
} Stab; } Stab;
@ -62,6 +62,7 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
s = (Stab *) sp; /* Stabs data */ s = (Stab *) sp; /* Stabs data */
ns = size/sizeof(Stab); /* number of stabs */ ns = size/sizeof(Stab); /* number of stabs */
slen = strlen(wsym->name); slen = strlen(wsym->name);
/* Reset the debug information section */ /* Reset the debug information section */
@ -72,27 +73,39 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
debug->nargs = 0; debug->nargs = 0;
for (i = 0; i < ns; i++, s++) { for (i = 0; i < ns; i++, s++) {
/*#define DEBUG_DEBUG */ /*#define DEBUG_DEBUG */
if (wad_debug_mode & DEBUG_STABS) if (wad_debug_mode & DEBUG_STABS) {
/* printf(" %10d %10x %10d %10d %10d: '%x'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value,
stabstr+s->n_strx); */
printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, 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 == 0) { }
if ((s->n_type == 0)) { /* && (s->n_desc >= 0)) { */
/* New stabs section. We need to be a little careful here. Do a recursive /* New stabs section. We need to be a little careful here. Do a recursive
search of the subsection. */ search of the subsection. */
if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, wsym, offset,debug)) return 1; if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, wsym, offset,debug)) return 1;
/* On solaris, each stabs section seem to increment the stab string pointer. On Linux,
the linker seems to do a certain amount of optimization that results in a single
string table. */
#ifdef WAD_SOLARIS
stabstr += s->n_value; /* Update the string table location*/ stabstr += s->n_value; /* Update the string table location*/
#endif
i += s->n_desc; i += s->n_desc;
s += s->n_desc; s += s->n_desc;
debug->objfile[0] = 0; debug->objfile[0] = 0;
debug->srcfile[0] = 0; debug->srcfile[0] = 0;
debug->line_number = -1; debug->line_number = -1;
debug->found = 0; debug->found = 0;
continue;
} else if (s->n_type == 0x64) { } else if (s->n_type == 0x64) {
if (debug->found) return 1; /* New file and we already found what we wanted */ if (debug->found) return 1; /* New file and we already found what we wanted */
/* Source file specification */ /* Source file specification */
/* Look for directory */ /* Look for directory */
file = stabstr+s->n_strx; file = stabstr+s->n_strx;
if (file[strlen(file)] == '/') { if (strlen(file) && (file[strlen(file)-1] == '/')) {
strcpy(debug->srcfile,file); strcpy(debug->srcfile,file);
} else { } else {
strcat(debug->srcfile,file); strcat(debug->srcfile,file);

View file

@ -18,9 +18,25 @@
unwinding */ unwinding */
static void static void
stack_unwind(unsigned long *sp, unsigned long *pc) { stack_unwind(unsigned long *sp, unsigned long *pc, unsigned long *fp) {
#ifdef WAD_SOLARIS
*pc = *((unsigned long *) *sp+15); /* %i7 - Return address */ *pc = *((unsigned long *) *sp+15); /* %i7 - Return address */
*sp = *((unsigned long *) *sp+14); /* %i6 - frame pointer */ *sp = *((unsigned long *) *sp+14); /* %i6 - frame pointer */
#endif
#ifdef WAD_LINUX
*pc = *((unsigned long *) *fp+1);
*sp = *fp;
*fp = *((unsigned long *) *fp);
/* If we get a frame pointer of zero, we've gone off the end of the stack. Set the
stack pointer to zero to signal the stack unwinder. */
if (*fp == 0) {
*sp = 0;
}
#endif
} }
static void *trace_addr = 0; static void *trace_addr = 0;
@ -42,6 +58,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
int ffile; int ffile;
unsigned long p_pc; unsigned long p_pc;
unsigned long p_sp; unsigned long p_sp;
unsigned long p_fp;
unsigned long p_lastsp; unsigned long p_lastsp;
int n = 0; int n = 0;
@ -64,10 +81,12 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
nlevels = 0; nlevels = 0;
p_pc = pc; p_pc = pc;
p_sp = sp; p_sp = sp;
p_fp = fp;
while (p_sp) { while (p_sp) {
/* Add check for stack validity here */ /* Add check for stack validity here */
ws = wad_segment_find(segments, (void *) p_sp); ws = wad_segment_find(segments, (void *) p_sp);
if (!ws) { if (!ws) {
/* If the stack is bad, we are really hosed here */ /* If the stack is bad, we are really hosed here */
break; break;
@ -101,6 +120,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
symname = 0; symname = 0;
} }
/* if (symname) symname = wad_cplus_demangle(&wsym); */ /* if (symname) symname = wad_cplus_demangle(&wsym); */
value = wsym.value; value = wsym.value;
@ -142,6 +162,8 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
} }
} }
#ifdef WAD_SOLARIS
/* Before unwinding the stack, copy the locals and %o registers from previous frame */ /* Before unwinding the stack, copy the locals and %o registers from previous frame */
if (!firstframe) { if (!firstframe) {
int i; int i;
@ -151,18 +173,22 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
frame.regs[i] = lsp[i]; frame.regs[i] = lsp[i];
} }
} }
#endif
firstframe = 0; firstframe = 0;
/* Determine stack frame size */ /* Determine stack frame size */
p_lastsp = p_sp; p_lastsp = p_sp;
stack_unwind(&p_sp, &p_pc); stack_unwind(&p_sp, &p_pc, &p_fp);
if (p_sp) { if (p_sp) {
stacksize = p_sp - p_lastsp; stacksize = p_sp - p_lastsp;
} else { } else {
#ifdef WAD_SOLARIS
stacksize = 0xffbf0000 - p_lastsp; /* Sick hack alert. Need to get stack top from somewhere */ stacksize = 0xffbf0000 - p_lastsp; /* Sick hack alert. Need to get stack top from somewhere */
#endif
#ifdef WAD_LINUX
stacksize = 0xc0000000 - p_lastsp;
#endif
} }
/* Set the frame pointer and stack size */ /* Set the frame pointer and stack size */
frame.fp = p_sp; frame.fp = p_sp;
frame.stack_size = stacksize; frame.stack_size = stacksize;

View file

@ -155,7 +155,14 @@ static void handler(int signo, WadFrame *frame, char *ret) {
if (f->line_number > 0) { if (f->line_number > 0) {
sprintf(temp,", line %d", f->line_number); sprintf(temp,", line %d", f->line_number);
strcat(message,temp); strcat(message,temp);
fline = f; {
int fd;
fd = open(SRCFILE(f), O_RDONLY);
if (fd > 0) {
fline = f;
}
close(fd);
}
} }
} else { } else {
if (strlen(fd+f->obj_off)) { if (strlen(fd+f->obj_off)) {
@ -251,3 +258,5 @@ extern "C"
void initlibwadpy() { void initlibwadpy() {
Py_InitModule((char *)"libwadpy",wadmethods); Py_InitModule((char *)"libwadpy",wadmethods);
} }