*** empty log message ***

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@940 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-11-08 22:08:04 +00:00
commit d778a385d9
7 changed files with 99 additions and 230 deletions

View file

@ -17,6 +17,8 @@
#include <fcntl.h>
#include <limits.h>
#include <sys/mman.h>
#include <ctype.h>
#ifdef WAD_SOLARIS
#include <procfs.h>
#endif
@ -29,49 +31,47 @@ extern "C" {
#define MAX_PATH 1024
#endif
/* Memory segment management */
/* Memory segments */
typedef struct WadSegment {
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 */
unsigned long offset; /* Offset into mapped object */
char mapname[MAX_PATH]; /* Filename mapped to this region */
char mappath[MAX_PATH]; /* Full path to mapname */
} WadSegment;
extern void wad_segment_print();
extern WadSegment *wad_segment_find(char *addr);
extern void wad_segment_release();
extern WadSegment *wad_segment_read();
extern WadSegment *wad_segment_find(WadSegment *s, void *vaddr);
extern void wad_segment_release(WadSegment *s);
/* Structure for managing object files */
typedef struct WadObject {
void *mptr; /* mmap'd pointer */
typedef struct WadObjectFile {
void *mptr; /* mmap'd pointer to file */
int mlen; /* mmap'd length */
void *ptr; /* Pointer to real data */
int len; /* Length of real data */
int refcnt; /* Reference count */
int type; /* Type of the object file */
char path[MAX_PATH]; /* Path name of this object */
} WadObject;
} WadObjectFile;
extern char *wad_find_symbol(WadObject *wo, void *ptr, unsigned base, unsigned long *value);
extern char *wad_find_symbol(WadObjectFile *wo, void *ptr, unsigned base, unsigned long *value);
/* Maximum number of object files that can be simultaneously loaded into memory */
#define WAD_MAX_OBJECT 32
extern WadObject *wad_object_load(const char *path);
extern WadObject *wad_arobject_load(const char *path, const char *name);
extern void wad_object_release(WadObject *);
extern WadObjectFile *wad_object_load(const char *path);
extern WadObjectFile *wad_arobject_load(const char *path, const char *name);
extern void wad_object_release(WadObjectFile *);
extern void wad_init();
extern void wad_signalhandler(int, siginfo_t *, void *);
extern void wad_set_return(const char *name, long value);
extern void wad_set_return_value(long value);
extern int wad_elf_check(WadObject *wo);
extern void wad_elf_debug(WadObject *wo);
extern int wad_elf_check(WadObjectFile *wo);
extern void wad_elf_debug(WadObjectFile *wo);
typedef struct WadParm {
char name[64];
@ -94,7 +94,7 @@ typedef struct WadDebug {
#define PARM_STACK 2
extern WadDebug *wad_search_stab(void *stab, int size, char *stabstr, char *symbol, unsigned long offset);
extern WadDebug *wad_debug_info(WadObject *wo, char *symbol, unsigned long offset);
extern WadDebug *wad_debug_info(WadObjectFile *wo, char *symbol, unsigned long offset);
/* 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
@ -147,6 +147,17 @@ typedef struct {
extern void wad_set_returns(WadReturnFunc *rf);
/* --- Debugging Interface --- */
#define DEBUG_SEGMENT 0x1
#define DEBUG_SYMBOL 0x2
#define DEBUG_STABS 0x4
extern int wad_debug_mode;
#ifdef __cplusplus
}
#endif

View file

@ -2,13 +2,14 @@
SRCS = default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
OBJS = default.o stack.o stab.o elf.o object.o signal.o segment.o init.o main.o
INCLUDE = -I../Include
OPT = -DWAD_SOLARIS
PYINCLUDE = -I/usr/local/include/python2.0
TCLINCLUDE = -I/usr/local/include
all::
CC -Kpic -c $(INCLUDE) main.cxx
cc -c $(INCLUDE) $(SRCS)
CC -Kpic -c $(OPT) $(INCLUDE) main.cxx
cc -c $(OPT) $(INCLUDE) $(SRCS)
CC -G $(OBJS) -o libwad.so
cp libwad.so ..

View file

@ -31,7 +31,7 @@
* ----------------------------------------------------------------------------- */
int
wad_elf_check(WadObject *wo) {
wad_elf_check(WadObjectFile *wo) {
int t;
if (strncmp((char *)wo->ptr,ELFMAG, SELFMAG) != 0)
@ -48,7 +48,7 @@ wad_elf_check(WadObject *wo) {
* ----------------------------------------------------------------------------- */
int
wad_elf_phdrcnt(WadObject *wo) {
wad_elf_phdrcnt(WadObjectFile *wo) {
Elf32_Ehdr *eh;
eh = (Elf32_Ehdr *) wo->ptr;
@ -62,7 +62,7 @@ wad_elf_phdrcnt(WadObject *wo) {
* ----------------------------------------------------------------------------- */
void *
wad_elf_phdrpos(WadObject *wo) {
wad_elf_phdrpos(WadObjectFile *wo) {
Elf32_Ehdr *eh;
char *c;
eh = (Elf32_Ehdr *) wo->ptr;
@ -77,7 +77,7 @@ wad_elf_phdrpos(WadObject *wo) {
* ----------------------------------------------------------------------------- */
int
wad_elf_shdrcnt(WadObject *wo) {
wad_elf_shdrcnt(WadObjectFile *wo) {
Elf32_Ehdr *eh;
eh = (Elf32_Ehdr *) wo->ptr;
@ -92,7 +92,7 @@ wad_elf_shdrcnt(WadObject *wo) {
* ----------------------------------------------------------------------------- */
void *
wad_elf_shdrpos(WadObject *wo) {
wad_elf_shdrpos(WadObjectFile *wo) {
Elf32_Ehdr *eh;
char *c;
eh = (Elf32_Ehdr *) wo->ptr;
@ -106,7 +106,7 @@ wad_elf_shdrpos(WadObject *wo) {
* Get a specific section number
* ----------------------------------------------------------------------------- */
void *wad_elf_section_header(WadObject *wo, int sn) {
void *wad_elf_section_header(WadObjectFile *wo, int sn) {
Elf32_Ehdr *eh;
char *r;
@ -123,7 +123,7 @@ void *wad_elf_section_header(WadObject *wo, int sn) {
* Get section data
* ----------------------------------------------------------------------------- */
void *wad_elf_section_data(WadObject *wo, int sn) {
void *wad_elf_section_data(WadObjectFile *wo, int sn) {
Elf32_Shdr *sh;
char *r;
@ -139,7 +139,7 @@ void *wad_elf_section_data(WadObject *wo, int sn) {
* Return section size
* ----------------------------------------------------------------------------- */
int wad_elf_section_size(WadObject *wo, int sn) {
int wad_elf_section_size(WadObjectFile *wo, int sn) {
Elf32_Shdr *sh;
sh = (Elf32_Shdr *) wad_elf_section_header(wo,sn);
@ -153,7 +153,7 @@ int wad_elf_section_size(WadObject *wo, int sn) {
* Returns the name of an ELF section
* ----------------------------------------------------------------------------- */
char *wad_elf_section_name(WadObject *wo, int sn) {
char *wad_elf_section_name(WadObjectFile *wo, int sn) {
Elf32_Ehdr *eh;
Elf32_Shdr *sh;
char *sectionstr;
@ -179,7 +179,7 @@ char *wad_elf_section_name(WadObject *wo, int sn) {
* ----------------------------------------------------------------------------- */
int
wad_elf_section_byname(WadObject *wo, char *name) {
wad_elf_section_byname(WadObjectFile *wo, char *name) {
int i;
char *sn;
int n;
@ -203,7 +203,7 @@ wad_elf_section_byname(WadObject *wo, char *name) {
char *
wad_elf_find_symbol(WadObject *wo, void *ptr, unsigned long base, unsigned long *value) {
wad_elf_find_symbol(WadObjectFile *wo, void *ptr, unsigned long base, unsigned long *value) {
int nsymtab;
int nstrtab;
int symtab_size;
@ -270,7 +270,7 @@ wad_elf_find_symbol(WadObject *wo, void *ptr, unsigned long base, unsigned long
* ----------------------------------------------------------------------------- */
WadDebug *
wad_elf_debug_info(WadObject *wo, char *symbol, unsigned long offset) {
wad_elf_debug_info(WadObjectFile *wo, char *symbol, unsigned long offset) {
int nstab, nstabstr, nstabindex, nstabindexstr, nstabexcl, nstabexclstr;
void *stab;
@ -323,7 +323,7 @@ wad_elf_debug_info(WadObject *wo, char *symbol, unsigned long offset) {
stabstr = (char *) wad_elf_section_data(wo, nstabindexstr);
wd = wad_search_stab(stab,stabsize,stabstr, symbol, offset);
if (wd) {
WadObject *wo1;
WadObjectFile *wo1;
/* Hmmm. Might be in a different file */
char objfile[MAX_PATH];
strcpy(objfile, wd->objfile);
@ -348,7 +348,7 @@ wad_elf_debug_info(WadObject *wo, char *symbol, unsigned long offset) {
* ----------------------------------------------------------------------------- */
void
wad_elf_debug(WadObject *wo) {
wad_elf_debug(WadObjectFile *wo) {
int i;
printf("ELF Debug : obj = %x (%s)\n", wo, wo->path);
printf(" phdrcnt = %d\n", wad_elf_phdrcnt(wo));
@ -370,11 +370,11 @@ wad_elf_debug(WadObject *wo) {
* ----------------------------------------------------------------------------- */
char *
wad_find_symbol(WadObject *wo, void *ptr, unsigned base, unsigned long *value) {
wad_find_symbol(WadObjectFile *wo, void *ptr, unsigned base, unsigned long *value) {
return wad_elf_find_symbol(wo,ptr,base,value);
}
WadDebug *
wad_debug_info(WadObject *wo, char *symbol, unsigned long offset) {
wad_debug_info(WadObjectFile *wo, char *symbol, unsigned long offset) {
return wad_elf_debug_info(wo,symbol,offset);
}

View file

@ -15,6 +15,9 @@
/* Size of signal stack */
#define STACK_SIZE 4*SIGSTKSZ
/* Debugging flag */
int wad_debug_mode = 0;
/* Make the alternate signal stack part of the wad data segment as
opposed to putting it on the process heap */
@ -26,6 +29,13 @@ void wad_init() {
static int init = 0;
static stack_t sigstk;
if (getenv("WAD_DEBUG_SEGMENT")) {
wad_debug_mode |= DEBUG_SEGMENT;
}
if (getenv("WAD_DEBUG_SYMBOL")) {
wad_debug_mode |= DEBUG_SYMBOL;
}
if (!init) {
/* Set up an alternative stack */
sigstk.ss_sp = (char *) wad_sig_stack;

View file

@ -17,7 +17,7 @@
#include <string.h>
#include <ctype.h>
static WadObject wad_objects[WAD_MAX_OBJECT]; /* Object file descriptor table */
static WadObjectFile wad_objects[WAD_MAX_OBJECT]; /* Object file descriptor table */
static int wad_obj_free[WAD_MAX_OBJECT]; /* Free object stack */
static int wad_obj_nfree = 0; /* Num free object descriptors */
static int wad_obj_init = 0; /* Initialized? */
@ -47,7 +47,7 @@ init_object() {
* ----------------------------------------------------------------------------- */
void
wad_object_release(WadObject *wo) {
wad_object_release(WadObjectFile *wo) {
int n;
if (!wo) return;
wo->refcnt--;
@ -71,9 +71,9 @@ wad_object_release(WadObject *wo) {
* not exist or if there are no more object descriptor slots
* ----------------------------------------------------------------------------- */
WadObject *
WadObjectFile *
wad_object_load(const char *path) {
WadObject *wo;
WadObjectFile *wo;
int nf;
int fd;
int i;
@ -152,9 +152,9 @@ wad_object_load(const char *path) {
* Load an archive file object into memory using mmap.
* ----------------------------------------------------------------------------- */
WadObject *
WadObjectFile *
wad_arobject_load(const char *arpath, const char *robjname) {
WadObject *wo;
WadObjectFile *wo;
int nf;
int fd;
int i;

View file

@ -3,8 +3,11 @@
*
* This file provides access to the virtual memory map of a process
* including the location of the executable, data segments, shared
* libraries, and memory mapped regions. This information is
* obtained through /proc.
* libraries, and memory mapped regions.
*
* The primary purpose of this module is to collect this information
* and store it in a form that hides platform specific details (the
* WadSegment structure).
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
@ -14,164 +17,28 @@
#include "wad.h"
/* The segment map is actually stored in an mmap'd data structure so we
can avoid the use of malloc()/free(). */
/* General comments:
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 segment map gets returned as an array of WadSegment structures.
Due to memory constraints, this is usually located in a memory mapped
region or similar section of memory.
The first element of the memory map describes the segment map (address and size)
so that it can be cleaned up later on.
The last element of the memory map is a sentinel where base == 0 and size == 0.
*/
/* Include the proper code for reading the segment map */
/* This function reads the segment map into memory */
#ifdef WAD_SOLARIS
/* ------------- Solaris Version ------------------ */
static
void read_segments() {
int fd;
int dz;
int offset = 0;
int i;
int n = 0;
WadSegment *s;
prmap_t pmap;
/* 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 (dz < 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);
}
#include "plat/segment_solaris.c"
#endif
#ifdef WAD_LINUX
/* ------------- Linux Version ------------------ */
static
void read_segments() {
FILE *f;
int dz;
int offset = 0;
int i;
int n = 0;
char pbuffer[1024];
char *c;
WadSegment *s;
/* Try to load the virtual address map */
f = fopen("/proc/self/maps", "r");
if (!f) return;
nsegments = 0;
while (1) {
if (fgets(pbuffer,1024,f) == NULL) break;
nsegments++;
}
nsegments++;
fclose(f);
dz = open("/dev/zero", O_RDWR, 0644);
if (dz < 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);
f = fopen("/proc/self/maps","r");
if (!f) return;
i = 0;
s = segments;
while (1) {
c = fgets(pbuffer,1024,f);
if (!c) break;
pbuffer[strlen(pbuffer)-1] = 0; /* Chop off endline */
/* Break up the field into records */
/* 0-8 : Starting address
9-17 : Ending Address
18 : r
19 : w
20 : x
21 : p
23-31 : Offset
49- : Filename */
pbuffer[8] = 0;
pbuffer[17] = 0;
pbuffer[31] = 0;
strcpy(s->mapname, pbuffer+49);
strcpy(s->mappath, pbuffer+49);
s->vaddr = (char *) strtoul(pbuffer,NULL,16);
s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr);
s->offset = strtoul(pbuffer+23,NULL,16);
s->base = s->vaddr;
s->flags = 0;
s++;
}
fclose(f);
}
#include "plat/segment_linux.c"
#endif
/* -----------------------------------------------------------------------------
* 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()
*
@ -182,48 +49,25 @@ void wad_segment_release() {
* ----------------------------------------------------------------------------- */
WadSegment *
wad_segment_find(char *addr) {
int i;
WadSegment *s, *ls;
wad_segment_find(WadSegment *s, void *vaddr) {
WadSegment *ls;
char *addr = (char *)vaddr;
if (!segments) read_segments();
if (!segments) return 0;
s = segments;
ls = s;
for (i = 0; i < nsegments; i++, s++) {
while (s->size || s->base) {
/* printf("s = %x, %x(%d) %x\n",s, s->vaddr, s->size,addr); */
if (strcmp(s->mapname,ls->mapname)) {
ls = s; /* First segment for a given name */
}
if ((addr >= s->vaddr) && (addr < (s->vaddr + s->size))) {
if (wad_debug_mode & DEBUG_SEGMENT) {
printf("wad_segment: %08x --> %08x-%08x in %s\n", vaddr, s->vaddr, ((char *) s->vaddr) + s->size, s->mappath);
}
return ls;
}
s++;
}
return 0;
}
/* -----------------------------------------------------------------------------
* wad_segment_print()
*
* Print the contents of a memory segment. (For debugging WAD)
* ----------------------------------------------------------------------------- */
void
wad_segment_print() {
int i;
WadSegment *s;
if (!segments) {
read_segments();
}
s = segments;
for (i = 0; i < nsegments; i++, s++) {
printf("Segment %x:::\n",s);
printf(" mapname = %s\n", s->mapname);
printf(" mappath = %s\n", s->mappath);
printf(" vaddr = 0x%x\n", s->vaddr);
printf(" size = %d\n", s->size);
printf(" offset = %d\n", s->offset);
printf(" flags = 0x%x\n", s->flags);
}
}

View file

@ -32,9 +32,8 @@ static int trace_len = 0;
WadFrame *
wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
int i;
WadSegment *ws;
WadObject *wo;
WadSegment *ws, *segments;
WadObjectFile *wo;
WadFrame frame;
WadDebug *wd;
int nlevels;
@ -48,6 +47,10 @@ wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
int lastsize = 0;
int firstframe = 1;
/* Read the segments */
segments = wad_segment_read();
/* Open the frame file for output */
sprintf(framefile,"/tmp/wad.%d", getpid());
ffile = open(framefile, O_CREAT | O_TRUNC | O_WRONLY, 0644);
@ -63,12 +66,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((char *) p_sp);
ws = wad_segment_find(segments, (void *) p_sp);
if (!ws) {
/* If the stack is bad, we are really hosed here */
break;
}
ws = wad_segment_find((char *) p_pc);
ws = wad_segment_find(segments, (void *) p_pc);
{
int symsize = 0;
int srcsize = 0;
@ -215,7 +218,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();
wad_segment_release(segments);
return (WadFrame *) trace_addr;
}