*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@1011 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
cd2f18170d
commit
bb2b81dc43
9 changed files with 296 additions and 329 deletions
|
|
@ -33,18 +33,20 @@ extern "C" {
|
|||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
/* Low level memory management */
|
||||
/* --- Low level memory management --- */
|
||||
|
||||
extern int wad_memory_init();
|
||||
extern void *wad_malloc(int nbytes);
|
||||
extern void *wad_pmalloc(int nbytes);
|
||||
extern void wad_release_memory();
|
||||
extern char *wad_strdup(const char *c);
|
||||
extern char *wad_pstrdup(const char *c);
|
||||
|
||||
/* I/O */
|
||||
/* --- I/O, Debugging --- */
|
||||
|
||||
extern void wad_printf(const char *fmt, ...);
|
||||
|
||||
/* Memory segments */
|
||||
/* --- Memory segments --- */
|
||||
typedef struct WadSegment {
|
||||
char *base; /* Base address for symbol lookup */
|
||||
char *vaddr; /* Virtual address start */
|
||||
|
|
@ -58,9 +60,8 @@ typedef struct WadSegment {
|
|||
extern int wad_segment_read();
|
||||
extern WadSegment *wad_segment_find(void *vaddr);
|
||||
|
||||
/* Object file handling */
|
||||
/* --- Object file handling --- */
|
||||
typedef struct WadObjectFile {
|
||||
struct WadFile *file; /* File data (private) */
|
||||
void *ptr; /* Pointer to data */
|
||||
int len; /* Length of data */
|
||||
int type; /* Type of the object file */
|
||||
|
|
@ -71,7 +72,7 @@ typedef struct WadObjectFile {
|
|||
extern void wad_object_reset();
|
||||
extern WadObjectFile *wad_object_load(const char *path);
|
||||
|
||||
/* Symbol table information */
|
||||
/* --- Symbol table information --- */
|
||||
|
||||
typedef struct WadSymbol {
|
||||
char *name; /* Symbol table name */
|
||||
|
|
@ -97,21 +98,23 @@ extern void wad_set_return_func(void (*f)(void));
|
|||
extern int wad_elf_check(WadObjectFile *wo);
|
||||
extern void wad_elf_debug(WadObjectFile *wo);
|
||||
|
||||
typedef struct WadParm {
|
||||
char name[64];
|
||||
int loc; /* Location: register or stack */
|
||||
int type; /* Argument type */
|
||||
int value; /* Argument position from stabs */
|
||||
} WadParm;
|
||||
typedef struct WadLocal {
|
||||
char *name; /* Name of the local */
|
||||
int loc; /* Location: register or stack */
|
||||
int type; /* Argument type */
|
||||
unsigned long position; /* Position on the stack */
|
||||
struct WadLocal *next;
|
||||
} WadLocal;
|
||||
|
||||
/* Debugging information */
|
||||
typedef struct WadDebug {
|
||||
int found; /* Whether or not debugging information was found */
|
||||
char srcfile[1024]; /* Source file */
|
||||
char objfile[1024]; /* Object file */
|
||||
int line_number; /* Line number */
|
||||
int nargs; /* Number of function arguments */
|
||||
WadParm parms[100]; /* Parameters */
|
||||
int found; /* Whether or not debugging information was found */
|
||||
char srcfile[1024]; /* Source file */
|
||||
char objfile[1024]; /* Object file */
|
||||
int line_number; /* Line number */
|
||||
int nargs; /* Number of function arguments */
|
||||
WadLocal *args; /* Arguments */
|
||||
WadLocal *lastarg;
|
||||
} WadDebug;
|
||||
|
||||
#define PARM_REGISTER 1
|
||||
|
|
@ -120,39 +123,29 @@ typedef struct WadDebug {
|
|||
extern int wad_search_stab(void *stab, int size, char *stabstr, WadSymbol *symbol, unsigned long offset, WadDebug *wd);
|
||||
extern int wad_debug_info(WadObjectFile *wo, WadSymbol *wsym, unsigned long offset, WadDebug *wd);
|
||||
|
||||
/* Data structure containing information about each stack frame */
|
||||
|
||||
/* This data structure is used to report exception data back to handler functions
|
||||
The offset fields contain offsets from the start of the frame to a location in
|
||||
the data segment */
|
||||
|
||||
typedef struct WadFrame {
|
||||
long size; /* Frame size */
|
||||
long lastsize; /* Size of previous frame */
|
||||
long last; /* Last frame ? */
|
||||
long frameno; /* Frame number */
|
||||
long pc; /* Program counter */
|
||||
long sp; /* Stack pointer */
|
||||
long fp; /* Frame pointer */
|
||||
long nargs; /* Number of arguments */
|
||||
long arg_off; /* Argument offset */
|
||||
long line_number; /* Source line number */
|
||||
long sym_base; /* Symbol base address */
|
||||
long sym_off; /* Symbol name offset */
|
||||
long src_off; /* Source filename offset */
|
||||
long obj_off; /* Object filename offset */
|
||||
long stack_off; /* Stack offset */
|
||||
long stack_size; /* Size of the stack segment */
|
||||
long regs[16]; /* Integer registers (%on, %ln) */
|
||||
double fregs[16]; /* Floating point registers */
|
||||
char data[8]; /* Frame data */
|
||||
long frameno; /* Frame number */
|
||||
long pc; /* Real PC */
|
||||
long sp; /* Real SP */
|
||||
long fp; /* Real FP */
|
||||
char *psp; /* Pointer to where the actual stack data is stored */
|
||||
int stack_size; /* Stack frame size */
|
||||
char *symbol; /* Symbol name */
|
||||
long sym_base; /* Symbol base address */
|
||||
char *objfile; /* Object file */
|
||||
char *srcfile; /* Source file */
|
||||
int line_number; /* Source line */
|
||||
int nargs; /* Number of arguments */
|
||||
WadLocal *args; /* Function arguments */
|
||||
WadLocal *lastarg; /* Last argument */
|
||||
int nlocals; /* Number of locals */
|
||||
int last; /* Last frame flag */
|
||||
struct WadFrame *next; /* Next frame up the stack */
|
||||
struct WadFrame *prev; /* Previous frame down the stack */
|
||||
} WadFrame;
|
||||
|
||||
#define SRCFILE(x) ((char *) x) + x->src_off
|
||||
#define SYMBOL(x) ((char *) x) + x->sym_off
|
||||
#define OBJFILE(x) ((char *) x) + x->obj_off
|
||||
#define STACK(x) (long *) (((char *) x) + x->stack_off)
|
||||
#define ARGUMENTS(x) (WadParm *) (((char *) x) + x->arg_off)
|
||||
|
||||
extern WadFrame *wad_stack_trace(unsigned long, unsigned long, unsigned long);
|
||||
extern char *wad_strip_dir(char *);
|
||||
extern void wad_default_callback(int signo, WadFrame *frame, char *ret);
|
||||
|
|
@ -175,20 +168,20 @@ extern WadReturnFunc *wad_check_return(const char *name);
|
|||
|
||||
/* --- Debugging Interface --- */
|
||||
|
||||
#define DEBUG_SEGMENT 0x1
|
||||
#define DEBUG_SYMBOL 0x2
|
||||
#define DEBUG_STABS 0x4
|
||||
#define DEBUG_OBJECT 0x8
|
||||
#define DEBUG_FILE 0x10
|
||||
#define DEBUG_HOLD 0x20
|
||||
#define DEBUG_RETURN 0x40
|
||||
#define DEBUG_SEGMENT 0x1
|
||||
#define DEBUG_SYMBOL 0x2
|
||||
#define DEBUG_STABS 0x4
|
||||
#define DEBUG_OBJECT 0x8
|
||||
#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
|
||||
#define DEBUG_STACK 0x800
|
||||
#define DEBUG_UNWIND 0x1000
|
||||
#define DEBUG_SIGNAL 0x2000
|
||||
#define DEBUG_INIT 0x100
|
||||
#define DEBUG_NOSTACK 0x200
|
||||
#define DEBUG_ONESHOT 0x400
|
||||
#define DEBUG_STACK 0x800
|
||||
#define DEBUG_UNWIND 0x1000
|
||||
#define DEBUG_SIGNAL 0x2000
|
||||
|
||||
extern int wad_debug_mode;
|
||||
extern int wad_heap_overflow;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
WADSRCS = io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
|
||||
WADOBJS = 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
|
||||
|
||||
# Rules for creation of a .o file from .cxx
|
||||
.SUFFIXES: .cxx
|
||||
|
|
@ -76,7 +76,7 @@ wc::
|
|||
wc $(SRCS)
|
||||
|
||||
semi::
|
||||
egrep ";" $(WADSRCS) | wc
|
||||
egrep ";" $(SRCS) wadpy.cxx | wc
|
||||
|
||||
|
||||
clean::
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ int main(int argc, char **argv) {
|
|||
} else if (strcmp(argv[1],"ret") == 0) {
|
||||
call_func(4,seg_crash);
|
||||
} else if (strcmp(argv[1],"test") == 0) {
|
||||
test(-4,seg_crash);
|
||||
test(-1000,seg_crash);
|
||||
} else if (strcmp(argv[1],"double") == 0) {
|
||||
double_crash(3.14159,2.1828);
|
||||
} else if (strcmp(argv[1],"math") == 0) {
|
||||
|
|
|
|||
|
|
@ -21,25 +21,20 @@
|
|||
char *wad_arg_string(WadFrame *frame) {
|
||||
static char str[1024];
|
||||
static char temp[64];
|
||||
WadParm *wp;
|
||||
WadLocal *wp;
|
||||
long *stack;
|
||||
long *nextstack;
|
||||
int i;
|
||||
WadFrame *nf;
|
||||
|
||||
if (frame->size) {
|
||||
nf = (WadFrame *) (((char *) frame) + frame->size);
|
||||
if (nf->size == 0) nf = 0;
|
||||
} else {
|
||||
nf = 0;
|
||||
}
|
||||
nf = frame->next;
|
||||
if (nf)
|
||||
nextstack = STACK(nf);
|
||||
nextstack = (long *) nf->psp;
|
||||
else
|
||||
nextstack = 0;
|
||||
|
||||
str[0] = 0;
|
||||
stack = STACK(frame);
|
||||
stack = (long *) frame->psp;
|
||||
|
||||
#ifdef WAD_LINUX
|
||||
if (!nf) {
|
||||
|
|
@ -62,15 +57,15 @@ char *wad_arg_string(WadFrame *frame) {
|
|||
#endif
|
||||
} else {
|
||||
/* We were able to get some argument information out the debugging table */
|
||||
wp = ARGUMENTS(frame);
|
||||
for (i = 0; i < frame->nargs; i++, wp++) {
|
||||
wp = frame->args;
|
||||
for (i = 0; i < frame->nargs; i++, wp = wp->next) {
|
||||
strcat(str,wp->name);
|
||||
strcat(str,"=");
|
||||
|
||||
/* Try to figure out where the value is */
|
||||
if ((wp->loc == PARM_STACK) && nf) {
|
||||
/* Parameter is located on the call stack */
|
||||
unsigned long argloc = wp->value; /* Location relative to frame pointer */
|
||||
unsigned long argloc = wp->position; /* Location relative to frame pointer */
|
||||
if ((argloc & 0x3) == 0) {
|
||||
if (argloc >= 0) {
|
||||
/* Is word aligned, make some kind of attempt to print this out */
|
||||
|
|
@ -85,18 +80,19 @@ char *wad_arg_string(WadFrame *frame) {
|
|||
}
|
||||
} else if (wp->loc == PARM_REGISTER) {
|
||||
#ifdef WAD_SOLARIS
|
||||
if ((wp->value >= 24) && (wp->value < 32)) {
|
||||
if ((wp->position >= 24) && (wp->position < 32)) {
|
||||
/* Value is located in the %in registers */
|
||||
sprintf(temp,"0x%x", stack[wp->value - 16]);
|
||||
sprintf(temp,"0x%x", stack[wp->position - 16]);
|
||||
strcat(str,temp);
|
||||
} else if ((wp->value >= 8) && (wp->value < 16)) {
|
||||
} else if ((wp->position >= 8) && (wp->position < 16)) {
|
||||
/* Value is located in the %on registers */
|
||||
sprintf(temp,"0x%x", frame->regs[wp->value]);
|
||||
strcat(str,temp);
|
||||
} else if ((wp->value >= 16) && (wp->value < 24)) {
|
||||
/* sprintf(temp,"0x%x", frame->regs[wp->value]);
|
||||
strcat(str,temp); */
|
||||
} else if ((wp->position >= 16) && (wp->position < 24)) {
|
||||
/* Value has been placed in the %ln registers */
|
||||
/*
|
||||
sprintf(temp,"0x%x", frame->regs[wp->value - 16]);
|
||||
strcat(str,temp);
|
||||
strcat(str,temp); */
|
||||
}
|
||||
#endif
|
||||
#ifdef WAD_LINUX
|
||||
|
|
@ -202,24 +198,24 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
|
||||
/* Find the last exception frame */
|
||||
|
||||
while (!f->last) {
|
||||
fd = fd + f->size;
|
||||
f = (WadFrame *) fd;
|
||||
while (f && !f->last) {
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
/* Now work backwards */
|
||||
fd = fd - f->lastsize;
|
||||
f = (WadFrame *) fd;
|
||||
while (1) {
|
||||
fprintf(stderr,"#%-3d 0x%08x in %s(%s)", f->frameno, f->pc, *(fd + f->sym_off) ? fd+f->sym_off : "?",
|
||||
if (f) {
|
||||
f = f->prev;
|
||||
}
|
||||
while (f) {
|
||||
fprintf(stderr,"#%-3d 0x%08x in %s(%s)", f->frameno, f->pc, f->symbol ? f->symbol : "?",
|
||||
wad_arg_string(f));
|
||||
if (strlen(fd+f->src_off)) {
|
||||
fprintf(stderr," in '%s'", wad_strip_dir(fd+f->src_off));
|
||||
if (f->srcfile && strlen(f->srcfile)) {
|
||||
fprintf(stderr," in '%s'", wad_strip_dir(f->srcfile));
|
||||
if (f->line_number > 0) {
|
||||
fprintf(stderr,", line %d", f->line_number);
|
||||
{
|
||||
int fd;
|
||||
fd = open(SRCFILE(f), O_RDONLY);
|
||||
fd = open(f->srcfile, O_RDONLY);
|
||||
if (fd > 0) {
|
||||
fline = f;
|
||||
}
|
||||
|
|
@ -227,14 +223,12 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen(fd+f->obj_off)) {
|
||||
fprintf(stderr," from '%s'", fd+f->obj_off);
|
||||
if (f->objfile && strlen(f->objfile)) {
|
||||
fprintf(stderr," from '%s'", f->objfile);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
if (!f->lastsize) break;
|
||||
fd = fd - f->lastsize;
|
||||
f = (WadFrame *) fd;
|
||||
f = f->prev;
|
||||
}
|
||||
|
||||
if (fline) {
|
||||
|
|
@ -246,9 +240,9 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
last = fline->line_number + 2;
|
||||
if (first < 1) first = 1;
|
||||
|
||||
line = wad_load_source(SRCFILE(fline),first);
|
||||
line = wad_load_source(fline->srcfile,first);
|
||||
if (line) {
|
||||
fprintf(stderr,"\n%s, line %d\n\n", SRCFILE(fline),fline->line_number);
|
||||
fprintf(stderr,"\n%s, line %d\n\n", fline->srcfile,fline->line_number);
|
||||
for (i = first; i <= last; i++) {
|
||||
if (i == fline->line_number) fprintf(stderr," => ");
|
||||
else fprintf(stderr," ");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ typedef struct _WadMemory {
|
|||
} WadMemory;
|
||||
|
||||
static WadMemory *current = 0; /* Current memory block */
|
||||
static WadMemory *persistent = 0; /* Persistent memory data */
|
||||
static int pagesize = 0; /* System page size */
|
||||
static int devzero = 0;
|
||||
|
||||
|
|
@ -92,6 +93,7 @@ void *wad_malloc(int nbytes) {
|
|||
/* Yep. Found a region */
|
||||
break;
|
||||
}
|
||||
wm = wm->next;
|
||||
}
|
||||
if (!wm) {
|
||||
wad_printf("wad_malloc: new page\n", nbytes);
|
||||
|
|
@ -107,6 +109,24 @@ void *wad_malloc(int nbytes) {
|
|||
return c;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_pmalloc()
|
||||
*
|
||||
* Persistent memory allocation. Allocates memory that will never be reclaimed.
|
||||
* This is only really used to store information pertaining to object files.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void *wad_pmalloc(int nbytes) {
|
||||
void *ptr;
|
||||
WadMemory *tmp;
|
||||
tmp = current;
|
||||
current = persistent;
|
||||
ptr = wad_malloc(nbytes);
|
||||
persistent = current;
|
||||
current = tmp;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_release_memory()
|
||||
*
|
||||
|
|
@ -119,7 +139,7 @@ void wad_release_memory() {
|
|||
wm = current;
|
||||
while (wm) {
|
||||
next = wm->next;
|
||||
munmap(wm, wm->npages*pagesize);
|
||||
munmap((char *) wm, wm->npages*pagesize);
|
||||
wm = next;
|
||||
}
|
||||
current = 0;
|
||||
|
|
@ -139,3 +159,11 @@ char *wad_strdup(const char *c) {
|
|||
return t;
|
||||
}
|
||||
|
||||
char *wad_pstrdup(const char *c) {
|
||||
char *t;
|
||||
if (!c) c = "";
|
||||
t = (char *) wad_pmalloc(strlen(c)+1);
|
||||
strcpy(t,c);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@
|
|||
* This file provides access to raw object files, executables, and
|
||||
* library files. Memory management is handled through mmap() to
|
||||
* avoid the use of heap/stack space.
|
||||
*
|
||||
* All of the files and objects created by this module persist
|
||||
* until the process exits. Since WAD may be invoked multiple times
|
||||
* over the course of program execution, it makes little sense to keep
|
||||
* loading and unloading files---subsequent invocations of the handler
|
||||
* can simply used previously loaded copies. Caveat: things probably
|
||||
* won't work right if a program is doing lots of low-level manipulation
|
||||
* of the dynamic loader.
|
||||
*
|
||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||
*
|
||||
|
|
@ -46,8 +54,8 @@ load_file(const char *path) {
|
|||
return 0; /* Doesn't exist. Oh well */
|
||||
}
|
||||
if (wad_debug_mode & DEBUG_FILE) wad_printf("loaded.\n");
|
||||
wf = (WadFile *) wad_malloc(sizeof(WadFile));
|
||||
wf->path = wad_strdup(path);
|
||||
wf = (WadFile *) wad_pmalloc(sizeof(WadFile));
|
||||
wf->path = wad_pstrdup(path);
|
||||
|
||||
/* Get file length */
|
||||
wf->size = lseek(fd,0,SEEK_END);
|
||||
|
|
@ -65,14 +73,13 @@ load_file(const char *path) {
|
|||
return wf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static WadObjectFile *wad_objects = 0; /* Linked list of object files */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_object_cleanup()
|
||||
*
|
||||
* Reset the object file loader
|
||||
* Reset the object file loader. This unmaps the files themselves, but
|
||||
* memory will leak for object files pointers themselves.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
|
|
@ -98,7 +105,7 @@ wad_object_reset() {
|
|||
* wad_object_load()
|
||||
*
|
||||
* Load an object file into memory using mmap. Returns 0 if the object does
|
||||
* not exist or if there are no more object descriptor slots
|
||||
* not exist or if we're out of memory.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadObjectFile *
|
||||
|
|
@ -135,7 +142,7 @@ wad_object_load(const char *path) {
|
|||
wo = wad_arobject_load(realfile,objfile);
|
||||
if (wo) {
|
||||
/* Reset the path */
|
||||
wo->path = wad_strdup(path);
|
||||
wo->path = wad_pstrdup(path);
|
||||
return wo;
|
||||
}
|
||||
}
|
||||
|
|
@ -143,9 +150,8 @@ wad_object_load(const char *path) {
|
|||
wf = load_file(path);
|
||||
if (!wf) return 0;
|
||||
|
||||
wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile));
|
||||
wo->file = wf;
|
||||
wo->path = wad_strdup(path);
|
||||
wo = (WadObjectFile *) wad_pmalloc(sizeof(WadObjectFile));
|
||||
wo->path = wad_pstrdup(path);
|
||||
wo->ptr = wf->addr;
|
||||
wo->len = wf->size;
|
||||
return wo;
|
||||
|
|
@ -154,7 +160,9 @@ wad_object_load(const char *path) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* wad_arobject_load()
|
||||
*
|
||||
* Load an archive file object into memory using mmap.
|
||||
* Load an object file stored in an archive file created with an archive. The
|
||||
* pathname should be the path of the .a file and robjname should be the name
|
||||
* of the object file stored in the object file.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadObjectFile *
|
||||
|
|
@ -227,8 +235,7 @@ wad_arobject_load(const char *arpath, const char *robjname) {
|
|||
/* Compare the names */
|
||||
if (strncmp(mname,objname,sobjname) == 0) {
|
||||
/* Found the archive */
|
||||
wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile));
|
||||
wo->file = wf;
|
||||
wo = (WadObjectFile *) wad_pmalloc(sizeof(WadObjectFile));
|
||||
wo->ptr = (void *) (arptr + offset);
|
||||
wo->len = msize;
|
||||
wo->path = 0;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "wad.h"
|
||||
|
||||
/* For some odd reason, certain linux distributions do not seem to define the
|
||||
ESP, EIP, and EBP registers. This is a hack */
|
||||
register constants in a way that is easily accessible to us. This is a hack */
|
||||
|
||||
#ifdef WAD_LINUX
|
||||
#ifndef ESP
|
||||
|
|
@ -330,45 +330,42 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
|
||||
if (wad_debug_mode & DEBUG_STACK) {
|
||||
/* Walk the exception frames and try to find a return point */
|
||||
framedata = (char *) frame;
|
||||
|
||||
while (frame->size) {
|
||||
while (frame) {
|
||||
int i;
|
||||
WadParm *p;
|
||||
WadLocal *p;
|
||||
/* Print out detailed stack trace information */
|
||||
printf("::: Stack frame - 0x%08x :::\n", frame);
|
||||
printf(" sp = %x\n", frame->sp);
|
||||
printf(" fp = %x\n", frame->fp);
|
||||
printf(" size = %x\n", frame->stack_size);
|
||||
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));
|
||||
printf(" symbol = '%s'\n", frame->symbol ? frame->symbol : "?");
|
||||
printf(" srcfile = '%s'\n", frame->srcfile ? frame->srcfile : "");
|
||||
printf(" objfile = '%s'\n", frame->objfile ? frame->objfile : "");
|
||||
printf(" numargs = %d\n", frame->nargs);
|
||||
printf(" arguments [\n");
|
||||
p = ARGUMENTS(frame);
|
||||
for (i = 0; i < frame->nargs; i++, p++) {
|
||||
printf(" arg[%d] : name = '%s', loc = %d, type = %d, value = %d\n", i, p->name, p->loc, p->type, p->value);
|
||||
p = frame->args;
|
||||
i = 0;
|
||||
while (p) {
|
||||
printf(" arg[%d] : name = '%s', loc = %d, type = %d, value = %d\n", i, p->name, p->loc, p->type, p->position);
|
||||
p = p->next;
|
||||
i++;
|
||||
}
|
||||
printf(" ]\n");
|
||||
framedata = framedata + frame->size;
|
||||
frame = (WadFrame *) framedata;
|
||||
frame = frame->next;
|
||||
}
|
||||
frame = origframe;
|
||||
}
|
||||
|
||||
/* Walk the exception frames and try to find a return point */
|
||||
framedata = (char *) frame;
|
||||
|
||||
while (frame->size) {
|
||||
WadReturnFunc *wr = wad_check_return(framedata+frame->sym_off);
|
||||
while (frame) {
|
||||
WadReturnFunc *wr = wad_check_return(frame->symbol);
|
||||
if (wr) {
|
||||
found = 1;
|
||||
wad_nlr_value = wr->value;
|
||||
retname = wr->name;
|
||||
}
|
||||
framedata = framedata + frame->size;
|
||||
frame = (WadFrame *) framedata;
|
||||
frame = frame->next;
|
||||
if (found) {
|
||||
frame->last = 1; /* Cut off top of the stack trace */
|
||||
break;
|
||||
|
|
@ -376,7 +373,6 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
nlevels++;
|
||||
}
|
||||
|
||||
|
||||
if (found) {
|
||||
wad_nlr_levels = nlevels - 1;
|
||||
#ifdef WAD_LINUX
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@
|
|||
|
||||
#include "wad.h"
|
||||
|
||||
|
||||
/* stabs data structure. This appears to be somewhat universal. */
|
||||
|
||||
typedef struct Stab {
|
||||
unsigned n_strx; /* index into file string table */
|
||||
unsigned char n_type; /* type flag (N_TEXT,..) */
|
||||
|
|
@ -23,11 +21,26 @@ typedef struct Stab {
|
|||
unsigned n_value; /* value of symbol (or sdb offset) */
|
||||
} Stab;
|
||||
|
||||
/* Match a stabs symbol name against a stab string (which may contain
|
||||
extra information delimetered by a colon */
|
||||
/* stabs data types used by this module */
|
||||
|
||||
int match_stab_symbol(char *symbol, char *stabtext, int slen) {
|
||||
/* wad_printf("matching: %s -> %s\n", symbol, stabtext); */
|
||||
#define N_UNDF 0x0 /* undefined */
|
||||
#define N_FUN 0x24 /* function */
|
||||
#define N_OBJ 0x38 /* object file path */
|
||||
#define N_RSYM 0x40 /* Register symbol */
|
||||
#define N_SLINE 0x44 /* Source line */
|
||||
#define N_SO 0x64 /* Source file name */
|
||||
#define N_PSYM 0xa0 /* Parameter */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* match_stab_symbol()
|
||||
*
|
||||
* Match a stabs symbol name against a stab string. The stab string may contain
|
||||
* extra information delimited by a colon which is not used in the comparsion.
|
||||
* Returns 1 on match, 0 on mismatch.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
match_stab_symbol(char *symbol, char *stabtext, int slen) {
|
||||
if (strcmp(symbol,stabtext) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -35,6 +48,17 @@ int match_stab_symbol(char *symbol, char *stabtext, int slen) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* scan_function()
|
||||
*
|
||||
* Collect stabs data for a function definition.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
scan_function(Stab *s, int ns, WadDebug *debug) {
|
||||
|
||||
}
|
||||
|
||||
/* Given a stabs data segment (obtained somehow), this function tries to
|
||||
collect as much information as it can about a given symbol.
|
||||
|
||||
|
|
@ -47,7 +71,6 @@ int match_stab_symbol(char *symbol, char *stabtext, int slen) {
|
|||
|
||||
Note: If a symbol corresponds to a local symbol, it's entirely possible
|
||||
that the only stabs data we will find is a file specifier. In this case,
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
|
|
@ -59,6 +82,7 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
int i;
|
||||
char *file, *lastfile = 0;
|
||||
int chk = 0;
|
||||
WadLocal *arg;
|
||||
|
||||
s = (Stab *) sp; /* Stabs data */
|
||||
ns = size/sizeof(Stab); /* number of stabs */
|
||||
|
|
@ -71,16 +95,16 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
debug->objfile[0] = 0;
|
||||
debug->line_number = -1;
|
||||
debug->nargs = 0;
|
||||
debug->args = 0;
|
||||
debug->lastarg = 0;
|
||||
|
||||
for (i = 0; i < ns; i++, s++) {
|
||||
/*#define DEBUG_DEBUG */
|
||||
if (wad_debug_mode & DEBUG_STABS) {
|
||||
/* wad_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); */
|
||||
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 == 0)) { /* && (s->n_desc >= 0)) { */
|
||||
if ((s->n_type == N_UNDF)) { /* && (s->n_desc >= 0)) { */
|
||||
/* New stabs section. We need to be a little careful here. Do a recursive
|
||||
search of the subsection. */
|
||||
|
||||
|
|
@ -100,7 +124,7 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
debug->line_number = -1;
|
||||
debug->found = 0;
|
||||
continue;
|
||||
} else if (s->n_type == 0x64) {
|
||||
} else if (s->n_type == N_SO) {
|
||||
if (debug->found) return 1; /* New file and we already found what we wanted */
|
||||
/* Source file specification */
|
||||
/* Look for directory */
|
||||
|
|
@ -116,13 +140,13 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
debug->found = 1;
|
||||
}
|
||||
lastfile = file;
|
||||
} else if (s->n_type == 0x38) {
|
||||
} else if (s->n_type == N_OBJ) {
|
||||
/* Object file specifier */
|
||||
if (debug->objfile[0]) {
|
||||
strcat(debug->objfile,"/");
|
||||
}
|
||||
strcat(debug->objfile,stabstr+s->n_strx);
|
||||
} else if (s->n_type == 0x24) {
|
||||
} else if (s->n_type == N_FUN) {
|
||||
if (match_stab_symbol(wsym->name, stabstr+s->n_strx, slen)) {
|
||||
if (!wsym->file || (strcmp(wsym->file,lastfile) == 0)) {
|
||||
infunc = 1;
|
||||
|
|
@ -134,13 +158,12 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
} else {
|
||||
infunc = 0;
|
||||
}
|
||||
} else if (debug->found && (s->n_type == 0x44) && (infunc)) {
|
||||
|
||||
} else if (debug->found && (s->n_type == N_SLINE) && (infunc)) {
|
||||
/* Line number location */
|
||||
if (s->n_value < offset) {
|
||||
debug->line_number = s->n_desc;
|
||||
} else return 1;
|
||||
} else if (debug->found && ((s->n_type == 0xa0) || (s->n_type == 0x40)) && (infunc)) {
|
||||
} else if (debug->found && ((s->n_type == N_PSYM) || (s->n_type == N_RSYM)) && (infunc)) {
|
||||
/* Parameter counting */
|
||||
char *pname;
|
||||
char *c;
|
||||
|
|
@ -153,41 +176,52 @@ wad_search_stab(void *sp, int size, char *stabstr, WadSymbol *wsym, unsigned lon
|
|||
len = strlen(pname);
|
||||
}
|
||||
|
||||
/* Check if already used */
|
||||
/* Check if the argument was already used */
|
||||
/* In this case, the first stab simply identifies an argument. The second
|
||||
one identifies its location for the debugger */
|
||||
|
||||
if (debug->nargs > 0) {
|
||||
if (debug->args) {
|
||||
/* Need to do some fix up for linux here */
|
||||
int i;
|
||||
for (i = 0; i < debug->nargs; i++) {
|
||||
if ((strncmp(debug->parms[i].name, pname,len) == 0) && (strlen(debug->parms[i].name) == len)) {
|
||||
WadLocal *a = debug->args;
|
||||
while (a) {
|
||||
if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) {
|
||||
/* We already saw this argument. Given a choice between a register and a stack
|
||||
argument. We will choose the stack version */
|
||||
if (debug->parms[i].loc == PARM_STACK) {
|
||||
if (a->loc == PARM_STACK) {
|
||||
break;
|
||||
}
|
||||
/* Go ahead and use the new argument */
|
||||
if (s->n_type == 0x40)
|
||||
debug->parms[i].loc = PARM_REGISTER;
|
||||
a->loc = PARM_REGISTER;
|
||||
else
|
||||
debug->parms[i].loc = PARM_STACK;
|
||||
debug->parms[i].value = s->n_value;
|
||||
a->loc = PARM_STACK;
|
||||
a->position = s->n_value;
|
||||
break;
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
if (i < debug->nargs) continue; /* We got an argument match. Just skip to next stab */
|
||||
if (a) continue; /* We got an argument match. Just skip to the next stab */
|
||||
}
|
||||
|
||||
strncpy(debug->parms[debug->nargs].name,pname,len);
|
||||
debug->parms[debug->nargs].name[len] = 0;
|
||||
arg = (WadLocal *) wad_malloc(sizeof(WadLocal));
|
||||
arg->name = (char *) wad_malloc(len+1);
|
||||
strncpy(arg->name, pname, len);
|
||||
arg->name[len] = 0;
|
||||
if (s->n_type == 0x40)
|
||||
debug->parms[debug->nargs].loc = PARM_REGISTER;
|
||||
arg->loc = PARM_REGISTER;
|
||||
else
|
||||
debug->parms[debug->nargs].loc = PARM_STACK;
|
||||
arg->loc = PARM_STACK;
|
||||
|
||||
debug->parms[debug->nargs].value = s->n_value;
|
||||
debug->parms[debug->nargs].type = 0; /* Not used yet */
|
||||
arg->position = s->n_value;
|
||||
arg->type = 0;
|
||||
arg->next = 0;
|
||||
if (debug->args) {
|
||||
debug->lastarg->next = arg;
|
||||
debug->lastarg = arg;
|
||||
} else {
|
||||
debug->args = arg;
|
||||
debug->lastarg = arg;
|
||||
}
|
||||
debug->nargs++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@
|
|||
#include <sys/mman.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* This needs to be changed so that the value is dynamically determined
|
||||
Might also get weird problems with stacks located in different regions. */
|
||||
|
||||
#ifdef WAD_SOLARIS
|
||||
#define STACK_BASE 0xffbf0000
|
||||
#endif
|
||||
|
|
@ -21,8 +24,12 @@
|
|||
#define STACK_BASE 0xc0000000
|
||||
#endif
|
||||
|
||||
/* Given a stack pointer, this function performs a single level of stack
|
||||
unwinding */
|
||||
/* -----------------------------------------------------------------------------
|
||||
* stack_unwind()
|
||||
*
|
||||
* Perform a single level of stack unwinding given the stack pointer, frame pointer
|
||||
* and program counter.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
stack_unwind(unsigned long *sp, unsigned long *pc, unsigned long *fp) {
|
||||
|
|
@ -49,51 +56,34 @@ stack_unwind(unsigned long *sp, unsigned long *pc, unsigned long *fp) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void *trace_addr = 0;
|
||||
static int trace_len = 0;
|
||||
|
||||
/* Perform a stack unwinding given the current value of the pc, stack pointer,
|
||||
and frame pointer. Returns a pointer to a wad exception frame structure
|
||||
which is actually a large memory mapped file. */
|
||||
|
||||
static char framefile[256];
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_stack_trace()
|
||||
*
|
||||
* Create a stack trace of the process. Returns a linked list of stack frames
|
||||
* with debugging information and other details.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadFrame *
|
||||
wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
||||
WadSegment *ws, *segments;
|
||||
WadObjectFile *wo;
|
||||
WadFrame frame;
|
||||
WadSegment *ws;
|
||||
WadObjectFile *wo;
|
||||
WadFrame *firstframe=0, *lastframe=0, *frame=0;
|
||||
WadDebug wd;
|
||||
WadSymbol wsym;
|
||||
int nlevels;
|
||||
|
||||
int ffile;
|
||||
unsigned long p_pc;
|
||||
unsigned long p_sp;
|
||||
unsigned long p_fp;
|
||||
unsigned long p_lastsp;
|
||||
|
||||
int n = 0;
|
||||
int lastsize = 0;
|
||||
int firstframe = 1;
|
||||
|
||||
/* Read the segments */
|
||||
|
||||
if (wad_segment_read() < 0) {
|
||||
wad_printf("WAD: Unable to read segment map\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open the frame file for output */
|
||||
tmpnam(framefile);
|
||||
ffile = open(framefile, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||
if (ffile < 0) {
|
||||
wad_printf("can't open %s\n", framefile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to do a stack traceback */
|
||||
nlevels = 0;
|
||||
|
||||
p_pc = pc;
|
||||
p_sp = sp;
|
||||
p_fp = fp;
|
||||
|
|
@ -110,21 +100,13 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
}
|
||||
ws = wad_segment_find((void *) p_pc);
|
||||
{
|
||||
int symsize = 0;
|
||||
int srcsize = 0;
|
||||
int objsize = 0;
|
||||
int stacksize = 0;
|
||||
int argsize = 0;
|
||||
char *srcname = 0;
|
||||
char *objname = 0;
|
||||
char *symname = 0;
|
||||
int pad = 0;
|
||||
int stacksize = 0;
|
||||
char *symname = 0;
|
||||
unsigned long value;
|
||||
|
||||
/* Try to load the object file for this address */
|
||||
if (ws) {
|
||||
wo = wad_object_load(ws->mappath);
|
||||
/* Special hack needed for base address */
|
||||
}
|
||||
else {
|
||||
wo = 0;
|
||||
|
|
@ -136,53 +118,51 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
} else {
|
||||
symname = 0;
|
||||
}
|
||||
|
||||
|
||||
/* if (symname) symname = wad_cplus_demangle(&wsym); */
|
||||
|
||||
value = wsym.value;
|
||||
|
||||
|
||||
/* Build up some information about the exception frame */
|
||||
frame.frameno = n;
|
||||
frame.last = 0;
|
||||
frame.lastsize = lastsize;
|
||||
frame.pc = p_pc;
|
||||
frame.sp = p_sp;
|
||||
frame.nargs = -1;
|
||||
frame.arg_off = 0;
|
||||
frame.sym_base = value + (long) ws->base;
|
||||
frame = (WadFrame *) wad_malloc(sizeof(WadFrame));
|
||||
frame->frameno = n;
|
||||
frame->pc = p_pc;
|
||||
frame->sp = p_sp;
|
||||
frame->nlocals = -1;
|
||||
frame->nargs = -1;
|
||||
frame->objfile = 0;
|
||||
frame->srcfile = 0;
|
||||
frame->psp = 0;
|
||||
frame->next = 0;
|
||||
frame->prev = lastframe;
|
||||
frame->last = 0;
|
||||
if (lastframe) {
|
||||
lastframe->next = frame;
|
||||
lastframe = frame;
|
||||
} else {
|
||||
lastframe = frame;
|
||||
firstframe = frame;
|
||||
}
|
||||
frame->symbol = wad_strdup(symname);
|
||||
frame->sym_base = value + (long) ws->base;
|
||||
n++;
|
||||
if (symname) {
|
||||
symsize = strlen(symname)+1;
|
||||
|
||||
/* wad_printf("C++: '%s' ---> '%s'\n", symname, wad_cplus_demangle(&wsym));*/
|
||||
|
||||
/* Try to gather some debugging information about this symbol */
|
||||
if (wad_debug_info(wo,&wsym, p_pc - (unsigned long) ws->base - value, &wd)) {
|
||||
srcname = wd.srcfile;
|
||||
srcsize = strlen(srcname)+1;
|
||||
objname = wd.objfile;
|
||||
objsize = strlen(objname)+1;
|
||||
frame.nargs = wd.nargs;
|
||||
frame->srcfile = wad_strdup(wd.srcfile);
|
||||
frame->objfile = wad_strdup(wd.objfile);
|
||||
frame->args = wd.args;
|
||||
frame->lastarg = wd.lastarg;
|
||||
frame->nargs = wd.nargs;
|
||||
|
||||
/*frame.nargs = wd.nargs;
|
||||
if (wd.nargs > 0) {
|
||||
argsize = sizeof(WadParm)*wd.nargs;
|
||||
}
|
||||
/*
|
||||
if (wd.nargs >=0) {
|
||||
int i;
|
||||
wad_printf("%s\n",symname);
|
||||
for (i = 0; i < wd.nargs; i++) {
|
||||
wad_printf(" [%d] = '%s', %d, %d\n", i, wd.parms[i].name, wd.parms[i].type, wd.parms[i].value);
|
||||
}
|
||||
}
|
||||
*/
|
||||
frame.line_number = wd.line_number;
|
||||
frame->line_number = wd.line_number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WAD_SOLARIS
|
||||
|
||||
#ifdef OLD /* Might not be necessary. Registers stored on stack already */
|
||||
/* Before unwinding the stack, copy the locals and %o registers from previous frame */
|
||||
if (!firstframe) {
|
||||
int i;
|
||||
|
|
@ -193,16 +173,16 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
firstframe = 0;
|
||||
|
||||
#endif
|
||||
/* Determine stack frame size */
|
||||
p_lastsp = p_sp;
|
||||
|
||||
stack_unwind(&p_sp, &p_pc, &p_fp);
|
||||
|
||||
if (p_sp) {
|
||||
stacksize = p_sp - p_lastsp;
|
||||
} else {
|
||||
stacksize = STACK_BASE - p_lastsp; /* Sick hack alert. Need to get stack top from somewhere */
|
||||
stacksize = STACK_BASE - p_lastsp;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
|
|
@ -211,101 +191,40 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
}
|
||||
|
||||
/* Set the frame pointer and stack size */
|
||||
|
||||
/* frame.fp = p_sp; */
|
||||
frame.fp = p_sp;
|
||||
frame.stack_size = stacksize;
|
||||
|
||||
/* Build the exception frame object we'll write */
|
||||
frame.size = sizeof(WadFrame) + symsize + srcsize + objsize + stacksize + argsize;
|
||||
pad = 8 - (frame.size % 8);
|
||||
frame.size += pad;
|
||||
|
||||
frame.data[0] = 0;
|
||||
frame.data[1] = 0;
|
||||
frame->fp = p_sp;
|
||||
frame->stack_size = stacksize;
|
||||
|
||||
/* Build up the offsets */
|
||||
if (!symname) {
|
||||
frame.sym_off = sizeof(WadFrame) - 8;
|
||||
frame.src_off = sizeof(WadFrame) - 8;
|
||||
frame.obj_off = sizeof(WadFrame) - 8;
|
||||
frame.stack_off = sizeof(WadFrame) + argsize;
|
||||
frame.arg_off = 0;
|
||||
} else {
|
||||
frame.arg_off = sizeof(WadFrame);
|
||||
frame.stack_off = sizeof(WadFrame) + argsize;
|
||||
frame.sym_off = frame.stack_off + stacksize;
|
||||
frame.src_off = frame.sym_off + symsize;
|
||||
frame.obj_off = frame.src_off + srcsize;
|
||||
/* Copy stack data */
|
||||
frame->psp = (char *) wad_malloc(stacksize);
|
||||
if (frame->psp) {
|
||||
memcpy(frame->psp, (void *) p_lastsp, stacksize);
|
||||
}
|
||||
|
||||
write(ffile,&frame,sizeof(WadFrame));
|
||||
/* Write the argument data */
|
||||
if (argsize > 0) {
|
||||
write(ffile, (void *) wd.parms, argsize);
|
||||
}
|
||||
/* Write the stack data */
|
||||
if (stacksize > 0) {
|
||||
write(ffile, (void *) p_lastsp, stacksize);
|
||||
}
|
||||
if (symname) {
|
||||
write(ffile,symname,symsize);
|
||||
write(ffile,srcname,srcsize);
|
||||
write(ffile,objname,objsize);
|
||||
}
|
||||
write(ffile,frame.data, pad);
|
||||
lastsize = frame.size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write terminator */
|
||||
frame.size = 0;
|
||||
frame.last = 1;
|
||||
frame.lastsize = lastsize;
|
||||
frame.stack_size = 0;
|
||||
write(ffile,&frame,sizeof(WadFrame));
|
||||
close(ffile);
|
||||
|
||||
/* mmap the debug file back into memory */
|
||||
|
||||
ffile = open(framefile, O_RDONLY, 0644);
|
||||
trace_len = lseek(ffile,0,SEEK_END);
|
||||
lseek(ffile,0,SEEK_SET);
|
||||
trace_addr = mmap(NULL, trace_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, ffile, 0);
|
||||
close(ffile);
|
||||
return (WadFrame *) trace_addr;
|
||||
lastframe->last = 1;
|
||||
return firstframe;
|
||||
}
|
||||
|
||||
void wad_release_trace() {
|
||||
char name[256];
|
||||
munmap(trace_addr, trace_len);
|
||||
unlink(framefile);
|
||||
trace_addr = 0;
|
||||
trace_len = 0;
|
||||
}
|
||||
|
||||
/* This function steals an argument out of a frame further up the call stack :-) */
|
||||
|
||||
long wad_steal_arg(WadFrame *f, char *symbol, int argno, int *error) {
|
||||
char *fd;
|
||||
long *regs;
|
||||
WadFrame *lastf = 0;
|
||||
|
||||
fd = (char *) f;
|
||||
|
||||
*error = 0;
|
||||
/* Start searching */
|
||||
while (f->size) {
|
||||
if (strcmp(SYMBOL(f),symbol) == 0) {
|
||||
while (f) {
|
||||
if (f->symbol && (strcmp(f->symbol,symbol) == 0)) {
|
||||
/* Got a match */
|
||||
if (lastf) {
|
||||
regs = STACK(f);
|
||||
regs = (long *) f->psp;
|
||||
return regs[8+argno];
|
||||
}
|
||||
}
|
||||
lastf = f;
|
||||
fd = fd + f->size;
|
||||
f = (WadFrame *) fd;
|
||||
f = f->next;
|
||||
}
|
||||
*error = -1;
|
||||
return 0;
|
||||
|
|
@ -313,31 +232,27 @@ long wad_steal_arg(WadFrame *f, char *symbol, int argno, int *error) {
|
|||
|
||||
|
||||
long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) {
|
||||
char *fd;
|
||||
long *regs;
|
||||
WadFrame *lastf = 0;
|
||||
|
||||
fd = (char *) f;
|
||||
|
||||
*error = 0;
|
||||
/* Start searching */
|
||||
while (f->size) {
|
||||
if (strcmp(SYMBOL(f),symbol) == 0) {
|
||||
while (f) {
|
||||
if (f->symbol && (strcmp(f->symbol,symbol) == 0)) {
|
||||
/* Got a match */
|
||||
if (lastf) {
|
||||
#ifdef WAD_SOLARIS
|
||||
regs = STACK(lastf);
|
||||
regs = (long *) lastf->psp;
|
||||
return regs[8+argno];
|
||||
#endif
|
||||
#ifdef WAD_LINUX
|
||||
regs = STACK(f);
|
||||
regs = (long *) f->psp;
|
||||
return regs[argno+2];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
lastf = f;
|
||||
fd = fd + f->size;
|
||||
f = (WadFrame *) fd;
|
||||
f = f->next;
|
||||
}
|
||||
*error = -1;
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue