*** 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:
Dave Beazley 2000-11-08 02:47:07 +00:00
commit 047feee80d
6 changed files with 123 additions and 172 deletions

View file

@ -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 {

View file

@ -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);

View file

@ -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();
}

View file

@ -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) {

View file

@ -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)) {

View file

@ -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) {