*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@983 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
78736752d8
commit
ed2d06d48c
8 changed files with 256 additions and 47 deletions
|
|
@ -10,7 +10,7 @@
|
|||
WADSRCS = return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
|
||||
WADOBJS = 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
|
||||
|
||||
# Rules for creation of a .o file from .cxx
|
||||
.SUFFIXES: .cxx
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@
|
|||
#ifndef EIP
|
||||
#define EIP 14
|
||||
#endif
|
||||
#ifndef ESI
|
||||
#define ESI 5
|
||||
#endif
|
||||
#ifndef EDI
|
||||
#define EDI 4
|
||||
#endif
|
||||
#ifndef EBX
|
||||
#define EBX 8
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Signal handling stack */
|
||||
|
|
@ -103,6 +113,13 @@ static void nonlocalret() {
|
|||
#endif
|
||||
|
||||
#ifdef WAD_LINUX
|
||||
|
||||
/* Saved values of the machine registers */
|
||||
|
||||
long wad_saved_esi = 0;
|
||||
long wad_saved_edi = 0;
|
||||
long wad_saved_ebx = 0;
|
||||
|
||||
static void nonlocalret() {
|
||||
asm("_returnsignal:");
|
||||
while (*nlr_p > 0) {
|
||||
|
|
@ -113,10 +130,107 @@ static void nonlocalret() {
|
|||
if (wad_nlr_func)
|
||||
(*wad_nlr_func)();
|
||||
|
||||
/* Restore the registers */
|
||||
asm("movl wad_saved_esi, %esi");
|
||||
asm("movl wad_saved_edi, %edi");
|
||||
asm("movl wad_saved_ebx, %ebx");
|
||||
asm("movl wad_nlr_value, %eax");
|
||||
asm("leave");
|
||||
asm("ret");
|
||||
}
|
||||
|
||||
/* This function uses a heuristic to restore the callee-save registers on i386.
|
||||
According to the Linux Assembly HOWTO, the %esi, %edi, %ebx, and %ebp registers
|
||||
are callee-saved. All others are caller saved. To restore the callee-save
|
||||
registers, we use the fact that the C compiler saves the callee-save registers
|
||||
(if any) at the beginning of function execution. Therefore, we can scan the
|
||||
instructions at the start of each function in the stack trace to try and find
|
||||
where they are.
|
||||
|
||||
The following heuristic is used:
|
||||
|
||||
1. Each function starts with a preamble like this which saves the %ebp
|
||||
register:
|
||||
|
||||
55 89 e5 ---> push %ebp
|
||||
mov %esp, %ebp
|
||||
|
||||
2. Next, space is allocated for local variables, using one of two schemes:
|
||||
|
||||
83 ec xx ---> Less than 256 bytes of local storage
|
||||
^^^
|
||||
length
|
||||
|
||||
81 ec xx xx xx xx --> More than 256 bytes of local storage
|
||||
^^^^^^^^^^^
|
||||
length
|
||||
|
||||
3. After this, a collection of 1-byte stack push op codes might appear
|
||||
|
||||
56 = pushl %esi
|
||||
57 = pushl %edi
|
||||
53 = pushl %ebx
|
||||
|
||||
|
||||
Based on the size of local variable storage and the order in which
|
||||
the %esi, %edi, and %ebx registers are pushed on the stack, we can
|
||||
determine where in memory the registers are saved and restore them to
|
||||
their proper values.
|
||||
*/
|
||||
|
||||
void wad_restore_i386_registers(WadFrame *f, int nlevels) {
|
||||
WadFrame *lastf = f;
|
||||
char *fd = (char *) f;
|
||||
int localsize = 0;
|
||||
unsigned char *pc;
|
||||
unsigned long *saved;
|
||||
int i, j;
|
||||
int pci;
|
||||
for (i = 0; i <= nlevels; i++) {
|
||||
|
||||
/* This gets the starting instruction for the stack frame */
|
||||
pc = (unsigned char *) f->sym_base;
|
||||
/* printf("pc = %x, base = %x, %s\n", f->pc, f->sym_base, SYMBOL(f)); */
|
||||
|
||||
/* Look for the standard prologue 0x55 0x89 0xe5 */
|
||||
if ((pc[0] == 0x55) && (pc[1] == 0x89) && (pc[2] == 0xe5)) {
|
||||
/* Determine the size */
|
||||
pci = 3;
|
||||
if ((pc[3] == 0x83) && (pc[4] == 0xec)) {
|
||||
/* printf("8-bit size\n");*/
|
||||
localsize = (int) pc[5];
|
||||
pci = 6;
|
||||
}
|
||||
if ((pc[3] == 0x81) && (pc[4] == 0xec)) {
|
||||
/* printf("32-bit size\n"); */
|
||||
localsize = (int) *((long *) (pc+5));
|
||||
pci = 10;
|
||||
}
|
||||
saved = (long *) (f->fp - localsize - sizeof(long));
|
||||
/* printf("saved = %x, fp = %x\n", saved, f->fp);
|
||||
printf("localsize = %d\n", localsize);
|
||||
*/
|
||||
for (j = 0; j < 3; j++, saved--, pci++) {
|
||||
if (pc[pci] == 0x57) {
|
||||
wad_saved_edi = *saved;
|
||||
/* printf("restored edi = %x\n", wad_saved_edi); */
|
||||
}
|
||||
else if (pc[pci] == 0x56) {
|
||||
wad_saved_esi = *saved;
|
||||
/* printf("restored esi = %x\n", wad_saved_esi); */
|
||||
}
|
||||
else if (pc[pci] == 0x53) {
|
||||
wad_saved_ebx = *saved;
|
||||
/* printf("restored ebx = %x\n", wad_saved_ebx); */
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
fd += f->size;
|
||||
f = (WadFrame *) fd;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||
|
|
@ -124,6 +238,11 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
greg_t *npc;
|
||||
greg_t *sp;
|
||||
greg_t *fp;
|
||||
#ifdef WAD_LINUX
|
||||
greg_t *esi;
|
||||
greg_t *edi;
|
||||
greg_t *ebx;
|
||||
#endif
|
||||
|
||||
unsigned long addr;
|
||||
ucontext_t *context;
|
||||
|
|
@ -163,6 +282,16 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
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 */
|
||||
esi = &((context->uc_mcontext).gregs[ESI]);
|
||||
edi = &((context->uc_mcontext).gregs[EDI]);
|
||||
ebx = &((context->uc_mcontext).gregs[EBX]);
|
||||
|
||||
wad_saved_esi = (unsigned long) (*esi);
|
||||
wad_saved_edi = (unsigned long) (*edi);
|
||||
wad_saved_ebx = (unsigned long) (*ebx);
|
||||
|
||||
/* printf("esi = %x, edi = %x, ebx = %x\n", wad_saved_esi, wad_saved_edi, wad_saved_ebx); */
|
||||
|
||||
/* printf("&sp = %x, &pc = %x\n", sp, pc); */
|
||||
#endif
|
||||
|
||||
|
|
@ -214,7 +343,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
printf(" sp = %x\n", frame->sp);
|
||||
printf(" fp = %x\n", frame->fp);
|
||||
printf(" size = %x\n", frame->stack_size);
|
||||
printf(" pc = %x\n", frame->pc);
|
||||
printf(" pc = %x (base = %x)\n", frame->pc, frame->sym_base);
|
||||
printf(" symbol = '%s'\n", SYMBOL(frame));
|
||||
printf(" srcfile = '%s'\n", SRCFILE(frame));
|
||||
printf(" objfile = '%s'\n", OBJFILE(frame));
|
||||
|
|
@ -253,6 +382,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
|
||||
if (found) {
|
||||
wad_nlr_levels = nlevels - 1;
|
||||
#ifdef WAD_LINUX
|
||||
wad_restore_i386_registers(origframe, wad_nlr_levels);
|
||||
#endif
|
||||
} else {
|
||||
wad_nlr_levels = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
/* if (symname) symname = wad_cplus_demangle(&wsym); */
|
||||
|
||||
value = wsym.value;
|
||||
|
||||
|
||||
/* Build up some information about the exception frame */
|
||||
frame.frameno = n;
|
||||
|
|
@ -145,6 +146,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
frame.sp = p_sp;
|
||||
frame.nargs = -1;
|
||||
frame.arg_off = 0;
|
||||
frame.sym_base = value + (long) ws->base;
|
||||
n++;
|
||||
if (symname) {
|
||||
symsize = strlen(symname)+1;
|
||||
|
|
@ -322,8 +324,14 @@ long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) {
|
|||
if (strcmp(SYMBOL(f),symbol) == 0) {
|
||||
/* Got a match */
|
||||
if (lastf) {
|
||||
#ifdef WAD_SOLARIS
|
||||
regs = STACK(lastf);
|
||||
return regs[8+argno];
|
||||
#endif
|
||||
#ifdef WAD_LINUX
|
||||
regs = STACK(f);
|
||||
return regs[argno+2];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
lastf = f;
|
||||
|
|
@ -334,3 +342,9 @@ long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
|||
break;
|
||||
default:
|
||||
type = (char*)"Unknown.";
|
||||
|
||||
break;
|
||||
}
|
||||
fd = (char *) frame;
|
||||
|
|
@ -73,7 +72,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)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue