*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@938 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
8d6a32bb08
commit
047feee80d
6 changed files with 123 additions and 172 deletions
|
|
@ -25,29 +25,21 @@ extern "C" {
|
|||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
/* Typedef's for various addresses and sizes */
|
||||
typedef char * wadaddr_t;
|
||||
typedef unsigned long wadlen_t;
|
||||
|
||||
/* Memory management */
|
||||
extern void *wadmalloc(unsigned int);
|
||||
extern void wadfree(void *ptr);
|
||||
/* Memory segment management */
|
||||
|
||||
typedef struct WadSegment {
|
||||
wadaddr_t vaddr; /* Virtual address start */
|
||||
wadlen_t size; /* Size of the segment (bytes) */
|
||||
char *base; /* Base address for symbol lookup */
|
||||
char *vaddr; /* Virtual address start */
|
||||
unsigned long size; /* Size of the segment (bytes) */
|
||||
int flags; /* Memory access permissions */
|
||||
wadlen_t offset; /* Offset into mapped object */
|
||||
unsigned long offset; /* Offset into mapped object */
|
||||
char mapname[MAX_PATH]; /* Filename mapped to this region */
|
||||
char mappath[MAX_PATH]; /* Full path to mapname */
|
||||
int identifier; /* identifier (if SysV shmem) */
|
||||
long wad; /* Private wad data (if any) */
|
||||
} WadSegment;
|
||||
|
||||
extern void wad_segment_print(WadSegment *s);
|
||||
extern WadSegment *wad_segment_find(wadaddr_t addr);
|
||||
extern WadSegment *wad_segment_first();
|
||||
extern WadSegment *wad_segment_next();
|
||||
extern void wad_segment_print(WadSegment *s);
|
||||
extern WadSegment *wad_segment_find(char *addr);
|
||||
extern void wad_segment_release();
|
||||
|
||||
/* Structure for managing object files */
|
||||
typedef struct WadObject {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ void wad_init() {
|
|||
sigaddset(&newvec.sa_mask, SIGABRT);
|
||||
sigaddset(&newvec.sa_mask, SIGILL);
|
||||
sigaddset(&newvec.sa_mask, SIGFPE);
|
||||
newvec.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
newvec.sa_flags = SA_SIGINFO | SA_ONSTACK /* | SA_RESETHAND */;
|
||||
newvec.sa_sigaction = ((void (*)(int,siginfo_t *, void *)) wad_signalhandler);
|
||||
sigaction(SIGSEGV, &newvec, NULL);
|
||||
sigaction(SIGBUS, &newvec, NULL);
|
||||
|
|
|
|||
|
|
@ -14,20 +14,122 @@
|
|||
|
||||
#include "wad.h"
|
||||
#include <procfs.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* The segment map is actually stored in an mmap'd data structure so we
|
||||
can avoid the use of malloc()/free(). */
|
||||
|
||||
static WadSegment *segments = 0; /* mmap data containing segment info */
|
||||
static int segments_size; /* Size of mmap'd region */
|
||||
static int nsegments = 0; /* Number of segments */
|
||||
|
||||
/* The current segment is stored in statically allocated memory to avoid
|
||||
the use of malloc()/free(). If a caller wants to make a copy, that is
|
||||
their problem */
|
||||
/* This function reads the segment map into memory */
|
||||
static
|
||||
void read_segments() {
|
||||
int fd;
|
||||
int dz;
|
||||
prmap_t pmap;
|
||||
int offset = 0;
|
||||
int i;
|
||||
int n = 0;
|
||||
WadSegment *s;
|
||||
|
||||
static WadSegment segment; /* Currently loaded segment */
|
||||
static int read_segment = 0;
|
||||
/* Try to load the virtual address map */
|
||||
fd = open("/proc/self/map", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
nsegments = 0;
|
||||
while (1) {
|
||||
n = read(fd,&pmap,sizeof(prmap_t));
|
||||
if (n <= 0) break;
|
||||
nsegments++;
|
||||
}
|
||||
nsegments++;
|
||||
close(fd);
|
||||
|
||||
dz = open("/dev/zero", O_RDWR, 0644);
|
||||
if (fd < 0) {
|
||||
puts("Couldn't open /dev/zero\n");
|
||||
return;
|
||||
}
|
||||
segments = (WadSegment *) mmap(NULL, nsegments*sizeof(WadSegment), PROT_READ | PROT_WRITE, MAP_PRIVATE, dz, 0);
|
||||
close(dz);
|
||||
segments_size = nsegments*sizeof(WadSegment);
|
||||
|
||||
fd = open("/proc/self/map", O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
i = 0;
|
||||
s = segments;
|
||||
while (1) {
|
||||
n = read(fd,&pmap,sizeof(prmap_t));
|
||||
if (n <= 0) break;
|
||||
strncpy(s->mapname, pmap.pr_mapname, MAX_PATH);
|
||||
strcpy(s->mappath,"/proc/self/object/");
|
||||
strcat(s->mappath,pmap.pr_mapname);
|
||||
s->vaddr = (char *) pmap.pr_vaddr;
|
||||
|
||||
/* This is a solaris oddity. a.out section starts 1 page up, but
|
||||
symbols are relative to a base of 0 */
|
||||
|
||||
if (strcmp(s->mapname,"a.out") == 0) s->base = 0;
|
||||
else s->base = s->vaddr;
|
||||
|
||||
s->size = pmap.pr_size;
|
||||
s->offset = pmap.pr_offset;
|
||||
s->flags = pmap.pr_mflags;
|
||||
s++;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_segment_release()
|
||||
*
|
||||
* This function releases all of the segments.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void wad_segment_release() {
|
||||
munmap((void *)segments, segments_size);
|
||||
segments = 0;
|
||||
segments_size = 0;
|
||||
nsegments = 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_segment_find()
|
||||
*
|
||||
* Try to find the virtual memory segment corresponding to a virtual address.
|
||||
* If a segment is mapped to a file, this function actually returns the *first*
|
||||
* segment that is mapped. This is because symbol relocations are always
|
||||
* performed relative to the beginning of the file (so we need the base address)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadSegment *
|
||||
wad_segment_find(char *addr) {
|
||||
int i;
|
||||
WadSegment *s, *ls;
|
||||
|
||||
if (!segments) read_segments();
|
||||
if (!segments) return 0;
|
||||
|
||||
s = segments;
|
||||
ls = s;
|
||||
for (i = 0; i < nsegments; i++, s++) {
|
||||
if (strcmp(s->mapname,ls->mapname)) {
|
||||
ls = s; /* First segment for a given name */
|
||||
}
|
||||
|
||||
if ((addr >= s->vaddr) && (addr < (s->vaddr + s->size))) {
|
||||
return ls;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_segment_print()
|
||||
*
|
||||
* Print the contents of a memory segment. (Debugging)
|
||||
* Print the contents of a memory segment. (For debugging WAD)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
|
|
@ -39,128 +141,4 @@ wad_segment_print(WadSegment *s) {
|
|||
printf(" size = %d\n", s->size);
|
||||
printf(" offset = %d\n", s->offset);
|
||||
printf(" flags = 0x%x\n", s->flags);
|
||||
printf(" identifier = %d\n", s->identifier);
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_segment_find()
|
||||
*
|
||||
* Try to find the virtual memory segment corresponding to a virtual address.
|
||||
* This overwrites the previously returned segment data.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadSegment *
|
||||
wad_segment_find(wadaddr_t addr) {
|
||||
char dirname[MAX_PATH];
|
||||
char filename[MAX_PATH];
|
||||
int fd;
|
||||
prmap_t pmap;
|
||||
int offset = 0;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (read_segment) {
|
||||
if ((addr >= segment.vaddr) && (addr < (segment.vaddr+segment.size))) return &segment;
|
||||
}
|
||||
|
||||
/* Set location in /proc */
|
||||
sprintf(dirname,"/proc/%d",getpid());
|
||||
|
||||
/* Try to load the virtual address map */
|
||||
sprintf(filename,"%s/map",dirname);
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("wad_segment_find: couldn't open '%s'\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
segment.mapname[0] = 0;
|
||||
|
||||
read_segment = 0;
|
||||
while (1) {
|
||||
n = read(fd,&pmap,sizeof(prmap_t));
|
||||
if (n <= 0) break;
|
||||
offset += n;
|
||||
if ((addr >= (wadaddr_t) pmap.pr_vaddr) && (addr <= (wadaddr_t) (pmap.pr_vaddr + pmap.pr_size))) {
|
||||
/* We are in a new segment */
|
||||
strncpy(segment.mapname, pmap.pr_mapname, MAX_PATH);
|
||||
strcpy(segment.mappath,dirname);
|
||||
strcat(segment.mappath,"/object/");
|
||||
strcat(segment.mappath,pmap.pr_mapname);
|
||||
segment.vaddr = (wadaddr_t) pmap.pr_vaddr;
|
||||
segment.size = pmap.pr_size;
|
||||
segment.offset = pmap.pr_offset;
|
||||
segment.flags = pmap.pr_mflags;
|
||||
segment.identifier = pmap.pr_shmid;
|
||||
segment.wad = offset;
|
||||
read_segment = 1;
|
||||
close(fd);
|
||||
return &segment;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* wad_segment_next()
|
||||
*
|
||||
* Read the next segment
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
WadSegment *wad_segment_next() {
|
||||
|
||||
char dirname[MAX_PATH];
|
||||
char filename[MAX_PATH];
|
||||
int fd;
|
||||
prmap_t pmap;
|
||||
int offset = 0;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (!read_segment) {
|
||||
segment.wad = 0;
|
||||
}
|
||||
|
||||
/* Set location in /proc */
|
||||
sprintf(dirname,"/proc/%d",getpid());
|
||||
|
||||
/* Try to load the virtual address map */
|
||||
sprintf(filename,"%s/map",dirname);
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("wad_segment_find: couldn't open '%s'\n", filename);
|
||||
return 0;
|
||||
}
|
||||
if (lseek(fd, segment.wad, SEEK_SET) < 0) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
n = read(fd,&pmap,sizeof(prmap_t));
|
||||
if (n <= 0) {
|
||||
read_segment = 0;
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
strncpy(segment.mapname, pmap.pr_mapname, MAX_PATH);
|
||||
strcpy(segment.mappath,dirname);
|
||||
strcat(segment.mappath,"/object/");
|
||||
strcat(segment.mappath,pmap.pr_mapname);
|
||||
segment.vaddr = (wadaddr_t) pmap.pr_vaddr;
|
||||
segment.size = pmap.pr_size;
|
||||
segment.offset = pmap.pr_offset;
|
||||
segment.flags = pmap.pr_mflags;
|
||||
segment.identifier = pmap.pr_shmid;
|
||||
segment.wad += n;
|
||||
read_segment = 1;
|
||||
close(fd);
|
||||
return &segment;
|
||||
}
|
||||
|
||||
WadSegment *
|
||||
wad_segment_first() {
|
||||
segment.wad = 0;
|
||||
read_segment = 0;
|
||||
return wad_segment_next();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,16 +120,6 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
addr = (unsigned long) si->si_addr;
|
||||
p_pc = (unsigned long) (*pc);
|
||||
p_sp = (unsigned long) (*sp);
|
||||
|
||||
|
||||
/* {
|
||||
Dl_info dli;
|
||||
if (dladdr((void *) p_pc, &dli) >= 0) {
|
||||
printf("dli_fname = %s\n", dli.dli_fname);
|
||||
printf("dli_sname = %s\n", dli.dli_sname);
|
||||
}
|
||||
}
|
||||
*/
|
||||
frame = wad_stack_trace(p_pc, p_sp, 0);
|
||||
origframe =frame;
|
||||
if (!frame) {
|
||||
|
|
@ -138,7 +128,6 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
}
|
||||
|
||||
/* Walk the exception frames and try to find a return point */
|
||||
|
||||
framedata = (char *) frame;
|
||||
|
||||
while (frame->size) {
|
||||
|
|
|
|||
|
|
@ -120,8 +120,7 @@ wad_search_stab(void *sp, int size, char *stabstr, char *symbol, unsigned long o
|
|||
} else if (debug.found && (s->n_type == 0x44) && (infunc)) {
|
||||
|
||||
/* Line number location */
|
||||
|
||||
if (s->n_value <= offset) {
|
||||
if (s->n_value < offset) {
|
||||
debug.line_number = s->n_desc;
|
||||
} else return &debug;
|
||||
} else if (debug.found && ((s->n_type == 0xa0) || (s->n_type == 0x40)) && (infunc)) {
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
|
||||
while (p_sp) {
|
||||
/* Add check for stack validity here */
|
||||
ws = wad_segment_find((wadaddr_t) p_sp);
|
||||
ws = wad_segment_find((char *) p_sp);
|
||||
if (!ws) {
|
||||
/* If the stack is bad, we are really hosed here */
|
||||
break;
|
||||
}
|
||||
ws = wad_segment_find((wadaddr_t) p_pc);
|
||||
ws = wad_segment_find((char *) p_pc);
|
||||
{
|
||||
int symsize = 0;
|
||||
int srcsize = 0;
|
||||
|
|
@ -85,7 +85,6 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
if (ws) {
|
||||
wo = wad_object_load(ws->mappath);
|
||||
/* Special hack needed for base address */
|
||||
if (strcmp(ws->mapname,"a.out") == 0) ws->vaddr= 0;
|
||||
}
|
||||
else {
|
||||
wo = 0;
|
||||
|
|
@ -93,13 +92,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
|
||||
/* Try to find the symbol corresponding to this PC */
|
||||
if (wo) {
|
||||
symname = wad_find_symbol(wo, (void *) p_pc, (unsigned long) ws->vaddr, &value);
|
||||
/* if (!symname) {
|
||||
Dl_info dli;
|
||||
if (dladdr((void *) p_pc, &dli) >= 0) {
|
||||
symname = (char *) dli.dli_sname;
|
||||
}
|
||||
}*/
|
||||
symname = wad_find_symbol(wo, (void *) p_pc, (unsigned long) ws->base, &value);
|
||||
} else {
|
||||
symname = 0;
|
||||
}
|
||||
|
|
@ -117,7 +110,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
symsize = strlen(symname)+1;
|
||||
|
||||
/* Try to gather some debugging information about this symbol */
|
||||
wd = wad_debug_info(wo,symname, p_pc - (unsigned long) ws->vaddr - value);
|
||||
wd = wad_debug_info(wo,symname, p_pc - (unsigned long) ws->base - value);
|
||||
if (wd) {
|
||||
srcname = wd->srcfile;
|
||||
srcsize = strlen(srcname)+1;
|
||||
|
|
@ -222,6 +215,7 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
|||
lseek(ffile,0,SEEK_SET);
|
||||
trace_addr = mmap(NULL, trace_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, ffile, 0);
|
||||
close(ffile);
|
||||
wad_segment_release();
|
||||
return (WadFrame *) trace_addr;
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +237,6 @@ long wad_steal_arg(WadFrame *f, char *symbol, int argno, int *error) {
|
|||
|
||||
fd = (char *) f;
|
||||
|
||||
|
||||
*error = 0;
|
||||
/* Start searching */
|
||||
while (f->size) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue