Linux stuff
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@951 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6f4e3da2c6
commit
012ba99b0c
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_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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue