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