UNIX PC COFF Disassembler (Part 2 of 2)

Lenny Tropiano lenny at icus.islp.ny.us
Tue Sep 27 10:35:46 AEST 1988


Here's part 2...

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  heur.c libmtch.c main.c prin.c robj.c unc.h
# Wrapped by lenny at icus on Mon Sep 26 20:30:25 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'heur.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'heur.c'\"
else
echo shar: Extracting \"'heur.c'\" \(9925 characters\)
sed "s/^X//" >'heur.c' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)heur.c	1.2	11/2/84	14:17:46
X *	Attempt to guess things about the file.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X */
X
X#include <stdio.h>
X#include <a.out.h>
X#include <ldfcn.h>
X#include "unc.h"
X
X#define	INITDAT	256
X#define	INCDAT	128
X
X#define	STRSCNT	3
X#define	STRECNT	3
X
Xchar	*malloc(), *realloc();
X
Xvoid	gette(), getde(), setde(), putte(), putde();
Xvoid	nomem();
Xlong	getdw();
Xsymbol	inventsymb();
X
Xlong	endt;
Xef_fids	mainfile;
X
X/*
X *	Talk about implemented things.....
X */
X
Xvoid	unimpl(msg)
Xchar	*msg;
X{
X	(void) fprintf(stderr, "Warning: handling of \"%s\" not implemented\n", msg);
X}
X
X/*
X *	Return 1 if string char, otherwise 0.
X */
X
Xint	possstr(x)
Xunsigned  x;
X{
X	if  (x >= ' '  &&  x <= '~')
X		return	1;
X	if  (x == '\n'  ||  x == '\t')
X		return	1;
X	return	0;
X}
X
X/*
X *	Guess things about data files.
X */
X
Xvoid	intudat(fid)
Xef_fid  fid;
X{
X	register  int	i, j;
X	int	lt, input, invcnt;
X	long	offs, soffs, endd;
X	d_entry	fdat;
X	unsigned  char	*inbuf;
X	int	ibsize;
X	
X	inbuf = (unsigned  char *)malloc(INITDAT);
X	if  (inbuf == NULL)
X		nomem();
X	ibsize = INITDAT;
X	
X	offs = fid->ef_dbase;
X	endd = fid->ef_bbase;
X
X	while  (offs < endd)  {
X		getde(fid, offs, &fdat);
X		if  (fdat.d_type != D_BYTE)  {
X			offs += fdat.d_lng;
X			continue;
X		}
X		
X		/*
X		 *	Looks like general data.  Read in as much as possible.
X		 */
X		
X		input = 0;
X		soffs = offs;
X		do  {
X			if  (input >= ibsize)  {
X				ibsize += INCDAT;
X				inbuf = (unsigned  char *)
X					realloc((char *)inbuf, (unsigned)ibsize);
X				if  (inbuf == NULL)
X					nomem();
X			}
X			inbuf[input++] = fdat.d_contents;
X			offs++;
X			if  (offs >= endd)
X				break;
X			getde(fid, offs, &fdat);
X		}  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
X		
X		/*
X		 *	Now split up the data.
X		 */
X		
X		for  (i = 0;  i < input;  )  {
X			
X			/*
X			 *	Might be a string.
X			 */
X			
X			if  (possstr(inbuf[i]))  {
X				lt = input;
X				if  (i + STRSCNT < lt)
X					lt = i + STRSCNT;
X				for  (j = i + 1;  j < lt;  j++)  {
X					if  (inbuf[j] == '\0')
X						break;
X					if  (!possstr(inbuf[j]))
X						goto  notstr;
X				}
X				
X				/*
X				 *	Looks like a string then.
X				 */
X				
X				invcnt = 0;
X				for  (j = i + 1; j < input;  j++)  {
X					if  (inbuf[j] == '\0')  {
X						j++;
X						break;
X					}
X					if  (possstr(inbuf[j]))
X						invcnt = 0;
X					else  {
X						invcnt++;
X						if  (invcnt >= STRECNT)  {
X							j -= invcnt - 1;
X							break;
X						}
X					}
X				}
X
X				setde(fid,
X				      soffs+i,
X				      (unsigned)(inbuf[j-1]=='\0'?D_ASCZ:D_ASC),
X				      j - i);
X				for  (i++;  i < j;  i++)
X					setde(fid, soffs+i, D_CONT, 1); 
X				continue;
X			}
X
Xnotstr:
X			/*
X			 *	If on odd boundary, treat as a byte.
X			 */
X			
X			if  ((soffs + i) & 1  ||  i + 1 >= input)  {
X				setde(fid, soffs + i, D_BYTE, 1);
X				i++;
X				continue;
X			}
X
X			/*
X			 *	Treat as longs unless not enough.
X			 */
X			
X			if  (i + 3 >= input)  {
X				setde(fid, soffs + i, D_WORD, 2);
X				setde(fid, soffs + i + 1, D_CONT, -1);
X				i += 2;
X				continue;
X			}
X
X			/*
X			 *	Treat as a long but mark changable.
X			 */
X			
X			setde(fid, soffs + i, D_LONG, 4);
X			for  (j = 1;  j < 4;  j++)
X				setde(fid, soffs + i + j, D_CONT, -j);
X			i += 4;
X		}
X	}
X	free((char *)inbuf);
X	
X	/*
X	 *	Now zap bss segment.
X	 */
X	
X	offs = fid->ef_bbase;
X	endd = fid->ef_end;
X
X	while  (offs < endd)  {
X		getde(fid, offs, &fdat);
X		if  (fdat.d_type != D_BYTE)  {
X			offs += fdat.d_lng;
X			continue;
X		}
X
X		soffs = offs;
X		do  {
X			offs++;
X			if  (offs >= endd)
X				break;
X			getde(fid, offs, &fdat);
X		}  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
X		
X		setde(fid, soffs, D_BYTE, (int)(offs-soffs));
X		for  (i = -1, soffs++;  soffs < offs; i--, soffs++)
X			setde(fid, soffs, D_CONT, i); 
X	}
X}
X
X/*
X *	For non relocatable files, try to identify address pointers in
X *	the data.
X */
X
Xvoid	inturdat(fid)
Xef_fid	fid;
X{
X	register  long	offs = fid->ef_dbase;
X	register  int	i;
X	register  symbol  ds;
X	long  endd = fid->ef_bbase;
X	long  cont;
X	d_entry	dent, refdent;
X
X	while  (offs < endd)  {
X		getde(fid, offs, &dent);
X		if  (dent.d_type != D_LONG)
X			goto  endit;
X		cont = getdw(fid, offs, R_LONG);
X		if  (cont < fid->ef_dbase || cont > fid->ef_end)
X			goto  endit;
X		getde(fid, cont, &refdent);
X		if  (refdent.d_type == D_CONT)  {
X			d_entry	pdent;
X			int	siz;
X			
X			if  (refdent.d_lng >= 0)
X				goto  endit;
X			getde(fid, cont+refdent.d_lng, &pdent);
X			i = -refdent.d_lng;
X			refdent.d_lng += pdent.d_lng;
X			pdent.d_lng = i;
X			if  (pdent.d_type == D_LONG  &&  i == 2)
X				siz = D_WORD;
X			else
X				siz = D_BYTE;
X			refdent.d_type = siz;
X			pdent.d_type = siz;
X			putde(fid, cont - i, &pdent);
X			for  (i = 1;  i < refdent.d_lng;  i++)
X				setde(fid, cont+i, D_CONT, -i);
X		}
X		if  ((ds = refdent.d_lab) == NULL)  {
X			if  (cont >= fid->ef_bbase)  {
X				ds = inventsymb("BS");
X				ds->s_type = S_BSS;
X			}
X			else  {
X				ds = inventsymb("DS");
X				ds->s_type = S_DATA;
X			}
X			ds->s_value = cont;
X			refdent.d_lab = ds;
X			putde(fid, cont, &refdent);
X		}
X		else
X			ds->s_used++;
X		dent.d_type = D_ADDR;
X		dent.d_relsymb = ds;
X		dent.d_rptr = ds->s_type;
X		putde(fid, offs, &dent);
X		for  (i = 1;  i < 4;  i++)
X			setde(fid, offs+i, D_CONT, 1);
Xendit:
X		offs += dent.d_lng;
X	}
X}
X
X/*
X *	Recursively follow through the code, stopping at unconditional
X *	branches and invalid instructions.
X */
X
Xvoid	follseq(pos)
Xlong	pos;
X{
X	t_entry	tent;
X	int	lng;
X	long	npos;
X
X	while  (pos < endt)  {
X		gette(&mainfile, pos, &tent);
X		if  (tent.t_amap)	/*  Been here  */
X			return;
X		tent.t_amap = 1;
X		lng = findinst(&tent, pos);
X		npos = pos + lng*2;
X		if  (npos > endt)  {
X			tent.t_vins = 0;
X			tent.t_lng = 1;
X			tent.t_type = T_UNKNOWN;
X			lng = 0;
X			npos = endt;
X		}
X		putte(&mainfile, pos, &tent);
X		pos = npos;
X		
X		if  (lng <= 0)
X			return;
X
X		switch  (tent.t_bchtyp)  {
X		case  T_UNBR:
X			if  (tent.t_relsymb == NULL)
X				return;
X			pos = tent.t_relsymb->s_value;
X			continue;
X		case  T_JSR:
X			if  (tent.t_relsymb != NULL)
X				follseq(tent.t_relsymb->s_value);
X			continue;
X		case  T_CONDBR:
X			follseq(tent.t_relsymb->s_value);
X		default:
X			continue;
X		}
X	}
X}
X			
X			
X/*
X *	Try to work out things about text files.
X */
X
Xvoid	intutext()
X{
X	long	pos;
X	t_entry	tent;
X	int	lng;
X	
X	endt = mainfile.ef_tbase + mainfile.ef_tsize;
X	pos = mainfile.ef_entry;
Xnextv:
X	for  (;  pos < endt;)  {
X		gette(&mainfile, pos, &tent);
X		if  (!tent.t_amap && tent.t_vins)  {
X			follseq(pos);
X			pos += 2;
X			goto  nextiv;
X		}
X		pos += tent.t_lng * 2;
X		if  (tent.t_bchtyp == T_UNBR)
X			goto  nextiv;
X	}
X	goto	dorest;
Xnextiv:
X	for  (;  pos < endt;  pos += 2)  {
X		gette(&mainfile, pos, &tent);
X		if  (tent.t_bdest)
X			goto  nextv;
X	}
Xdorest:
X	/*
X	 *	Deal with unmapped instructions.
X	 */
X	
X 	for  (pos = mainfile.ef_tbase;  pos < endt;)  {
X		gette(&mainfile, pos, &tent);
X		switch  (tent.t_type)  {
X		case  T_BEGIN:
X			pos += tent.t_lng * 2;
X			continue;
X		case  T_UNKNOWN:
X			if  (tent.t_vins)  {
X				lng = findinst(&tent, pos);
X				putte(&mainfile, pos, &tent);
X				if  (lng > 0)  {
X					pos += lng * 2;
X					continue;
X				}
X			}
X		default:
X			pos += 2;
X			continue;
X		}
X	}
X}
X
X/*
X *	Invent local symbols.
X */
X
Xvoid	intlsym()
X{
X	long	bpos, epos, hiref, hipos;
X	unsigned  llnum;
X	t_entry	tent;
X	register  symbol  tl;
X	
X	endt = mainfile.ef_tbase + mainfile.ef_tsize;
X	epos = mainfile.ef_entry;
X	for  (;;)  {
X		bpos = epos;
X		hiref = bpos;
X		if  (epos >= endt)
X			return;
X		gette(&mainfile, epos, &tent);
X		epos += tent.t_lng * 2;
X		for  (;  epos < endt;)  {
X			gette(&mainfile, epos, &tent);
X			if  (tent.t_gbdest  ||  tent.t_dref)
X				break;
X			if  (tent.t_reflo < bpos)
X				break;
X			if  (tent.t_refhi > hiref)  {
X				hiref = tent.t_refhi;
X				hipos = epos;
X			}
X			epos += tent.t_lng * 2;
X		}
X		if  (hiref > epos)
X			epos = hipos;
X		llnum = 0;
X		for  (hipos = bpos;  hipos < epos;)  {
X			gette(&mainfile, hipos, &tent);
X			if  (!tent.t_gbdest && !tent.t_dref &&
X			 tent.t_reflo >= bpos && tent.t_refhi < epos &&
X			 (tl = tent.t_lab) != NULL)
X				tl->s_lsymb = ++llnum;
X			hipos += tent.t_lng * 2;
X		}
X	}
X}
X
X/*
X *	Given the main file, a possible candidate for matching in the
X *	file and an offset, see if text matches.  Return 1 if matches,
X *	or 0 if no match.
X */
X
Xint	matchup(mf, lf, startpos)
Xregister  ef_fid  mf, lf;
Xlong	startpos;
X{
X	register  int	i, matches = 0;
X	t_entry	ltent, mtent;
X
X	if  (lf->ef_tsize > mf->ef_tsize - startpos + mf->ef_tbase)
X		return	0;	/*  At end - can't fit  */
X
X	for  (i = 0;  i < lf->ef_tsize;  i += 2)  {
X		gette(lf, lf->ef_tbase + i, &ltent);
X		if  (ltent.t_isrel)
X			continue;
X		gette(mf, startpos + i, &mtent);
X		if  (mtent.t_contents != ltent.t_contents)
X			return	0;
X		matches++;
X	}
X	
X	/*
X	 *	Give up on zero length or all relocatable files.
X	 */
X	
X	return	matches > 0;
X}
X
X/*
X *	Scan through main file looking for a match.
X */
X
Xlong	findstart(mf, lf)
Xregister  ef_fid  mf, lf;
X{
X	register  long	res = mf->ef_tbase;
X	long	lim = mf->ef_tbase + mf->ef_tsize - lf->ef_tsize;
X	t_entry	tent;
X	
Xrestart:
X	for  (;  res <= lim;  res += 2)  {
X		gette(mf, res, &tent);
X		if  (tent.t_match != 0)  {
X			res += tent.t_match;
X			goto  restart;
X		}
X		if  (matchup(mf, lf, res))
X			return	res;
X	}
X	return	-1;
X}
X
X/*
X *	Mark the head of a matched module to save searching.
X */
X
Xvoid	markmatch(mf, lf, pos)
Xef_fid	mf, lf;
Xlong	pos;
X{
X	t_entry	tent;
X	
X	gette(mf, pos, &tent);
X	tent.t_match = (unsigned) lf->ef_tsize;
X	putte(mf, pos, &tent);
X}
END_OF_FILE
if test 9925 -ne `wc -c <'heur.c'`; then
    echo shar: \"'heur.c'\" unpacked with wrong size!
fi
# end of 'heur.c'
fi
if test -f 'libmtch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libmtch.c'\"
else
echo shar: Extracting \"'libmtch.c'\" \(6912 characters\)
sed "s/^X//" >'libmtch.c' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)libmtch.c	1.2	11/2/84	14:18:55
X *	Read library files.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <string.h>
X#include <a.out.h>
X#include <ar.h>
X#include <setjmp.h>
X#include <ldfcn.h>
X#include "unc.h"
X
Xlong	atol();
Xlong	lseek();
Xvoid	bfopen(), bfclose(), nomem();
Xvoid	rrell2(), markmatch();
Xchar	*malloc();
Xint	matchup();
Xlong	findstart();
X
Xchar	verbose;		/*  Tell the world what we are doing  */
Xchar	*tfnam;
Xchar	*cfile;
Xef_fids	mainfile;
Xstruct	commit	dreltab;
Xint	donedrel, donebrel;
Xlong	trelpos, drelpos, brelpos;
Xstatic	struct	libit	currlib = {NULL, NULL, ""};
X
Xvoid	lclash(str)
Xchar	*str;
X{
X	(void) fprintf(stderr, "Library scan failure - %s\n", str);
X	(void) fprintf(stderr, "Searching %s\n", cfile);
X	if  (currlib.lf_name[0])
X		(void) fprintf(stderr, "Member is %s\n", currlib.lf_name);
X	exit(255);
X}
X
X/*
X *	Find next member.
X */
X
Xlong	nextmemb(filename,lfd)
Xchar *filename;
Xregister  struct  libit	 *lfd;
X{
X	struct	ar_hdr	arbuf;
X	
X	ldaclose(lfd->ldptr2);
X	if (ldclose(lfd->ldptr != FAILURE))	/* end of archive */
X	    return -1;
X	lfd->ldptr = ldopen(filename,lfd->ldptr);
X	ldahread(lfd->ldptr, (char *)&arbuf);
X	(void) strncpy(lfd->lf_name, arbuf.ar_name, sizeof(lfd->lf_name));
X	return 1;
X}
X
X/*
X *	Decode a file name thus -
X *
X *	-lxxx decode as /lib/libxxx.a /usr/lib/libxxx.a etc
X *	-Lxxx forget "lib" ".a" bit thus -Lcrt0.o
X *	or read LDPATH environment var to give list of directories as sh
X *	(default /lib:/usr/lib).
X *
X *	Alternatively treat as normal pathname.
X *
X *	File names may be followed by (membername) if the file is an archive,
X *	thus
X *
X *		-lc(printf.o)
X *
X *	in which case the specified module is fetched.
X */
X
Xstruct	libit	*getfnam(str)
Xchar	*str;	/* will be expanded to full path name if necessary */
X{
X	char	*bp, *ep = NULL, *pathb, *pathe, *fullpath = NULL;
X	static	char	*pathn;
X	extern	char	*getenv();
X 	char	magic[8];
X	struct	ar_hdr	arhdr;
X	LDFILE *ldptr;
X
X 	if  ((bp = strrchr(str, '(')) != NULL &&
X 		 (ep = strrchr(str, ')')) != NULL)
X		*ep = *bp = '\0';
X
X	if  (str[0] == '-'  &&  (str[1] == 'l' || str[1] == 'L'))  {
X		if  (pathn == NULL)  {
X			if  ((pathn = getenv("LDPATH")) == NULL)
X				pathn = "/lib:/usr/lib";
X		}
X		fullpath = malloc((unsigned)(strlen(pathn) + strlen(str) + 1));
X		if  (fullpath == NULL)
X			nomem();
X		pathb = pathn;
X		do  {
X 			pathe = strchr(pathb, ':');
X			if  (*pathb == ':')
X				fullpath[0] = '\0';
X			else  {
X				if  (pathe != NULL)
X					*pathe = '\0';
X				(void) strcpy(fullpath, pathb);
X				(void) strcat(fullpath, "/");
X				if  (pathe != NULL)
X					*pathe = ':';
X			}
X			if  (str[1] == 'l')
X				(void) strcat(fullpath, "lib");
X			(void) strcat(fullpath, &str[2]);
X			if  (str[1] == 'l')
X				(void) strcat(fullpath, ".a");
X			if  ((ldptr = ldopen(fullpath, NULL)) != NULL)
X				goto  found;
X			pathb = pathe + 1;
X		}   while  (pathe != NULL);
X		
X		(void) fprintf(stderr, "Unable to locate lib%s.a in %s\n",
X			&str[2], pathn);
X		exit(101);
X	}
X	else  if  ((ldptr = ldopen(str, NULL)) == NULL)  {
X		(void) fprintf(stderr, "Cannot open %s\n", str);
X		exit(102);
X	}
X	
Xfound:
X
X	str = fullpath? fullpath: str;
X 	if  (FREAD(magic, sizeof(magic),1,ldptr) != 1  ||
X 		strcmp(magic, ARMAG) != 0)  {
X		if  (ep != NULL)  {
X			(void) fprintf(stderr, "%s is not library file\n", str);
X			exit(103);
X		}
X		currlib.ldptr = ldptr;
X		currlib.ldptr2 = ldaopen(str,ldptr);
X		currlib.lf_name[0] = '\0';
X		return  &currlib;
X	}
X	
X	/*
X	 *	It appears to be a library file - see if we want a specific
X	 *	one.
X	 */
X	
X	if  (ep != NULL)  {
X 		char *cp;
X 
X		for  (;;)  {
X			if  (ldahread(ldptr,&arhdr) == FAILURE)  {
X				(void) fprintf(stderr, "Cannot find member %s in %s\n",
X					bp+1, str);
X				exit(103);
X			}
X 			for ( cp = arhdr.ar_name + sizeof(arhdr.ar_name) - 1;
X 				*cp == ' ';
X 				cp -- ) ;
X 			if  (strncmp(bp+1, arhdr.ar_name, cp - arhdr.ar_name + 1) == 0)
X				break;
X
X			if (ldclose(ldptr) != FAILURE) {
X				(void) fprintf(stderr, "Cannot find member %s in %s\n",
X					bp+1, str);
X				exit(103);
X			}
X			ldptr = ldopen(str,ldptr);
X		}
X		currlib.ldptr = ldptr;
X		currlib.ldptr2 = ldaopen(str,ldptr);
X		currlib.lf_name[0] = '\0';
X		*bp = '(';
X		*ep = ')';
X		return	&currlib;
X	}
X	
X	/*
X	 *	Otherwise point to 1st member in library.
X	 */
X	
X	if  (ldahread(ldptr, &arhdr) == FAILURE)  {
X		(void) fprintf(stderr, "Library %s empty\n", str);
X		exit(104);
X	}
X	currlib.ldptr = ldptr;
X	currlib.ldptr2 = ldaopen(str,ldptr);
X	(void) strncpy(currlib.lf_name, arhdr.ar_name, sizeof(currlib.lf_name));
X	return	&currlib;
X}
X
X/*
X *	Process library files.
X */
X
X#define	MINTEXT	6
X
Xvoid	lscan(nfiles, fnames)
Xint	nfiles;
Xchar	**fnames;
X{
X	ef_fids	libfile;
X	register  ef_fid  ll = &libfile;
X	register  struct  libit	 *clf;
X	extern	symbol	dolsymb();
X	int	firstfile;
X	
X	for  (;  nfiles > 0;  fnames++, nfiles--)  {
X		clf = getfnam(*fnames);
X		cfile = *fnames;
X		firstfile = 1;
X		do  {
X			bfopen(tfnam, ll);
X
X			/*
X			 *	If file is garbled, silently forget it and go
X			 *	on to the next one.
X			 */
X
X			if  (!rtext(clf->ldptr, ll))
X				goto  closeit;
X				
X			if  (ll->ef_tsize < MINTEXT)
X				goto  closeit;
X				
X			if  (!rdata(clf->ldptr, ll))
X				goto  closeit;
X				
X			if  (rrell1(clf->ldptr, ll) < 0)
X				goto  closeit;
X				
X			/*
X			 *	If first file in library, find it from
X			 *	beginning of main file.
X			 */
X			
X			if  (firstfile)  {
X				if  ((trelpos = findstart(&mainfile, ll)) < 0)
X					goto  closeit;
X				firstfile = 0;
X			}
X			else   if  (!matchup(&mainfile, ll, trelpos))
X					goto  closeit;
X			
X			/*
X			 *	Found a match.
X			 */
X			
X			if  (!rsymb(clf->ldptr, dolsymb, ll))  {
X				(void) fprintf(stderr, "Corrupt file %s\n",
X							*fnames);
X				exit(150);
X			}
X			
X			donedrel = 0;
X			donebrel = 0;
X			rrell2(clf->ldptr, clf->ldptr2, ll);
X			if  (verbose)  {
X				(void) fprintf(stderr, "Found: ");
X				if  (clf->lf_name[0])
X					(void) fprintf(stderr, "%.14s in ",
X							clf->lf_name);
X				(void) fprintf(stderr, "%s\n", *fnames);
X			}
X			if  (libfile.ef_stvec != NULL)  {
X				free(libfile.ef_stvec);
X				libfile.ef_stvec = NULL;
X				libfile.ef_stcnt = 0;
X			}
X			dreltab.c_int = 0;
X				
X			/*
X			 *	Start looking next time round
X			 *	where last one left off.
X			 */
X			
X			markmatch(&mainfile, ll, trelpos);
X			trelpos += libfile.ef_tsize;
Xcloseit:
X			bfclose(ll);
X		}  while  (nextmemb(cfile,clf) >= 0);
X	}
X}
END_OF_FILE
if test 6912 -ne `wc -c <'libmtch.c'`; then
    echo shar: \"'libmtch.c'\" unpacked with wrong size!
fi
# end of 'libmtch.c'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(5877 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)main.c	1.2	11/2/84	14:19:31
X *	Main routine etc.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <a.out.h>
X#include <ldfcn.h>
X#include "unc.h"
X
X#define	LINELNG	70
X
Xvoid	inturdat(), intutext(), intudat(), intlsym();
Xvoid	ptext(), pdata(), pabs(), pbss(), lscan();
X
Xef_fids	mainfile;
X
Xint	nmods;			/*  Number of modules it looks like  */
X
Xchar	*tfnam = "split";
X
Xchar	lsyms;			/*  Generate local symbols  */
Xchar	verbose;		/*  Tell the world what we are doing  */
Xchar	noabs;			/*  No non-global absolutes  */
Xint	rel;			/*  File being analysed is relocatable  */
Xint	lpos;
X
Xsymbol	dosymb();
Xstruct	libit	*getfnam();
X
X/*
X *	Get hex characters, also allowing for 'k' and 'm'.
X */
X
Xint	ghex(str)
Xregister  char	*str;
X{
X	register  int	result = 0;
X	register  int	lt;
X
X	for  (;;)  {
X		lt = *str++;
X		switch  (lt)  {
X		default:
Xerr:			(void) fprintf(stderr, "Invalid hex digit \'%c\'\n", lt);
X			exit(1);
X			
X		case '\0':
X			return	result;
X			
X		case '0':case '1':case '2':case '3':case '4':
X		case '5':case '6':case '7':case '8':case '9':
X			result = (result << 4) + lt - '0';
X			continue;
X			
X		case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
X			result = (result << 4) + lt - 'a' + 10;
X			continue;
X
X		case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
X			result = (result << 4) + lt - 'A' + 10;
X			continue;
X		
X		case 'k':case 'K':
X			if  (*str != '\0')
X				goto  err;
X			return  result << 10;
X			
X		case 'm':case 'M':
X			if  (*str != '\0')
X				goto  err;
X			return  result << 20;
X		}
X	}
X}
X
X/*
X *	Process entry line options.  Return number dealt with.
X */
X
Xint	doopts(av)
Xchar	*av[];
X{
X	register  int	cnt = 0, lt;
X	register  char	*arg;
X	
X	for  (;;)  {
X		arg = *++av;
X		if  (*arg++ != '-')
X			return	cnt;
X		cnt++;
X		
Xnx:		switch  (lt = *arg++)  {
X		default:
X			(void) fprintf(stderr, "Bad option -%c\n", lt);
X			exit(1);
X			
X		case  '\0':
X			continue;
X			
X		case  'l':	/*  A file name  */
X		case  'L':
X			return	cnt - 1;
X			
X		case  's':
X			lsyms++;
X			goto  nx;
X			
X		case  'v':
X			verbose++;
X			goto  nx;
X			
X		case  'a':
X			noabs++;
X			goto  nx;
X
X		case  't':
X			if  (*arg == '\0')  {
X				cnt++;
X				arg = *++av;
X				if  (arg == NULL) {
Xbo:					(void) fprintf(stderr,"Bad -%c option\n",lt);
X					exit(1);
X 				      }
X			}
X			tfnam = arg;
X			continue;
X			
X		case  'o':
X			if  (*arg == '\0')  {
X				cnt++;
X				arg = *++av;
X				if  (arg == NULL)
X					goto  bo;
X			}
X			if  (freopen(arg, "w", stdout) == NULL)  {
X				(void) fprintf(stderr, "Help! cant open %s\n", arg);
X				exit(20);
X			}
X			continue;
X		}
X	}
X}
X	
X/*
X *	Open binary files.  Arrange to erase them when finished.
X */
X
Xvoid	bfopen(nam, fid)
Xchar	*nam;
Xef_fid	fid;
X{
X	char	fnam[80];
X	
X	(void) sprintf(fnam, "%s.tx", nam);
X	if  ((fid->ef_t = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)  {
Xefil:		(void) fprintf(stderr, "Help could not open %s\n", fnam);
X		exit(4);
X	}
X	(void) unlink(fnam);
X	(void) sprintf(fnam, "%s.dt", nam);
X	if  ((fid->ef_d = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)
X		goto  efil;
X	(void) unlink(fnam);
X}
X
X/*
X *	Close binary files.  They should get zapped anyway.
X */
X
Xvoid	bfclose(fid)
Xef_fid	fid;
X{
X	(void) close(fid->ef_t);
X	(void) close(fid->ef_d);
X}
X
X/*
X *	Main routine.
X */
X
Xmain(argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int	i;
X	char	*progname = argv[0];
X	char	*msg;
X	register  struct  libit  *lfd;
X	
X	i = doopts(argv);
X	argc -= i;
X	argv += i;
X	
X	if  (argc < 2)  {
X		(void) fprintf(stderr, "Usage: %s [ options ] file\n", progname);
X		exit(1);
X	}
X	
X	lfd = getfnam(argv[1]);
X	if  (TYPE(lfd->ldptr) == ARTYPE)  {
X		(void) fprintf(stderr, "Main file (%s) cannot be library\n", argv[1]);
X		exit(2);
X	}
X	
X	bfopen(tfnam, &mainfile);
X	if  (verbose)
X		(void) fprintf(stderr, "Scanning text\n");
X	if  (!rtext(lfd->ldptr, &mainfile))  {
X		msg = "text";
Xbf:		(void) fprintf(stderr, "Bad format input file - reading %s\n", msg);
X		exit(5);
X	}
X	if  (verbose)
X		(void) fprintf(stderr, "Scanning data\n");
X	if  (!rdata(lfd->ldptr, &mainfile))  {
X		msg = "data";
X		goto  bf;
X	}
X	if  (verbose)
X		(void) fprintf(stderr, "Scanning symbols\n");
X	if  (!rsymb(lfd->ldptr, dosymb, &mainfile))  {
X		msg = "symbols";
X		goto  bf;
X	}
X	if  (verbose)
X		(void) fprintf(stderr, "Scanning for relocation\n");
X	if  ((rel = rrel(lfd->ldptr, lfd->ldptr2, &mainfile)) < 0)  {
X		msg = "reloc";
X		goto  bf;
X	}
X	
X	if  (rel)  {
X		if  (verbose)
X			(void) fprintf(stderr, "File is relocatable\n");
X		if  (argc > 2)
X			(void) fprintf(stderr, "Sorry - no scan on reloc files\n");
X	}
X	else
X		lscan(argc - 2, &argv[2]);
X
X	if  (verbose)
X		(void) fprintf(stderr, "End of input\n");
X	
X	ldaclose(lfd->ldptr2);
X	ldclose(lfd->ldptr);
X	if  (nmods > 0)
X		(void) fprintf(stderr, "Warning: at least %d merged modules\n",
X			nmods + 1);
X
X	if  (mainfile.ef_stvec != NULL)  {
X		free(mainfile.ef_stvec);
X		mainfile.ef_stvec = NULL;
X		mainfile.ef_stcnt = 0;
X	}
X	
X	if  (verbose)
X		(void) fprintf(stderr, "Text anal 1\n");
X	intutext();
X	if  (verbose)
X		(void) fprintf(stderr, "Data anal 1\n");
X	intudat(&mainfile);
X	if  (!rel)  {
X		if  (verbose)
X			(void) fprintf(stderr, "Data anal 2\n");
X		inturdat(&mainfile);
X	}
X	if  (lsyms)  {
X		if  (verbose)
X			(void) fprintf(stderr, "Local symbol scan\n");
X		intlsym();
X	}
X	pabs();
X	ptext(&mainfile);
X	pdata(&mainfile);
X	pbss(&mainfile);
X	bfclose(&mainfile);
X	exit(0);
X}
END_OF_FILE
if test 5877 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'prin.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prin.c'\"
else
echo shar: Extracting \"'prin.c'\" \(5515 characters\)
sed "s/^X//" >'prin.c' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)prin.c	1.2	11/2/84	14:19:47
X *	Print stuff.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X */
X
X#include <stdio.h>
X#include <a.out.h>
X#include <ldfcn.h>
X#include "unc.h"
X
X#define	LINELNG	70
X
Xvoid	gette(), getde();
Xlong	gettw(), getdw();
Xvoid	prinst();
X
Xchar	noabs;			/*  No non-global absolutes  */
Xint	rel;			/*  File being analysed is relocatable  */
Xint	lpos;
X
Xstruct	commit	abstab, comtab;
X
X/*
X *	Print absolute and common values.
X */
X
Xvoid	pabs()
X{
X	register  int	i;
X	register  symbol  cs;
X
X	for  (i = 0;  i < abstab.c_int;  i++)
X	
X	for  (i = 0;  i < abstab.c_int;  i++)  {
X		cs = abstab.c_symb[i];
X		if  (cs->s_glob)
X			(void) printf("\t.globl\t%s\n", cs->s_name);
X		else  if  (noabs)
X			continue;
X		(void) printf("%s\t=\t0x%lx\n", cs->s_name, cs->s_value);
X	}
X	for  (i = 0;  i < comtab.c_int;  i++)  {
X		cs = comtab.c_symb[i];
X		(void) printf("\t.comm\t%s,%d\n", cs->s_name, cs->s_value);
X	}
X}
X
X/*
X *	Print out labels.
X */
X
Xvoid	plabs(ls, seg)
Xregister  symbol  ls;
Xint	seg;
X{
X	for  (; ls != NULL;  ls = ls->s_link)  {
X		if  (ls->s_type != seg)
X			continue;
X		if  (ls->s_lsymb)  {
X			(void) printf("%u$:\n", ls->s_lsymb);
X			return;		/*  Set last  */
X		}
X		if  (ls->s_glob)
X			(void) printf("\n\t.globl\t%s", ls->s_name);
X		(void) printf("\n%s:\n", ls->s_name);
X	}
X}
X
X/*
X *	Print out text.
X */
X
Xvoid	ptext(fid)
Xregister  ef_fid  fid;
X{
X	register  long	tpos, endt;
X	t_entry	tstr;
X
X	(void) printf(".text\n");
X	
X	tpos = fid->ef_tbase;
X	endt = tpos + fid->ef_tsize;
Xcontin:	
X	for  (;  tpos < endt;  tpos += tstr.t_lng * 2)  {
X		gette(fid, tpos, &tstr);
X		plabs(tstr.t_lab, S_TEXT);
X		if  (tstr.t_type == T_BEGIN)
X			prinst(&tstr, tpos);
X		else  if  (tstr.t_relsymb != NULL)  {
X			(void) printf("\t.long\t%s", tstr.t_relsymb->s_name);
X			if  (tstr.t_relsymb->s_type!=S_TEXT &&
X				tstr.t_relsymb->s_type!=S_DATA)
X				(void) printf("+0x%x", gettw(fid, tpos, R_LONG));
X			putchar('\n');
X			tpos += 4;
X			goto  contin;
X		}
X		else
X			(void) printf("\t.word\t0x%x\n", tstr.t_contents);
X	}
X
X	/*
X	 *	Print out any trailing label.
X	 */
X	
X	gette(fid, tpos, &tstr);
X	plabs(tstr.t_lab, S_TEXT);
X}
X
X/*
X *	Print out data.
X */
X
Xvoid	pdata(fid)
Xregister  ef_fid  fid;
X{
X	register  long	dpos, endd;
X	register  int	lng;
X	unsigned  ctyp;
X	int	had, par, inc;
X	char	*msg;
X	d_entry	dstr;
X	
X	(void) printf("\n.data\n");
X	
X	dpos = fid->ef_dbase;
X	endd = dpos + fid->ef_dsize;
X
X	while  (dpos < endd)  {
X		
X		getde(fid, dpos, &dstr);
X		plabs(dstr.d_lab, S_DATA);
X			
X		switch  (dstr.d_type)  {
X		case  D_CONT:
X			(void) fprintf(stderr, "Data sync error\n");
X			exit(200);
X			
X		case  D_ASC:
X		case  D_ASCZ:
X			ctyp = dstr.d_type;
X			lng = dstr.d_lng;
X			(void) printf("\t.asci");
X			if  (ctyp == D_ASC)
X				(void) printf("i\t\"");
X			else  {
X				(void) printf("z\t\"");
X				lng--;
X			}
X				
X			while  (lng > 0)  {
X				getde(fid, dpos, &dstr);
X				switch  (dstr.d_contents)  {
X				default:
X					if  (dstr.d_contents < ' ' ||
X						dstr.d_contents > '~')
X						(void) printf("\\%.3o", dstr.d_contents);
X					else
X						putchar(dstr.d_contents);
X					break;
X				case  '\"':
X				case  '\'':
X				case  '\\':
X				case  '|':
X					(void) printf("\\%c", dstr.d_contents);
X					break;
X				case  '\b':
X					(void) printf("\\b");
X					break;
X				case  '\n':
X					(void) printf("\\n");
X					break;
X				case  '\r':
X					(void) printf("\\r");
X					break;
X				}
X				
X				lng--;
X				dpos++;
X			}
X			(void) printf("\"\n");
X			if  (ctyp == D_ASCZ)
X				dpos++;
X			break;
X
X		case  D_BYTE:
X			msg = "byte";
X			par = R_BYTE;
X			inc = 1;
X			goto  wrest;
X			
X		case  D_WORD:
X			msg = "word";
X			par = R_WORD;
X			inc = 2;
X			goto  wrest;
X			
X		case  D_LONG:
X			msg = "long";
X			par = R_LONG;
X			inc = 4;
X		wrest:
X			(void) printf("\t.%s\t", msg);
X			lng = dstr.d_lng;
X			lpos = 16;
X			had = 0;
X			while  (lng > 0)  {
X				if  (lpos > LINELNG)  {
X					(void) printf("\n\t.%s\t", msg);
X					lpos = 16;
X				}
X				else  if  (had)
X					lpos += printf(", ");
X
X				lpos += printf("0x%x", getdw(fid, dpos, par));
X				lng -= inc;
X				dpos += inc;
X				had++;
X			}
X			putchar('\n');
X			break;
X
X		case  D_ADDR:
X			(void) printf("\t.long\t");
X			lng = dstr.d_lng;
X			lpos = 16;
X			had = 0;
X			while  (lng > 0)  {
X				if  (lpos > LINELNG)  {
X					(void) printf("\n\t.long\t");
X					lpos = 16;
X				}
X				else  if  (had)
X					lpos += printf(", ");
X
X				getde(fid, dpos, &dstr);
X				lpos += printf("%s", dstr.d_relsymb->s_name);
X				lng -= sizeof(long);
X				dpos += sizeof(long);
X				had++;
X			}
X			putchar('\n');
X			break;
X		}
X	}
X	
X	/*
X	 *	Print trailing label.
X	 */
X	
X	getde(fid, dpos, &dstr);
X	plabs(dstr.d_lab, S_DATA);
X}
X
Xvoid	pbss(fid)
Xregister  ef_fid  fid;
X{
X	register  long	bpos = fid->ef_bbase;
X	long	endb = fid->ef_end;
X	d_entry	bstr;
X	
X	(void) printf("\n.bss\n");
X	
X	while  (bpos < endb)  {
X		getde(fid, bpos, &bstr);
X		plabs(bstr.d_lab, S_BSS);
X		(void) printf("\t.space\t%d\n", bstr.d_lng);
X		bpos += bstr.d_lng;
X	}
X	
X	getde(fid, endb, &bstr);
X	plabs(bstr.d_lab, S_BSS);
X}
END_OF_FILE
if test 5515 -ne `wc -c <'prin.c'`; then
    echo shar: \"'prin.c'\" unpacked with wrong size!
fi
# end of 'prin.c'
fi
if test -f 'robj.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'robj.c'\"
else
echo shar: Extracting \"'robj.c'\" \(18405 characters\)
sed "s/^X//" >'robj.c' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)robj.c	1.2	11/2/84	14:19:59
X *	Read object files.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X *
X *	This particular module will obviously have to be munged beyond
X *	recognition for another object format.
X */
X
X#include <stdio.h>
X#include <a.out.h>
X#include <ldfcn.h>
X#include <string.h>
X#include "unc.h"
X
Xvoid	gette(), getde(), setde(), putte(), putde();
Xlong	gettw(), getdw();
Xvoid	reallst(), lclash(), nomem(), unimpl();
Xvoid	addit();
Xchar	*malloc();
Xlong	lseek();
X
Xint	par_entry, par_round, nmods, donedrel, donebrel;
Xstruct	commit	abstab, comtab, dreltab;
Xlong	trelpos, drelpos, brelpos;
X
Xint *symord;	/* convert symbol index to symbol ordinal */
X
Xef_fids	mainfile;
X
Xsymbol	lookup(), inventsymb(), getnsymb();
X
X#define RWORD 1
X#define RLONG 2
X#define	DBSIZE	100
X#define	STINIT	20
X
X/*
X *	Read text segment.  Return 0 if not ok.
X */
X
Xint	rtext(ldptr, outf)
XLDFILE *ldptr;		/*  a.out file (possibly in library)  */
Xef_fid	outf;		/*  Output file descriptor  */
X{
X	t_entry		tstr;
X 	struct	aouthdr	unixhdr;
X	struct  scnhdr  sect;
X	register  long	size;
X	register  int	i, l;
X	unsigned  short	inbuf[DBSIZE/2];
X
X	/*
X	 *	Initialise fields in structure.
X	 */
X	
X	tstr.t_type = T_UNKNOWN;
X	tstr.t_vins = 1;		/*  For the moment  */
X	tstr.t_bdest = 0;
X	tstr.t_gbdest = 0;
X	tstr.t_lng = 1;
X	tstr.t_reloc = R_NONE;
X	tstr.t_rdisp = 0;
X	tstr.t_isrel = 0;
X	tstr.t_amap = 0;
X	tstr.t_dref = 0;
X	tstr.t_relsymb = NULL;
X	tstr.t_reldisp = 0;
X	tstr.t_lab = NULL;
X	tstr.t_lsymb = 0;
X	tstr.t_refhi = 0;
X	tstr.t_reflo = 0x7fffffff;
X	tstr.t_match = 0;
X	
X	/*
X	 *	Read a.out header.
X	 */
X
X	if (ldohseek(ldptr) == FAILURE) {	/* no optional header */
X
X	    outf->ef_entry = 0;
X	    ldshread(ldptr,1,&sect);		/* text header */
X	    outf->ef_tbase = sect.s_vaddr;
X	    outf->ef_tsize = sect.s_size;
X
X	    ldshread(ldptr,2,&sect);		/* data header */
X	    outf->ef_dbase = sect.s_vaddr;
X	    outf->ef_dsize = sect.s_size;
X
X	    ldshread(ldptr,3,&sect);		/* bss header */
X	    outf->ef_bbase = sect.s_vaddr;
X	    outf->ef_bsize = sect.s_size;
X	    outf->ef_end = sect.s_vaddr + sect.s_size;
X	} else {
X	    FREAD((char *)&unixhdr,sizeof(struct aouthdr),1,ldptr);
X	
X	    if ( N_BADMAG(unixhdr) )
X		return	0;
X
X	    outf->ef_entry = unixhdr.entry;
X	    outf->ef_tbase = unixhdr.text_start;
X	    outf->ef_dbase = unixhdr.data_start;
X	    outf->ef_bbase = outf->ef_dbase + unixhdr.dsize;
X	    outf->ef_end = outf->ef_bbase + unixhdr.bsize;
X
X	    outf->ef_tsize = unixhdr.tsize;
X	    outf->ef_dsize = unixhdr.dsize;
X	    outf->ef_bsize = unixhdr.bsize;
X	}
X	
X	ldsseek(ldptr,1);	/* seek to text section */
X	
X	size = outf->ef_tsize;
X	
X	while  (size > 1)  {
X		l = size > DBSIZE? DBSIZE: size;
X		if  (FREAD((char *)inbuf,1,l,ldptr) != l)
X			return	0;
X		l /= 2;
X		for  (i = 0;  i < l;  i++)  {
X			tstr.t_contents = inbuf[i];
X			(void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
X		}
X		size -= l + l;
X	}
X	
X	/*
X	 *	Extra one to cope with "etext".
X	 */
X	
X	(void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
X	return	1;
X}
X/*
X *	Same sort of thing for the data segment.
X */
X
Xint	rdata(ldptr, outf)
XLDFILE *ldptr;		/*  a.out file (possibly in library)  */
Xef_fid	outf;		/*  Output file descriptor  */
X{
X	d_entry		dstr;
X	register  long	size;
X	register  int	i, l;
X	unsigned  char	inbuf[DBSIZE];
X
X	/*
X	 *	Initialise fields in structure.
X	 */
X	
X	dstr.d_type = D_BYTE;
X	dstr.d_reloc = R_NONE;
X	dstr.d_lng = 1;
X	dstr.d_relsymb = NULL;
X	dstr.d_reldisp = 0;
X	dstr.d_lab = NULL;
X	
X	ldsseek(ldptr,2);	/* seek to data section */
X	
X	size = outf->ef_dsize;
X	
X	while  (size > 0)  {
X		l = size > DBSIZE? DBSIZE: size;
X		if  (FREAD((char *)inbuf,1,l,ldptr) != l)
X			return	0;
X		for  (i = 0;  i < l;  i++)  {
X			dstr.d_contents = inbuf[i];
X			(void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
X		}
X		size -= l;
X	}
X	
X	/*
X	 *	Repeat for BSS segment.
X	 */
X
X	dstr.d_contents = 0;
X	for  (size = outf->ef_bsize;  size > 0;  size--)
X		(void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
X	
X	/*
X	 *	Extra one to cope with "end".
X	 */
X	
X	(void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
X	return	1;
X}
X
X/*
X *	Process symbol table segment.
X */
X
Xint	rsymb(ldptr, dproc, outf)
XLDFILE *ldptr;		/*  a.out file (possibly in library)  */
Xsymbol	(*dproc)();
Xregister  ef_fid  outf;	/*  Output file descriptor  */
X{
X#define SYMLENGTH 256
X	register  symbol  csym;
X 	struct	syment	isym;
X	register  int   nsyms,symindex;
X	unsigned long   stroff;
X 	char	inbuf[SYMLENGTH+1], *cp;
X	int ord;
X
X	nsyms = HEADER(ldptr).f_nsyms;
X	stroff = HEADER(ldptr).f_symptr + nsyms*sizeof(struct syment);
X
X	if  (nsyms <= 0)
X		nsyms = STINIT;
X
X	outf->ef_stvec = (symbol *) malloc(nsyms * sizeof(symbol));
X	symord = (int *) malloc(nsyms * sizeof(int));
X	if  (outf->ef_stvec == NULL)
X		nomem();
X
X	outf->ef_stcnt = 0;
X	outf->ef_stmax = nsyms;
X	ord = 0;
X	
X 	for  (symindex=0; symindex<nsyms; symindex++)  {
X		ldtbread(ldptr,symindex,&isym);
X		if (isym.n_zeroes == 0) {	/* get from string table */
X		    FSEEK(ldptr,stroff + isym.n_offset,0);
X		    cp = inbuf;
X		    do {
X 			if (FREAD(cp,1,1,ldptr) != 1)/* Read symbol chars 1-by-1 */
X 				return 0;
X 			if ( cp - inbuf >= SYMLENGTH )/* Check against buffer overflow */
X 				return 0;
X		    } while (*cp++ != '\0');/* Terminate on null byte */
X		} else {			/* get from symbol field */
X		    strncpy(inbuf,isym.n_name,8);
X		    inbuf[8] = '\0';
X		}
X 		csym = (*dproc)(lookup(inbuf), convtosun(&isym),
X				isym.n_value, outf);
X 		if (outf->ef_stcnt >= outf->ef_stmax)
X			reallst(outf);
X		outf->ef_stvec[outf->ef_stcnt++] = csym;
X		symord[symindex] = ord++;		/* record ordinal */
X		symindex += isym.n_numaux;		/* skip aux entries */
X	}
X	return	1;
X}
X
X/*
X *	Process relocation stuff.  -1 error, 0 no relocation, 1 relocation.
X */
X
Xint	rrel(ldptr, ldptr2, outf)
XLDFILE *ldptr,*ldptr2;	/*  a.out file (possibly in library)  */
Xef_fid	outf;		/*  Output file descriptor  */
X{
X 	struct	reloc	crel;
X	struct scnhdr tsect,dsect;
X	struct syment isym;
X	t_entry	tstr;
X	d_entry	dstr;
X	register  int	nreloc;
X	long	cont, pos;
X
X	ldshread(ldptr,1,&tsect);
X	ldshread(ldptr,2,&dsect);
X 	if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
X		return	0;
X
X	nreloc = tsect.s_nreloc;
X
X	ldrseek(ldptr,1);
X 	while  (nreloc-- > 0)  {
X		if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
X			return	-1;
X
X 		pos = crel.r_vaddr;
X		gette(outf, pos, &tstr);
X		if (crel.r_type == R_ABS)
X		    tstr.t_reloc = R_NONE;
X		else
X		    tstr.t_reloc = R_LONG;	/* what about PC-relative? */
X		ldtbread(ldptr2,crel.r_symndx,&isym);
X		if (isym.n_sclass == C_EXT) {
X 			tstr.t_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
X 			tstr.t_reldisp = gettw(outf, pos, (int)tstr.t_reloc);
X		}
X		else  {
X 			cont = gettw(outf, pos, (int)tstr.t_reloc);
X 			tstr.t_relsymb = getnsymb(outf, convtosun(&isym), cont);
X		}
X		tstr.t_relsymb->s_used++;
X		putte(outf, pos, &tstr);
X	}
X	
X	/*
X	 *	And now repeat all that for data relocations.
X	 */
X	
X	nreloc = dsect.s_nreloc;
X	
X	ldrseek(ldptr,2);
X 	while  (nreloc-- > 0)  {
X		if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
X			return	-1;
X
X 		pos = crel.r_vaddr;
X		getde(outf, pos, &dstr);
X		if (crel.r_type == R_ABS)
X		    dstr.d_reloc = R_NONE;
X		else
X		    dstr.d_reloc = R_LONG;	/* what about PC-relative? */
X
X		ldtbread(ldptr2,crel.r_symndx,&isym);
X		if (isym.n_sclass == C_EXT) {
X 			dstr.d_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
X 			dstr.d_reldisp = getdw(outf, pos, (int)dstr.d_reloc);
X		}
X		else  {
X 			cont = getdw(outf, pos, (int)dstr.d_reloc);
X 			dstr.d_relsymb = getnsymb(outf, convtosun(&isym), cont);
X 			if  (dstr.d_relsymb->s_type == S_TEXT)  {
X				gette(outf, cont, &tstr);
X				tstr.t_dref = 1;
X				putte(outf, cont, &tstr);
X			}
X		}
X 		switch  (dstr.d_reloc)  {
X		default:
X			unimpl("Data byte relocation");
X			break;
X		case  R_WORD:
X			unimpl("data word reloc");
X			dstr.d_type = D_WORD;
X			dstr.d_lng = 2;
X			setde(outf, pos+1, D_CONT, 1);
X			break;
X		case  R_LONG:
X			dstr.d_type = D_ADDR;
X			dstr.d_lng = 4;
X			setde(outf, pos+1, D_CONT, 1);
X			setde(outf, pos+2, D_CONT, 1);
X			setde(outf, pos+3, D_CONT, 1);
X			break;
X		}
X		dstr.d_relsymb->s_used++;
X		putde(outf, pos, &dstr);
X	}
X	return 1;
X}
X
X/*
X *	Process a symbol.
X */
X
Xsymbol	dosymb(sy, type, val, fid)
Xregister  symbol  sy;
Xint	type;
Xlong	val;
Xef_fid	fid;
X{
X	t_entry	tstr;
X	d_entry	dstr;
X	
X	if  (!sy->s_newsym)  {
X 		if  (type & S_EXT)  {
X			(void) fprintf(stderr, "Duplicate symbol %s\n", sy->s_name);
X			/* exit(10);  temporary? */
X		}
X		if  (++sy->s_defs > nmods)
X			nmods = sy->s_defs;
X		sy = inventsymb("DUP");
X	}
X
X	sy->s_value = val;
X	
X	switch  (type)  {
X	default:
X		return	NULL;
X		
X 	case  S_EXT|S_UNDF:
X		if  (val != 0)  {
X 			sy->s_type = S_COMM;
X			addit(&comtab, sy);
X		}
X		else
X			sy->s_type = S_UNDF;
X		sy->s_glob = 1;
X		break;
X		
X 	case  S_EXT|S_ABS:
X		sy->s_type = S_ABS;
X		sy->s_glob = 1;
X		addit(&abstab, sy);
X		break;
X		
X 	case  S_ABS:
X		sy->s_type = S_ABS;
X		addit(&abstab, sy);
X		break;
X		
X 	case  S_EXT|S_TEXT:
X 	case  S_TEXT:
X		sy->s_type = S_TEXT;
X		gette(fid, val, &tstr);
X		tstr.t_bdest = 1;
X 		if  (type & S_EXT)  {
X			tstr.t_gbdest = 1;
X			sy->s_glob = 1;
X		}
X		sy->s_link = tstr.t_lab;
X		tstr.t_lab = sy;
X		putte(fid, val, &tstr);
X		break;
X		
X 	case  S_BSS:
X 	case  S_EXT|S_BSS:
X		sy->s_type = S_BSS;
X		goto	datrest;
X 	case  S_DATA:
X 	case  S_EXT|S_DATA:
X		sy->s_type = S_DATA;
X	datrest:
X		getde(fid, val, &dstr);
X 		if  (type & S_EXT)
X			sy->s_glob = 1;
X		sy->s_link = dstr.d_lab;
X		dstr.d_lab = sy;
X		putde(fid, val, &dstr);
X		break;
X	}
X	
X	sy->s_newsym = 0;
X	return	sy;
X}
X
X
X/*
X *	Process relocation stuff in putative library modules.
X *	The main function of all this is to mark which bits of the text
X *	not to look at as I compare the stuff.
X *
X *	As with "rrel", return -1 error, 0 no relocation, 1 relocation.
X */
X
Xint	rrell1(ldptr, outf)
XLDFILE *ldptr;		/*  a.out file (possibly in library)  */
Xef_fid	outf;		/*  Output file descriptor  */
X{
X 	struct	reloc	crel;
X	struct scnhdr tsect,dsect;
X	t_entry	tstr;
X	register  int	nreloc;
X	long	pos;
X
X	ldshread(ldptr,1,&tsect);
X	ldshread(ldptr,2,&dsect);
X 	if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
X		return	0;
X
X	nreloc = tsect.s_nreloc;
X
X	ldrseek(ldptr,1);
X 	while  (nreloc-- > 0)  {
X		if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
X			return	-1;
X
X 		pos = crel.r_vaddr;
X		gette(outf, pos, &tstr);
X		if (crel.r_type == R_ABS)
X		    tstr.t_reloc = R_NONE;
X		else
X		    tstr.t_reloc = R_LONG;	/* what about PC-relative? */
X		tstr.t_isrel = 1;
X		putte(outf, pos, &tstr);
X 		if  (tstr.t_reloc == R_LONG)  {
X			gette(outf, pos+2, &tstr);
X			tstr.t_isrel = 1;
X			putte(outf, pos+2, &tstr);
X		}
X	}
X	
X	/*
X	 *	Dont bother with data relocation at this stage. We'll
X	 *	tie that up later.
X	 */
X	
X	return 1;
X}
X
X/*
X *	Process a symbol in library file.  The extern variable trelpos gives
X *	the place in the main file where the library module is relocated.
X *	We don't know the data position until we do the final merge, perhaps
X *	not even then.
X */
X/* trelpos ??? */
X
Xsymbol	dolsymb(sy, type, val, fid)
Xregister  symbol  sy;
Xint	type;
Xlong	val;
Xef_fid	fid;
X{
X	t_entry	tstr;
X	
X	switch  (type)  {
X	default:
X		return	NULL;
X		
X 	case  S_EXT|S_UNDF:
X		if  (!sy->s_newsym)
X			return	sy;
X		sy->s_value = val;
X		if  (val != 0)  {
X 			sy->s_type = S_COMM;
X			addit(&dreltab, sy);
X		}
X		else
X			sy->s_type = S_UNDF;
X		sy->s_glob = 1;
X		break;
X		
X 	case  S_EXT|S_ABS:
X		if  (!sy->s_newsym)  {
X			if  (sy->s_type != S_ABS || sy->s_value != val)
X				lclash("abs");
X		}
X		sy->s_type = S_ABS;
X		sy->s_value = val;
X		sy->s_glob = 1;
X		addit(&abstab, sy);
X		break;
X		
X 	case  S_EXT|S_TEXT:
X		sy->s_type = S_TEXT;
X		val += trelpos - fid->ef_tbase;
X		if  (!sy->s_newsym)  {
X			if  (val != sy->s_value)
X				lclash("tsym");
X			return	sy;
X		}
X		sy->s_value = val;
X		gette(&mainfile, val, &tstr);
X		tstr.t_bdest = 1;
X		tstr.t_gbdest = 1;
X		sy->s_glob = 1;
X		sy->s_link = tstr.t_lab;
X		tstr.t_lab = sy;
X		putte(&mainfile, val, &tstr);
X		break;
X
X 	case  S_EXT|S_BSS:
X		if  (!sy->s_newsym)
X			return	sy;
X		sy->s_type = S_BSS;
X		sy->s_value = val - fid->ef_bbase;
X		goto	datrest;
X
X 	case  S_EXT|S_DATA:
X		if  (!sy->s_newsym)
X			return	sy;
X		sy->s_type = S_DATA;
X		sy->s_value = val - fid->ef_dbase;
X	datrest:
X		sy->s_glob = 1;
X		addit(&dreltab, sy);
X		break;
X	}
X	
X	sy->s_newsym = 0;
X	return	sy;
X}
X
X/*
X *	Change definition of undefined symbol as we define it.
X */
X
Xvoid	reassign(sy, val)
Xregister  symbol  sy;
Xlong	val;
X{
X	sy->s_value = val;
X
X	if  (val < mainfile.ef_tbase)  {
X		sy->s_type = S_ABS;
X		addit(&abstab, sy);
X	}
X	else  if  (val < mainfile.ef_dbase)  {
X		t_entry	tstr;
X		
X		sy->s_type = S_TEXT;
X		gette(&mainfile, val, &tstr);
X		tstr.t_bdest = 1;
X		tstr.t_gbdest = 1;
X		sy->s_glob = 1;
X		sy->s_link = tstr.t_lab;
X		tstr.t_lab = sy;
X		putte(&mainfile, val, &tstr);
X	}
X	else  {
X		d_entry dstr;
X		
X		sy->s_type = val < mainfile.ef_bbase? S_DATA: S_BSS;
X		getde(&mainfile, val, &dstr);
X		sy->s_link = dstr.d_lab;
X		dstr.d_lab = sy;
X		putde(&mainfile, val, &dstr);
X	}
X}
X
X/*
X *	When we discover where bss or data come, reallocate the table.
X */
X
Xvoid	zapdat(seg, inc)
Xint	seg;
Xlong	inc;
X{
X	register  int	i;
X	register  symbol  csymb;
X	d_entry	dent;
X	
X	for  (i = 0;  i < dreltab.c_int;  i++) {
X		csymb = dreltab.c_symb[i];
X		if  (csymb->s_type != seg)
X			continue;
X		csymb->s_value += inc;
X		getde(&mainfile, csymb->s_value, &dent);
X		csymb->s_link = dent.d_lab;
X		dent.d_lab = csymb;
X		putde(&mainfile, csymb->s_value, &dent);
X	}
X}
X
X/*
X *	Process relocation stuff in library module which we are inserting.
X *	Horrors if something goes wrong.
X */
X/* trelpos, drelpos ??? */
X
Xrrell2(ldptr, ldptr2, outf)
XLDFILE *ldptr,*ldptr2;	/*  a.out file (possibly in library)  */
Xef_fid	outf;		/*  Output file descriptor  */
X{
X 	struct	reloc	crel;
X	t_entry	mtstr;
X	d_entry	mdstr;
X	struct scnhdr tsect,dsect;
X	struct syment isym;
X	int nreloc;
X	unsigned rtype;
X	register  long	size;
X	register  symbol  csymb;
X	long	pos, mpos, mval, lval;
X	int	dhere = 0;		/*  Mark whether bss done  */
X
X	ldshread(ldptr,1,&tsect);
X	ldshread(ldptr,2,&dsect);
X 	if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
X		return	0;
X
X	nreloc = tsect.s_nreloc;
X
X	ldrseek(ldptr,1);
X 	while  (nreloc-- > 0)  {
X		if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
X			lclash("rd trel");
X
X 		pos = crel.r_vaddr;
X 		mpos = crel.r_vaddr + trelpos;
X		gette(&mainfile, mpos, &mtstr);
X		if (crel.r_type == R_ABS)
X		    rtype = R_NONE;
X		else
X		    rtype = R_LONG;	/* what about PC-relative? */
X		ldtbread(ldptr2,crel.r_symndx,&isym);
X 		lval = gettw(outf, pos, (int)rtype);
X 		mval = gettw(&mainfile, mpos, (int)rtype);
X		
X		if ( isym.n_sclass != C_EXT ) {
X		switch (convtosun(&isym)) {
X 		case  S_TEXT:
X			if  (lval + trelpos - outf->ef_tbase != mval)
X				lclash("Trel");
X			continue;
X 		case  S_DATA:
X			if  (donedrel)  {
X				if  (lval + drelpos - outf->ef_dbase != mval)
X					lclash("Drel");
X			}
X			else  {
X				donedrel++;
X				drelpos = mval - lval + outf->ef_dbase;
X			}
X			continue;
X 		case  S_BSS:
X			if  (donebrel)  {
X				if  (lval + brelpos - outf->ef_bbase != mval)
X					lclash("brel");
X			}
X			else  {
X				donebrel++;
X				brelpos = mval - lval + outf->ef_bbase;
X			}
X			continue;
X 		      }
X 	      } else {
X 			if  (crel.r_symndx >= outf->ef_stcnt)
X				lclash("Bad sy no");
X 			csymb = outf->ef_stvec[symord[crel.r_symndx]];
X			if  (csymb == NULL)
X				continue;
X			switch  (csymb->s_type)  {
X			case  S_UNDF:
X				reassign(csymb, mval - lval);
X				break;
X			case  S_ABS:
X				if  (lval + csymb->s_value != mval)
X					lclash("abs rel");
X				break;
X			case  S_TEXT:
X				if  (lval + csymb->s_value != mval)
X					lclash("text rel");
X				break;
X			case  S_DATA:
X				if  (lval + csymb->s_value != mval)
X					lclash("data rel");
X				break;
X			case  S_BSS:
X				if  (lval + csymb->s_value != mval)
X					lclash("bss rel");
X				break;
X 			case  S_COMM:
X				reassign(csymb, mval - lval);
X				break;
X			}
X			mtstr.t_relsymb = csymb;
X			mtstr.t_reldisp = lval;
X		}
X	}
X	
X	/*
X	 *	Relocate data and bss if possible.
X	 */
X	
X	if  (donebrel)  {
X		zapdat(S_BSS, brelpos);
X		dhere++;
X	}
X	
X	if  (!donedrel)
X		return;
X		
X
X	zapdat(S_DATA, drelpos);
X	
X	/*
X	 *	And now repeat all that for data relocations if possible
X	 */
X	
X	nreloc = tsect.s_nreloc;
X
X	ldrseek(ldptr,2);
X	
X	while (nreloc-- > 0) {
X		if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
X			lclash("Rd drel");
X
X 		if  (crel.r_type == R_ABS)
X			continue;
X
X 		pos = crel.r_vaddr;
X 		mpos = crel.r_vaddr + drelpos;
X		getde(&mainfile, mpos, &mdstr);
X		rtype = R_LONG;		/* what about PC-relative? */
X		ldtbread(ldptr2,crel.r_symndx,&isym);
X
X 		lval = getdw(outf, pos, (int)rtype);
X 		mval = getdw(&mainfile, mpos, (int)rtype);
X		if ( isym.n_sclass != C_EXT ) {
X		switch (convtosun(&isym)) {
X 		case  S_TEXT:
X			if  (lval + trelpos - outf->ef_tbase != mval)
X				lclash("Trel-d");
X			continue;
X 		case  S_DATA:
X			if  (lval + drelpos - outf->ef_dbase != mval)
X				lclash("Drel-d");
X			continue;
X 		case  S_BSS:
X			if  (donebrel)  {
X				if  (lval + brelpos - outf->ef_bbase != mval)
X					lclash("brel");
X			}
X			else  {
X				donebrel++;
X				brelpos = mval - lval + outf->ef_bbase;
X			}
X			continue;
X 		      }
X 	      } else { 
X 			if  (crel.r_symndx >= outf->ef_stcnt)
X				lclash("Bad sy no");
X 			csymb = outf->ef_stvec[symord[crel.r_symndx]];
X			if  (csymb == NULL)
X				continue;
X			switch  (csymb->s_type)  {
X			case  S_UNDF:
X				reassign(csymb, mval - lval);
X				break;
X			case  S_ABS:
X				if  (lval + csymb->s_value != mval)
X					lclash("abs rel");
X				break;
X			case  S_TEXT:
X				if  (lval + csymb->s_value != mval)
X					lclash("text rel");
X				break;
X			case  S_DATA:
X				if  (lval + csymb->s_value != mval)
X					lclash("data rel");
X				break;
X			case  S_BSS:
X				if  (lval + csymb->s_value != mval)
X					lclash("bss rel");
X				break;
X 			case  S_COMM:
X				reassign(csymb, mval - lval);
X				break;
X			}
X			mtstr.t_relsymb = csymb;
X			mtstr.t_reldisp = lval;
X		}
X	}
X
X	if  (dhere || !donebrel)
X		return;
X
X	zapdat(S_BSS, brelpos);
X}
END_OF_FILE
if test 18405 -ne `wc -c <'robj.c'`; then
    echo shar: \"'robj.c'\" unpacked with wrong size!
fi
# end of 'robj.c'
fi
if test -f 'unc.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unc.h'\"
else
echo shar: Extracting \"'unc.h'\" \(5112 characters\)
sed "s/^X//" >'unc.h' <<'END_OF_FILE'
X/*
X *	SCCS:	@(#)unc.h	1.2	11/2/84	14:21:02
X *	Header file for uncompile program.
X *
X ***********************************************************************
X *	This software is copyright of
X *
X *		John M Collins
X *		47 Cedarwood Drive
X *		St Albans
X *		Herts, AL4 0DN
X *		England			+44 727 57267
X *
X *	and is released into the public domain on the following conditions:
X *
X *		1.  No free maintenance will be guaranteed.
X *		2.  Nothing may be based on this software without
X *		    acknowledgement, including incorporation of this
X *		    notice.
X *
X *	Notwithstanding the above, the author welcomes correspondence and bug
X *	fixes.
X ***********************************************************************
X */
X
X#define	MAXCHARS	50
X#define	HASHMOD		97
X
X/*
X *	The following structure is used to keep track of symbols.
X */
X
Xstruct	symstr	{
X	struct	symstr	*s_next;		/*  Next in hash chain  */
X	struct	symstr	*s_link;		/*  Next in duplicate labels */
X	unsigned	s_type	:  5;		/*  Symbol type  */
X	unsigned	s_newsym:  1;		/*  A new symbol  */
X	unsigned	s_invent:  1;		/*  Invented symbol  */
X	unsigned	s_glob	:  1;		/*  Global symbol  */
X	long		s_value;		/*  Value if defined  */
X	short		s_defs;			/*  Defined count  */
X	short		s_used;			/*  Used count  */
X	unsigned short	s_lsymb;		/*  Local symbol  */
X	char		s_name[1];		/*  Chars of name null term */
X};
X
Xtypedef	struct	symstr	*symbol;
X
Xsymbol	symbhash[HASHMOD];
X
Xtypedef	struct	{
X	int	ef_t;			/*  Text file fd  */
X	int	ef_d;			/*  Data file fd  */
X	long	ef_entry;		/*  Entry point  */
X	long	ef_tsize;		/*  Text size  */
X	long	ef_dsize;		/*  Data size  */
X	long	ef_bsize;		/*  Bss size  */
X	long	ef_end;			/*  End of it all  */
X	long	ef_tbase;		/*  Text base  */
X	long	ef_dbase;		/*  Data base  */
X	long	ef_bbase;		/*  Bss base  */
X	int	ef_stcnt;		/*  Number of symbols  */
X	int	ef_stmax;		/*  Max number of symbols  */
X	symbol	*ef_stvec;		/*  Symbol vector  */
X}  ef_fids;
X
Xtypedef	ef_fids	*ef_fid;
X
X/*
X *	Description of word in text file.  This entry is held in the place
X *	corresponding to the address in the text file.
X */
X
Xtypedef	struct	{
X	unsigned  short	t_contents;		/*  Actual contents  */
X	unsigned  short t_iindex;		/*  Index in table  */
X	unsigned	t_type	:  2;		/*  Type  */
X	unsigned	t_vins  :  1;		/*  Valid instruction  */
X	unsigned	t_bdest	:  1;		/*  Is branch dest  */
X	unsigned	t_gbdest:  1;		/*  Is global dest  */
X	unsigned	t_dref	:  1;		/*  Refered to in data  */
X	unsigned	t_bchtyp:  2;		/*  Branch type  */
X	unsigned	t_lng	:  3;		/*  Length in words  */
X	unsigned	t_reloc :  2;		/*  Relocatable  */
X	unsigned	t_rptr	:  2;		/*  Where relocated  */
X	unsigned	t_rdisp :  1;		/*  Relocatable displacement */
X	unsigned	t_isrel :  1;		/*  Relocated  */
X	unsigned	t_amap	:  1;		/*  Worked out  */
X	symbol		t_relsymb;		/*  Relocation symbol  */
X	long		t_reldisp;		/*  Offset + or - from symb */
X	symbol		t_lab;			/*  Label  */
X	unsigned  short	t_lsymb;		/*  Local symbol  */
X	long		t_reflo;		/*  Lowest place referred  */
X	long		t_refhi;		/*  Highest place referred  */
X	unsigned  short	t_match;		/*  Lib match lng  */
X}  t_entry;
X
X/*
X *	Types ......
X */
X
X#define	T_UNKNOWN	0
X#define	T_BEGIN		1
X#define	T_CONT		2
X
X#define	R_NONE		0		/*  No relocation  */
X#define	R_BYTE		1		/*  Byte relocation  */
X#define	R_WORD		2		/*  Word relocation  */
X#define	R_LONG		3		/*  Long relocation  */
X
X/*
X *	Branch types.
X */
X
X#define	T_NOBR		0
X#define	T_CONDBR	1
X#define	T_UNBR		2
X#define	T_JSR		3
X
Xtypedef	struct	{
X	unsigned  char	d_contents;		/*  Actual contents  */
X	unsigned	d_type  :  4;		/*  Data type  */
X	unsigned	d_reloc :  2;		/*  Relocatable  */
X	unsigned	d_rptr	:  2;		/*  Where relocated  */
X	short		d_lng;			/*  Length -ve for D_CONT */
X	symbol		d_relsymb;		/*  Relocation symbol  */
X	long		d_reldisp;		/*  Offset + or - from symb */
X	symbol		d_lab;			/*  Label  */
X}  d_entry;
X
X/*
X *	Data types.
X */
X
X#define	D_ASC		0		/*  Ascii chars  */
X#define	D_ASCZ		1		/*  Null-term ascii  */
X#define	D_BYTE		2		/*  Decimal bytes  */
X#define	D_WORD		3		/*  Words  */
X#define	D_LONG		4		/*  Longs  */
X#define	D_ADDR		5		/*  Address pointer  */
X#define	D_CONT		6		/*  Continuation of last  */
X
X/*
X *	'Common' items.
X */
X
Xstruct	commit	{
X	symbol	*c_symb;		/*  List of symbols  */
X	int	c_int;			/*  Current number  */
X	int	c_max;			/*  Maximum  */
X};
X
X/*
X *	Library file description.
X */
X
Xstruct	libit	{
X	LDFILE *ldptr,*ldptr2;		/*  independent file pointer packages
X					    for the same file */
X	char	lf_name[14];		/*  Name of item  */
X};
X
X/* magic number stuff like Sun */
X#define OMAGIC 0407
X#define NMAGIC 0410
X#define ZMAGIC 0413
X#define N_BADMAG(x) \
X    (((x).magic)!=OMAGIC && ((x).magic)!=NMAGIC && ((x).magic)!=ZMAGIC)
X
X/* definitions of type for Sun -- used for symstr.type, d_entry.d_rptr */
X#define S_UNDF 0x0		/* undefined */
X#define S_ABS  0x2		/* absolute */
X#define S_TEXT 0x4		/* text */
X#define S_DATA 0x6		/* data */
X#define S_BSS  0x8		/* bss */
X#define S_COMM 0x12		/* common (internal to ld) */
X#define S_FN   0x1f		/* file name symbol */
X#define S_EXT  01		/* external bit, or'ed in */
X#define S_TYPE 0x1e		/* mask for all the type bits */
END_OF_FILE
if test 5112 -ne `wc -c <'unc.h'`; then
    echo shar: \"'unc.h'\" unpacked with wrong size!
fi
# end of 'unc.h'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    echo "Read the README* files for more info"
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems       [work] +1 (516) 582-5525
lenny at icus.islp.ny.us      Telex: 154232428 ICUS       [home] +1 (516) 968-8576
{talcott,boulder,hombre,pacbell,sbcs}!icus!lenny       attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752



More information about the Unix-pc.sources mailing list