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:
parent
6b8ce695b8
commit
344fa26627
12 changed files with 217 additions and 39 deletions
|
|
@ -172,6 +172,10 @@ extern WadReturnFunc *wad_check_return(const char *name);
|
|||
#define DEBUG_FILE 0x10
|
||||
#define DEBUG_HOLD 0x20
|
||||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
|
||||
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.
|
||||
OPT = -DWAD_SOLARIS
|
||||
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
|
||||
|
||||
all::
|
||||
CC -Kpic -c $(OPT) $(INCLUDE) main.cxx
|
||||
cc -c $(OPT) $(INCLUDE) $(SRCS)
|
||||
CC -G $(OBJS) -o libwad.so $(LIBS)
|
||||
CC -G $(OBJS) main.o -o libwad.so $(LIBS)
|
||||
cp libwad.so ..
|
||||
|
||||
python::
|
||||
cc -c $(OPT) $(INCLUDE) $(SRCS)
|
||||
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 ..
|
||||
|
||||
tcl::
|
||||
|
|
@ -28,7 +29,19 @@ tcl::
|
|||
cp libwadtcl.so ..
|
||||
|
||||
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::
|
||||
cc -g debug.c $(INCLUDE) -L. -R. -lwad
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ char *wad_arg_string(WadFrame *frame) {
|
|||
int i;
|
||||
WadFrame *nf;
|
||||
|
||||
#ifdef WAD_LINUX
|
||||
strcat(str,"");
|
||||
return str;
|
||||
#endif
|
||||
|
||||
if (frame->size)
|
||||
nf = (WadFrame *) (((char *) frame) + frame->size);
|
||||
else
|
||||
|
|
@ -97,6 +102,7 @@ char *wad_arg_string(WadFrame *frame) {
|
|||
|
||||
char *wad_strip_dir(char *name) {
|
||||
char *c;
|
||||
/* printf("strip: '%s'\n", name); */
|
||||
c = name + strlen(name);
|
||||
while (c != name) {
|
||||
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));
|
||||
if (f->line_number > 0) {
|
||||
printf(", line %d", f->line_number);
|
||||
fline = f;
|
||||
{
|
||||
int fd;
|
||||
fd = open(SRCFILE(f), O_RDONLY);
|
||||
if (fd > 0) {
|
||||
fline = f;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen(fd+f->obj_off)) {
|
||||
|
|
|
|||
|
|
@ -224,9 +224,9 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
|
|||
vaddr = (unsigned long) ptr;
|
||||
|
||||
nsymtab = wad_elf_section_byname(wo,".symtab");
|
||||
if (nsymtab < 0) return 0;
|
||||
if (nsymtab < 0) goto dynsym;
|
||||
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);
|
||||
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) {
|
||||
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;
|
||||
if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) {
|
||||
ws->file = localfile;
|
||||
|
|
@ -250,9 +258,10 @@ wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, WadSymbol
|
|||
ws->name = name;
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dynsym:
|
||||
|
||||
/* 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");
|
||||
|
|
@ -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) {
|
||||
localfile = name;
|
||||
}
|
||||
/* printf("%x(%x): %s %x + %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size); */
|
||||
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;
|
||||
if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) {
|
||||
ws->file = localfile;
|
||||
|
|
|
|||
|
|
@ -46,11 +46,29 @@ void wad_init() {
|
|||
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) {
|
||||
wad_signal_init();
|
||||
wad_object_init();
|
||||
}
|
||||
#endif
|
||||
init = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@
|
|||
* See the file LICENSE for information on usage and redistribution.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static char linux_firstsegment[1024];
|
||||
static int linux_first = 1;
|
||||
|
||||
static FILE *
|
||||
segment_open() {
|
||||
FILE *f;
|
||||
f = fopen("/proc/self/maps", "r");
|
||||
linux_first =1;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +42,7 @@ segment_read(FILE *fs, WadSegment *s)
|
|||
21 : p
|
||||
23-31 : Offset
|
||||
49- : Filename */
|
||||
|
||||
|
||||
len = strlen(pbuffer);
|
||||
pbuffer[8] = 0;
|
||||
pbuffer[17] = 0;
|
||||
|
|
@ -49,10 +53,18 @@ segment_read(FILE *fs, WadSegment *s)
|
|||
strcpy(s->mapname, 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->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr);
|
||||
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++;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void wad_set_return(const char *name, long value) {
|
|||
}
|
||||
|
||||
void wad_set_returns(WadReturnFunc *rf) {
|
||||
int i;
|
||||
int i = 0;
|
||||
while (strlen(rf[i].name)) {
|
||||
wad_set_return(rf[i].name, rf[i].value);
|
||||
i++;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ wad_segment_read() {
|
|||
s->size = ws.size;
|
||||
s->offset = ws.offset;
|
||||
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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void wad_set_callback(void (*s)(int,WadFrame *,char *ret)) {
|
|||
normally. */
|
||||
|
||||
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;
|
||||
|
||||
/* Set the return value from another module */
|
||||
|
|
@ -37,6 +37,7 @@ void wad_set_return_value(long value) {
|
|||
nlr_value = value;
|
||||
}
|
||||
|
||||
#ifdef WAD_SOLARIS
|
||||
static void nonlocalret() {
|
||||
long a;
|
||||
|
||||
|
|
@ -65,15 +66,32 @@ static void nonlocalret() {
|
|||
asm("restore");
|
||||
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) {
|
||||
greg_t *pc;
|
||||
greg_t *npc;
|
||||
greg_t *sp;
|
||||
greg_t *fp;
|
||||
|
||||
unsigned long addr;
|
||||
ucontext_t *context;
|
||||
unsigned long p_sp; /* process stack pointer */
|
||||
unsigned long p_pc; /* Process program counter */
|
||||
unsigned long p_fp; /* Process frame pointer */
|
||||
int nlevels = 0;
|
||||
int found = 0;
|
||||
void _returnsignal();
|
||||
|
|
@ -86,15 +104,30 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
context = (ucontext_t *) vcontext;
|
||||
|
||||
/* Get some information about the current context */
|
||||
|
||||
#ifdef WAD_SOLARIS
|
||||
pc = &((context->uc_mcontext).gregs[REG_PC]);
|
||||
npc = &((context->uc_mcontext).gregs[REG_nPC]);
|
||||
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 */
|
||||
addr = (unsigned long) si->si_addr;
|
||||
p_pc = (unsigned long) (*pc);
|
||||
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;
|
||||
if (!frame) {
|
||||
/* We're really hosed here */
|
||||
|
|
@ -144,7 +177,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
|
||||
if (nlr_levels > 0) {
|
||||
*(pc) = (greg_t) _returnsignal;
|
||||
#ifdef WAD_SOLARIS
|
||||
*(npc) = *(pc) + 4;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
exit(1);
|
||||
|
|
@ -160,12 +195,19 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
void wad_signal_init() {
|
||||
struct sigaction newvec;
|
||||
static stack_t sigstk;
|
||||
|
||||
if (wad_debug_mode & DEBUG_INIT) {
|
||||
printf("WAD: Initializing signal handler.\n");
|
||||
}
|
||||
|
||||
/* Set up an alternative stack */
|
||||
sigstk.ss_sp = (char *) wad_sig_stack;
|
||||
sigstk.ss_size = STACK_SIZE;
|
||||
sigstk.ss_flags = 0;
|
||||
if (sigaltstack(&sigstk, (stack_t*)0) < 0) {
|
||||
perror("sigaltstack");
|
||||
if (!(wad_debug_mode & DEBUG_NOSTACK)) {
|
||||
if (sigaltstack(&sigstk, (stack_t*)0) < 0) {
|
||||
perror("sigaltstack");
|
||||
}
|
||||
}
|
||||
sigemptyset(&newvec.sa_mask);
|
||||
sigaddset(&newvec.sa_mask, SIGSEGV);
|
||||
|
|
@ -173,11 +215,24 @@ void wad_signal_init() {
|
|||
sigaddset(&newvec.sa_mask, SIGABRT);
|
||||
sigaddset(&newvec.sa_mask, SIGILL);
|
||||
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);
|
||||
sigaction(SIGSEGV, &newvec, NULL);
|
||||
sigaction(SIGBUS, &newvec, NULL);
|
||||
sigaction(SIGABRT, &newvec, NULL);
|
||||
sigaction(SIGFPE, &newvec, NULL);
|
||||
sigaction(SIGILL, &newvec, NULL);
|
||||
if (sigaction(SIGSEGV, &newvec, NULL) < 0) goto werror;
|
||||
if (sigaction(SIGBUS, &newvec, NULL) < 0) goto werror;
|
||||
if (sigaction(SIGABRT, &newvec, NULL) < 0) goto werror;
|
||||
if (sigaction(SIGFPE, &newvec, NULL) < 0) goto werror;
|
||||
if (sigaction(SIGILL, &newvec, NULL) < 0) goto werror;
|
||||
|
||||
return;
|
||||
werror:
|
||||
printf("WAD: Couldn't install signal handler!\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ typedef struct Stab {
|
|||
unsigned n_strx; /* index into file string table */
|
||||
unsigned char n_type; /* type flag (N_TEXT,..) */
|
||||
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) */
|
||||
} Stab;
|
||||
|
||||
|
|
@ -62,6 +62,7 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
|
||||
s = (Stab *) sp; /* Stabs data */
|
||||
ns = size/sizeof(Stab); /* number of stabs */
|
||||
|
||||
slen = strlen(wsym->name);
|
||||
|
||||
/* 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;
|
||||
for (i = 0; i < ns; i++, s++) {
|
||||
/*#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,
|
||||
stabstr+s->n_strx);
|
||||
|
||||
if (s->n_type == 0) {
|
||||
stabstr+s->n_strx);
|
||||
|
||||
}
|
||||
if ((s->n_type == 0)) { /* && (s->n_desc >= 0)) { */
|
||||
/* New stabs section. We need to be a little careful here. Do a recursive
|
||||
search of the subsection. */
|
||||
|
||||
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*/
|
||||
#endif
|
||||
i += s->n_desc;
|
||||
s += s->n_desc;
|
||||
debug->objfile[0] = 0;
|
||||
debug->srcfile[0] = 0;
|
||||
debug->line_number = -1;
|
||||
debug->found = 0;
|
||||
continue;
|
||||
} else if (s->n_type == 0x64) {
|
||||
if (debug->found) return 1; /* New file and we already found what we wanted */
|
||||
/* Source file specification */
|
||||
/* Look for directory */
|
||||
file = stabstr+s->n_strx;
|
||||
if (file[strlen(file)] == '/') {
|
||||
if (strlen(file) && (file[strlen(file)-1] == '/')) {
|
||||
strcpy(debug->srcfile,file);
|
||||
} else {
|
||||
strcat(debug->srcfile,file);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,25 @@
|
|||
unwinding */
|
||||
|
||||
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 */
|
||||
*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;
|
||||
|
|
@ -42,6 +58,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
int ffile;
|
||||
unsigned long p_pc;
|
||||
unsigned long p_sp;
|
||||
unsigned long p_fp;
|
||||
unsigned long p_lastsp;
|
||||
|
||||
int n = 0;
|
||||
|
|
@ -64,10 +81,12 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
nlevels = 0;
|
||||
p_pc = pc;
|
||||
p_sp = sp;
|
||||
p_fp = fp;
|
||||
|
||||
while (p_sp) {
|
||||
/* Add check for stack validity here */
|
||||
ws = wad_segment_find(segments, (void *) p_sp);
|
||||
|
||||
if (!ws) {
|
||||
/* If the stack is bad, we are really hosed here */
|
||||
break;
|
||||
|
|
@ -101,6 +120,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
symname = 0;
|
||||
}
|
||||
|
||||
|
||||
/* if (symname) symname = wad_cplus_demangle(&wsym); */
|
||||
|
||||
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 */
|
||||
if (!firstframe) {
|
||||
int i;
|
||||
|
|
@ -151,18 +173,22 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
frame.regs[i] = lsp[i];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
firstframe = 0;
|
||||
/* Determine stack frame size */
|
||||
p_lastsp = p_sp;
|
||||
stack_unwind(&p_sp, &p_pc);
|
||||
stack_unwind(&p_sp, &p_pc, &p_fp);
|
||||
|
||||
if (p_sp) {
|
||||
stacksize = p_sp - p_lastsp;
|
||||
} else {
|
||||
#ifdef WAD_SOLARIS
|
||||
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 */
|
||||
frame.fp = p_sp;
|
||||
frame.stack_size = stacksize;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,14 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
|||
if (f->line_number > 0) {
|
||||
sprintf(temp,", line %d", f->line_number);
|
||||
strcat(message,temp);
|
||||
fline = f;
|
||||
{
|
||||
int fd;
|
||||
fd = open(SRCFILE(f), O_RDONLY);
|
||||
if (fd > 0) {
|
||||
fline = f;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen(fd+f->obj_off)) {
|
||||
|
|
@ -251,3 +258,5 @@ extern "C"
|
|||
void initlibwadpy() {
|
||||
Py_InitModule((char *)"libwadpy",wadmethods);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue