mprof patches for SCO XENIX with GCC
Steve Bleazard
steve at robobar.co.uk
Wed Jun 26 17:08:43 AEST 1991
Submitted-by: steve at robobar.co.uk (Steve Bleazard)
Archive-name: mprof/xenix.pch01
Environment: SCO XENIX GCC
Mprof is a tool for finding memory leaks, etc., which I found languishing
on ucbarpa.berkeley.edu:/pub/mprof-3.0.tar.Z and I needed it, so here's
the port to XENIX which I did in order to be able to use it.
This port works best if you have a reasonably up to date version of
my port of GCC to SCO XENIX (any version with GDB support will do).
You can find copies of my XENIX GCC binaries on unix.secs.oakland.edu
for anon FTP, and on the anomaly.sbs.com anon UUCP archive which is
regularly advertised here. (GCC at version 1.37.1 which is what I
still use) Of course you need SCO's development system (I use
version 2.3.1b) as well. I have not tried mprof with any combination
other than GCC with SCO 2.3.1 libraries/include files.
I'm not sure if I will be able to help anyone with problems using mprof
since I haven't read the manual yet, although it has helped me plug a
couple of serious leaks already, well justifying the time spent porting it,
in fact. However, mail will be welcome.
diff -c -r -N mprof.orig/Makefile mprof/Makefile
*** mprof.orig/Makefile
--- mprof/Makefile Wed Jun 26 07:34:57 1991
***************
*** 0 ****
--- 1,102 ----
+ # %M% %I% %G% %U%
+ # Copyright (c) 1987, Benjamin G. Zorn
+ #
+ # Makefile for MPROF data generation
+ #
+
+ CC = gcc
+
+ CFLAGS= -I. -Dxenix
+ BIN= /usr/local/bin
+ LIB= /lib/386
+ MPLIB= Slibmp.a
+
+ MPROF_MON_SRCS = leak.c malloc.c mpattach.c mprof_mon.c mpstruct.c pagesz.c
+ MPROF_MON_OBJS = leak.o malloc.o mpattach.o mprof_mon.o mpstruct.o pagesz.o
+ MPROF_SRCS = mprof.c mpstruct.c mpgraph.c xsym.c
+ MPROF_OBJS = mprof.o mpstruct.o mpgraph.o xsym.o
+ DOC_SRC = mprof.1
+ DOC_OBJS = mprof.man
+
+ DISTNAME = mprof30
+
+ TEST_SRCS = test1.c test2.c
+ TEST_OBJS = test1.o test2.o
+
+ all: mprof $(MPROF_MON_OBJS) $(DOC_OBJS) $(MPLIB)
+
+ $(MPLIB): $(MPROF_MON_OBJS)
+ rm -rf $(MPLIB)
+ ar cq $(MPLIB) $(MPROF_MON_OBJS)
+ ranlib $(MPLIB)
+
+ test: $(TEST_OBJS) test1-demo test2-demo
+
+ clean:
+ rm -f *.o mprof.lint mprof-mon.lint \
+ $(DOC_OBJS) \
+ $(TEST_OBJS) \
+ test1 test1.data test1.mprof \
+ test2 test2.data test2.mprof \
+ libc_mp.a mprof mprof.data
+
+ leak.o: leak.c
+ mprof_mon.o: mprof_mon.c
+ mpstruct.o: mpstruct.c
+ mpgraph.o: mpgraph.c
+ mprof.o: mprof.c
+
+ malloc.o: malloc.c
+ $(CC) $(CFLAGS) -Dmalloc=__malloc__ -Dfree=__free__ -Drealloc=__realloc__ malloc.c -c
+
+ mprof: $(MPROF_OBJS)
+ $(CC) $(CFLAGS) -o mprof $(MPROF_OBJS)
+
+ mprof.man: mprof.1
+ nroff -man mprof.1 > mprof.man
+
+ dist: MANIFEST
+ tar cvf $(DISTNAME).tar `cat MANIFEST`
+ compress $(DISTNAME).tar
+
+ #
+ # Examples to test if MPROF is installed correctly
+ #
+
+ # A very simple test (tests calloc and valloc)
+
+ test1-demo: test1.data
+ $(BIN)/mprof -normal test1 test1.data > test1.mprof
+
+ test1.mprof: test1.data
+ $(BIN)/mprof -normal test1 test1.data > test1.mprof
+
+ test1.data: test1
+ test1
+ cp mprof.data test1.data
+
+ # test1: test1.o $(MPLIB)
+ # $(CC) $(CFLAGS) -o test1 test1.o $(MPLIB)
+ test1: test1.o $(MPROF_MON_OBJS)
+ $(CC) $(CFLAGS) -g -o test1 test1.o $(MPROF_MON_OBJS)
+
+ test1.o: test1.c
+
+
+ # test2 program (example from paper)
+
+ test2-demo: test2.data
+ $(BIN)/mprof -normal test2 test2.data > test2.mprof
+
+ test2.mprof: test2.data
+ $(BIN)/mprof -normal test2 test2.data > test2.mprof
+
+ test2.data: test2
+ test2
+ cp mprof.data test2.data
+
+ test2: test2.o $(MPLIB)
+ $(CC) $(CFLAGS) -o test2 test2.o $(MPLIB)
+
+ test2.o: test2.c
+
diff -c -r -N mprof.orig/gas-nlist.h mprof/gas-nlist.h
*** mprof.orig/gas-nlist.h
--- mprof/gas-nlist.h Tue Jun 25 10:21:12 1991
***************
*** 0 ****
--- 1,13 ----
+ #define N_STAB 0340
+
+ struct gas_nlist {
+ union {
+ char *n_name;
+ struct gas_nlist *n_next;
+ long n_strx;
+ } n_un;
+ char n_type;
+ char n_other;
+ short n_desc;
+ unsigned n_value;
+ };
diff -c -r -N mprof.orig/malloc.c mprof/malloc.c
*** mprof.orig/malloc.c Fri Sep 14 18:19:40 1990
--- mprof/malloc.c Tue Jun 25 08:08:04 1991
***************
*** 20,25 ****
--- 20,31 ----
*/
#include <sys/types.h>
+ #ifdef xenix
+ #include <string.h>
+ typedef unsigned char u_char;
+ typedef unsigned int u_int;
+ #define bcopy(s,d,l) memcpy(d,s,l)
+ #endif
#define NULL 0
diff -c -r -N mprof.orig/mpattach.c mprof/mpattach.c
*** mprof.orig/mpattach.c Fri Sep 14 18:19:41 1990
--- mprof/mpattach.c Tue Jun 25 15:26:16 1991
***************
*** 181,186 ****
--- 181,201 ----
#endif
+ #if defined(xenix) && !defined(USE_ATEXIT)
+ void exit(int code)
+ {
+ void mprof_exit();
+ extern void _cleanup(void);
+ extern void _xcleanup(void);
+ extern int _exit(int);
+
+ mprof_exit(code, 0);
+ _cleanup();
+ _xcleanup();
+ _exit(code);
+ }
+ #endif
+
void
mprof_exit(status, dummy)
int status;
diff -c -r -N mprof.orig/mpgraph.c mprof/mpgraph.c
*** mprof.orig/mpgraph.c Fri Sep 14 23:24:55 1990
--- mprof/mpgraph.c Tue Jun 25 13:04:12 1991
***************
*** 104,110 ****
vertex from, to;
mpdata data;
int mark;
! struct edge_struct *save
} *edge, edge_item;
edge
--- 104,110 ----
vertex from, to;
mpdata data;
int mark;
! struct edge_struct *save;
} *edge, edge_item;
edge
diff -c -r -N mprof.orig/mprof.c mprof/mprof.c
*** mprof.orig/mprof.c Fri Sep 14 22:01:25 1990
--- mprof/mprof.c Tue Jun 25 13:40:31 1991
***************
*** 5,15 ****
--- 5,27 ----
*/
+ #ifdef xenix
+ #include "xgasstab.h"
+ #include "gas-nlist.h"
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <sys/relsym.h>
+ #include <sys/param.h>
+ #define index strchr
+ #endif
+
#include <stdio.h>
#include <sys/file.h>
#include <ctype.h>
#include <a.out.h>
+ #ifndef xenix
#include <stab.h>
+ #endif
#include "mprof.h"
#ifdef mips
***************
*** 16,22 ****
#include <ldfcn.h>
#endif
! #if defined(mips) || defined(vax)
char *
strdup(s)
char *s;
--- 28,34 ----
#include <ldfcn.h>
#endif
! #if defined(mips) || defined(vax) || defined(xenix)
char *
strdup(s)
char *s;
***************
*** 694,699 ****
--- 706,798 ----
}
#else
+ #ifdef xenix
+
+ void
+ st_read(exec_name)
+ char *exec_name;
+ {
+ int aout_file = open(exec_name, (O_RDONLY));
+ extern char *index();
+ extern char *malloc();
+ char *stmp;
+ int string_size;
+ char *fname;
+ int i;
+ struct xseg *cseg;
+ long str_offset, nsyms, address, ntaboff;
+ struct xseg *find_segment();
+ struct gas_nlist nl;
+
+ process_a_out(aout_file, exec_name);
+
+ /* read in the global symbol table from the x.out */
+
+ if (cseg = find_segment(XS_TSYMS, 1))
+ {
+ char *symdata, *p;
+ struct sym symb;
+
+ symdata = p = malloc(cseg->xs_psize + 1);
+ lseek(aout_file, cseg->xs_filpos, 0);
+ read(aout_file, symdata, cseg->xs_psize);
+
+ while (p < symdata + cseg->xs_psize)
+ {
+ symb = *((struct sym *)p);
+ p += sizeof(struct sym);
+ if ((symb.s_type & S_TYPE) == S_TEXT)
+ {
+ stab_name(stab_i) = *p == '_' ? p + 1 : p;
+ stab_addr(stab_i) = symb.s_value;
+ stab_incr(stab_i);
+ }
+ p += strlen(p) + 1;
+ }
+ }
+
+ /* read in the string table
+ */
+ if (cseg = find_segment(XS_TSYMS, 4))
+ {
+ lseek(aout_file, cseg->xs_filpos, 0);
+ st_strings = malloc(cseg->xs_psize);
+ read(aout_file, st_strings, cseg->xs_psize);
+ }
+ else st_strings = 0;
+
+ /* read in the symbols one at a time
+ */
+ init_fileinfo_processing();
+ while (get_next_fileinfo(&str_offset, &nsyms, &address, &ntaboff))
+ {
+ lseek(aout_file, ntaboff, 0);
+ while (nsyms--)
+ {
+ read(aout_file, &nl, sizeof(nl));
+ if (nl.n_type & N_STAB)
+ {
+ if ((unsigned char)nl.n_type == N_LSYM ||
+ (unsigned char)nl.n_type == N_GSYM)
+ {
+ /* a local symbol that may be a structure definition
+ */
+ st_read_structure(st_strings + str_offset + nl.n_un.n_strx);
+ }
+ }
+ }
+ }
+ stab_name(stab_i) = "unknown";
+ stab_addr(stab_i) = stab_addr(stab_i - 1) + 0x10000;
+ stab_incr(stab_i);
+ stab_name(stab_i) = "end_marker";
+ stab_addr(stab_i) = 0xffffffff;
+ stab_incr(stab_i);
+ qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
+ }
+
+
+ #else /* !xenix */
void
st_read(exec_name)
***************
*** 774,779 ****
--- 873,880 ----
qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
}
+ #endif /* xenix */
+
void
st_read_structure(symp)
char *symp;
***************
*** 1376,1379 ****
exit(0);
}
-
--- 1477,1479 ----
diff -c -r -N mprof.orig/mprof.h mprof/mprof.h
*** mprof.orig/mprof.h Fri Sep 14 22:01:24 1990
--- mprof/mprof.h Wed Jun 26 07:31:50 1991
***************
*** 109,115 ****
extern char *strdup();
! #if (defined(vax) || (defined(sun) && !defined(sun4)))
#define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
#endif
--- 109,115 ----
extern char *strdup();
! #if (defined(vax) || (defined(sun) && !defined(sun4)) || defined(xenix))
#define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
#endif
***************
*** 119,124 ****
--- 119,132 ----
#define prev_fp_from_fp(fp) (unsigned)(((struct frame *)(fp))->fr_savfp)
#define ret_addr_from_fp(fp) (unsigned)(((struct frame *)(fp))->fr_savpc)
#endif
+ #if (defined(xenix))
+ struct frame {
+ unsigned long fr_savfp;
+ unsigned long fr_savpc;
+ };
+ #define prev_fp_from_fp(fp) (unsigned)(((struct frame *)(fp))->fr_savfp)
+ #define ret_addr_from_fp(fp) (unsigned)(((struct frame *)(fp))->fr_savpc)
+ #endif
/* for ultrix 0x38, 4.3 bsd 0x3d, other?
***************
*** 134,137 ****
--- 142,149 ----
#ifdef mips
#define CRT0_ADDRESS 0x0 /* to be filled in later */
+ #endif
+
+ #ifdef xenix
+ #define CRT0_ADDRESS 0x0
#endif
diff -c -r -N mprof.orig/mprof_mon.c mprof/mprof_mon.c
*** mprof.orig/mprof_mon.c Fri Sep 14 18:19:47 1990
--- mprof/mprof_mon.c Tue Jun 25 15:29:49 1991
***************
*** 5,10 ****
--- 5,14 ----
*/
#include <stdio.h>
+ #ifdef xenix
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #endif
#include <sys/file.h>
#include "mprof.h"
***************
*** 411,416 ****
--- 415,423 ----
#ifdef sun
on_exit(mprof_exit, NULL);
#endif
+ #if defined(xenix) && defined(USE_ATEXIT)
+ atexit(mprof_exit);
+ #endif
if (strcmp(mprof_filename, "") == 0) {
mprof_file = 1;
} else {
***************
*** 445,451 ****
--- 452,460 ----
char stats[256];
extern int mprof_fmemC, mprof_dmemC, mprof_lmemC, mprof_smemC;
+ #ifndef xenix
ftruncate(mprof_file, 0);
+ #endif
lseek(mprof_file, 0L, 0);
sprintf(stats, "alloc=%d free=%d depth=%d same=%d all=%d\n",
diff -c -r -N mprof.orig/pagesz.c mprof/pagesz.c
*** mprof.orig/pagesz.c
--- mprof/pagesz.c Tue Jun 25 08:04:00 1991
***************
*** 0 ****
--- 1,4 ----
+ int getpagesize()
+ {
+ return 4096;
+ }
diff -c -r -N mprof.orig/test1.c mprof/test1.c
*** mprof.orig/test1.c Fri Sep 14 18:19:49 1990
--- mprof/test1.c Tue Jun 25 08:10:31 1991
***************
*** 11,17 ****
extern char *realloc();
extern char *calloc();
extern char *memalign();
! extern long random();
int
main()
--- 11,17 ----
extern char *realloc();
extern char *calloc();
extern char *memalign();
! extern int rand();
int
main()
***************
*** 37,45 ****
c = calloc(1, sizeof(struct tstruct));
c = realloc(c, sizeof(struct tstruct) / 2);
free(c);
! c = malloc(random() % 57);
free(c);
! c = calloc(1, random() % 57);
if (i % 2) {
free(c);
}
--- 37,45 ----
c = calloc(1, sizeof(struct tstruct));
c = realloc(c, sizeof(struct tstruct) / 2);
free(c);
! c = malloc(rand() % 57);
free(c);
! c = calloc(1, rand() % 57);
if (i % 2) {
free(c);
}
diff -c -r -N mprof.orig/xgasstab.h mprof/xgasstab.h
*** mprof.orig/xgasstab.h
--- mprof/xgasstab.h Tue Jun 25 11:30:50 1991
***************
*** 0 ****
--- 1,28 ----
+ #define N_GSYM 0x20
+ #define N_FNAME 0x22
+ #define N_FUN 0x24
+ #define N_STSYM 0x26
+ #define N_LCSYM 0x28
+ #define N_MAIN 0x2a
+ #define N_RSYM 0x40
+ #define N_SSYM 0x60
+ #define N_PSYM 0xa0
+ #define N_LSYM 0x80
+ #define N_ENTRY 0xa4
+ #define N_SO 0x64
+ #define N_SOL 0x84
+ #define N_SLINE 0x44
+ #define N_DSLINE 0x46
+ #define N_BSLINE 0x48
+ #define N_BINCL 0x82
+ #define N_EINCL 0xa2
+ #define N_EXCL 0xc2
+ #define N_LBRAC 0xc0
+ #define N_RBRAC 0xe0
+ #define N_BCOMM 0xe2
+ #define N_ECOMM 0xe4
+ #define N_ECOML 0xe8
+ #define N_LENG 0xfe
+ #define N_PC 0x30
+ #define N_M2C 0x42
+ #define N_SCOPE 0xc4
diff -c -r -N mprof.orig/xsym.c mprof/xsym.c
*** mprof.orig/xsym.c
--- mprof/xsym.c Tue Jun 25 12:29:27 1991
***************
*** 0 ****
--- 1,341 ----
+ #include <stdio.h>
+ #include <a.out.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/relsym.h>
+ #include <sys/param.h>
+ #include <sys/file.h>
+ #include "gas-nlist.h"
+
+
+ /* XENIX symbol segment shape definitions */
+
+ struct section2 { /* File info table shape */
+ short segment; /* segment number */
+ unsigned long address; /* start address for this file */
+ unsigned short textsize; /* size of the text for this file */
+ long type3off; /* offset to type3 records, psym tab */
+ long type4off; /* offset to type4 records, nlist tab */
+ long type5off; /* offset to type5 records, str tab */
+ long type6off; /* offset to type6 records */
+ unsigned short type3sz; /* size of type3 records */
+ unsigned short type4sz; /* size of type4 records */
+ unsigned short type5sz; /* size of type5 records */
+ unsigned short type6sz; /* size of type6 records */
+ char filelen; /* length of filename */
+ };
+
+ /* psymtable (attribute 3) symbol segment shape */
+
+ struct psymbol_seg {
+ long address; /* core address */
+ short segid; /* segment number */
+ short typeid; /* variable's type */
+ char varlen; /* variable's length */
+ /* char name[0]; trailing name varlen long */
+ } record3;
+
+ /* Info maintenance structures */
+
+ struct fileinfo { /* per file info */
+ unsigned long address; /* start address for this file */
+ unsigned short textsize; /* size of text for this file */
+ long psymoff; /* psyms table */
+ long strtaboff; /* string table aka $$TYPES */
+ long ntaboff; /* nlist table aka $$SYMBOLS */
+ unsigned short psymsz; /* size of psyms table */
+ unsigned short strtabsz; /* size of string table */
+ unsigned short ntabsz; /* size of nlist table */
+ int mscdebuginfo; /* compiled with cc -g not gcc -g */
+ char *filename; /* name of this file */
+ struct fileinfo *next;
+ };
+
+ static struct fileinfo *fi_table = 0;
+ struct xseg *seg_table;
+ long num_seg_table_entries;
+
+ #ifdef __GNUC__
+ #define alloca __builtin_alloca
+ #endif
+
+ #define IGNORE_ATTR (-1)
+
+ static error (string, arg1, arg2, arg3)
+ char *string;
+ int arg1, arg2, arg3;
+ {
+ fflush (stdout);
+ fprintf (stderr, string, arg1, arg2, arg3);
+ fprintf (stderr, "\n");
+ exit(1);
+ }
+
+ static char * xmalloc (size)
+ long size;
+ {
+ register char *val = (char *) malloc (size);
+ if (!val)
+ error ("virtual memory exhausted.");
+ return val;
+ }
+
+ static perror_with_name (string)
+ char *string;
+ {
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ extern int errno;
+ char *err;
+ char *combined;
+
+ if (errno < sys_nerr)
+ err = sys_errlist[errno];
+ else
+ err = "unknown error";
+
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+
+ error ("%s.", combined);
+ }
+
+ static char *savestring (ptr, size)
+ char *ptr;
+ int size;
+ {
+ register char *p = (char *) xmalloc (size + 1);
+ memcpy(p, ptr, size);
+ p[size] = 0;
+ return p;
+ }
+
+ static read_fileinfo_table(fp, segsize, name)
+ FILE *fp;
+ int segsize;
+ char *name;
+ {
+ extern char *strrchr(), *xmalloc();
+ char *fi_name;
+ char *filename;
+ struct section2 fi_entry;
+ struct fileinfo *fi;
+
+ fi_table = fi = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
+ while (segsize > 0)
+ {
+ if ((fread((char *)&fi_entry.segment, sizeof(short), 1, fp) != 1)
+ || (fread((char *)&fi_entry.address, sizeof(unsigned long), 1, fp) != 1)
+ || (fread((char *)&fi_entry.textsize, sizeof(unsigned short),1,fp) != 1)
+ || (fread((char *)&fi_entry.type3off, sizeof(long), 1, fp) != 1)
+ || (fread((char *)&fi_entry.type4off, sizeof(long), 1, fp) != 1)
+ || (fread((char *)&fi_entry.type5off, sizeof(long), 1, fp) != 1)
+ || (fread((char *)&fi_entry.type6off, sizeof(long), 1, fp) != 1)
+ || (fread((char *)&fi_entry.type3sz, sizeof(unsigned short),1,fp) != 1)
+ || (fread((char *)&fi_entry.type4sz, sizeof(unsigned short),1,fp) != 1)
+ || (fread((char *)&fi_entry.type5sz, sizeof(unsigned short),1,fp) != 1)
+ || (fread((char *)&fi_entry.type6sz, sizeof(unsigned short),1,fp) != 1)
+ || (fread((char *)&fi_entry.filelen, sizeof(char), 1, fp) != 1))
+ perror_with_name(name);
+
+ segsize -= sizeof(short) + sizeof(unsigned long) + 5*sizeof(unsigned short)
+ + 4 * sizeof(long) + sizeof(char);
+
+ fi_name = alloca(fi_entry.filelen + 1);
+ if (fread(fi_name, fi_entry.filelen, 1, fp) != 1)
+ perror_with_name(name);
+ fi_name[fi_entry.filelen] = '\0';
+ segsize -= fi_entry.filelen;
+
+ if ((filename = strrchr(fi_name, '/')) != (char *)0)
+ fi_name = filename + 1;
+
+ if ((filename = strrchr(fi_name, '(')) != (char *)0)
+ fi_name = filename + 1;
+
+ if ((filename = strrchr(fi_name, ')')) != (char *)0)
+ *filename = '\0';
+
+ {
+ int len = strlen(fi_name);
+
+ if (len > 2 && fi_name[len - 1] == 'o' && fi_name[len - 2] == '.')
+ fi_name[len - 1] = 'c';
+ }
+
+ fi_name = savestring(fi_name, strlen(fi_name) + 1);
+
+ fi->next = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
+ fi = fi->next;
+
+ fi->address = fi_entry.address;
+ fi->textsize = fi_entry.textsize;
+ fi->psymoff = fi_entry.type3off;
+ fi->psymsz = fi_entry.type3sz;
+ fi->strtaboff = fi_entry.type4off;
+ fi->strtabsz = fi_entry.type4sz;
+ fi->ntaboff = fi_entry.type5off;
+ fi->ntabsz = fi_entry.type5sz;
+ fi->mscdebuginfo = (fi_entry.type6sz != 0);
+ fi->filename = fi_name;
+ }
+ fi->next = 0; fi = fi_table; fi_table = fi_table->next; free(fi);
+
+ #ifdef X_DEBUG
+ printf("\naddress textsz symoff symsz stroff strsz taboff tabsz name\n\n");
+ for (fi = fi_table; fi != 0; fi = fi->next)
+ {
+ printf("% 8x % 6d % 6d % 6d % 6d % 6d % 6d %6d %s\n", fi->address, fi->textsize, fi->psymoff, fi->psymsz, fi->strtaboff, fi->strtabsz, fi->ntaboff, fi->ntabsz, fi->filename);
+ }
+ printf("\n");
+ #endif /* X_DEBUG */
+ }
+
+ static read_seg_table(fp, pos, size, name)
+ FILE *fp;
+ long pos, size;
+ {
+ seg_table = (struct xseg *) xmalloc(size);
+ fseek(fp, pos, 0);
+ if (fread((char *)seg_table, size, 1, fp) != 1)
+ perror_with_name(name);
+ num_seg_table_entries = size / sizeof (struct xseg);
+ }
+
+
+ struct xseg *find_segment(type, attr)
+ int type, attr;
+ {
+ struct xseg *cseg;
+
+ for (cseg = seg_table; cseg < seg_table + num_seg_table_entries; ++cseg)
+ if (cseg->xs_type == type &&
+ (attr == IGNORE_ATTR || attr == cseg->xs_attr))
+ return cseg;
+ return NULL;
+ }
+
+ process_a_out(desc, name)
+ int desc;
+ char *name;
+ {
+ struct xexec exec_aouthdr;
+ struct xext *xext;
+ struct xseg *cseg;
+ FILE *fp;
+
+ lseek(desc, 0L, 0);
+ if ((fp = fdopen(dup(desc), "r")) == NULL)
+ perror_with_name(name);
+
+ if (fread((char *)&exec_aouthdr, sizeof(struct xexec), 1, fp) != 1)
+ perror_with_name(name);
+
+ xext = (struct xext *) alloca(exec_aouthdr.x_ext);
+ if (fread((char *)xext, exec_aouthdr.x_ext, 1, fp) != 1)
+ perror_with_name(name);
+
+ read_seg_table(fp, xext->xe_segpos, xext->xe_segsize, name);
+
+ if (cseg = find_segment(XS_TSYMS, 2))
+ {
+ fseek(fp, cseg->xs_filpos, 0);
+ read_fileinfo_table(fp, cseg->xs_psize, name);
+ }
+
+ fclose(fp);
+ }
+
+ static struct fileinfo *current_fi;
+ static int first_get_fileinfo_call = 1;
+
+ init_fileinfo_processing() /* start processing the list of files */
+ {
+ first_get_fileinfo_call = 1;
+ }
+
+ long get_next_fileinfo(stroff, nsyms, address, symtaboff)
+ long *stroff, *nsyms, *address, *symtaboff;
+ {
+ struct xseg *cseg;
+
+ if (first_get_fileinfo_call)
+ {
+ current_fi = fi_table;
+ first_get_fileinfo_call = 0;
+ }
+ else
+ current_fi = current_fi->next;
+
+ if (current_fi == 0)
+ return 0;
+
+ if (current_fi->mscdebuginfo)
+ {
+ *stroff = 0;
+ *nsyms = 0;
+ *address = current_fi->address;
+ }
+ else if (cseg = find_segment(XS_TSYMS, 5))
+ {
+ *symtaboff = cseg->xs_filpos + current_fi->ntaboff;
+ *stroff = current_fi->strtaboff;
+ *nsyms = current_fi->ntabsz / sizeof(struct gas_nlist);
+ *address = current_fi->address;
+ return 1;
+ }
+ else
+ {
+ *symtaboff = 0;
+ *stroff = 0;
+ *nsyms = 0;
+ *address = 0;
+ }
+ }
+
+ #ifdef TEST
+
+ main()
+ {
+ char *stab;
+ long str_offset, nsyms, address, ntaboff;
+ int desc;
+ struct xseg *cseg;
+
+ process_a_out((desc = open("a.out", O_RDONLY, 0)), "a.out");
+
+ printf("\n");
+
+ if (cseg = find_segment(XS_TSYMS, 4))
+ {
+ lseek(desc, cseg->xs_filpos, 0);
+ stab = alloca(cseg->xs_psize);
+ read(desc, stab, cseg->xs_psize);
+ }
+ else
+ stab = 0;
+
+ init_fileinfo_processing();
+ while (get_next_fileinfo(&str_offset,&nsyms,&address,&ntaboff))
+ {
+ lseek(desc, ntaboff, 0);
+ printf("\n type desc value stroff string (%#x)\n", address);
+ while (nsyms--)
+ {
+ struct gas_nlist nl;
+
+ read(desc, &nl, sizeof(nl));
+ printf("% 6x % 6x % 8x % 6x %s\n",
+ (unsigned char)nl.n_type,
+ (unsigned short)nl.n_desc,
+ (unsigned int)nl.n_value,
+ (unsigned int)nl.n_un.n_strx,
+ nl.n_un.n_strx ? stab + str_offset + nl.n_un.n_strx : "");
+ }
+ lseek(desc, 0L, 0);
+ }
+ }
+
+ #endif /* TEST */
--
Steve.Bleazard at RoboBar.Co.Uk | Phone: +44 81 991 1142 x153
Snr Software Engineer, Robobar Ltd. | Fax: +44 81 998 8343 (G3)
22 Wadsworth Road, Perivale. |
Middx., UB6 7JD ENGLAND. | ...!ukc!robobar!steve
More information about the Alt.sources
mailing list