Subject: Object file symbols limited to 8 characters [+FIX] (#162 - #5 of 19)
Index:	cc,as,ld,ar,ranlib,nm,nlist,adb,... (2.11BSD)

Description:
	For some time now (seem like eons;-)) the object file format used 
	by Unix for the PDP-11 has restricted symbols to 8 significant 
	characters (actually 7 due to the C compiler prefixing symbols with 
	a leading tilde (~) or underscore (_)).

	Aside from the "creative constraints" this imposes on the programmer
	there was the continuing problem of 'name collisions', especially
	when porting applications from machines whose object file format
	permitted longer symbol names.

	Numerous workarounds have been employed in the past.  The
	most common one relied on a combination of a name collision
	detection program ('shortc') and the flexname capability of the
	C preprocessor ('cpp').  This served to mask the problem while
	making debugging difficult due to mangled/synthetic symbol names.

Repeat-By:
	Attempt to compile the following program:

		int	this_is_a_long_name;
		int	this_is_a_long_name_too;

		main() { exit(0)};

Fix:
	This section is repeated in each of the 19 parts which make up
	the update kit.  You should read it perhaps once or twice, but
	then skip over it (how to do that is mentioned below).

	Taking a "hint" from the a.out(5) man page:

"The compiler will note name collisions when they occur within a single file...
There is really little that can be done about this.  Some thought is being
given to modifying the loader to flag detectable collisions, but the real
solution would be to change over to the 4BSD a.out format.  This would 
involve modifying the compiler, assembler and adb and then simply porting 
the 4.3BSD ld, nm, ranlib, strip and nlist.  Or perhaps simply porting the 
entire 4.3BSD suite might be best ...  Anyone interested in a project?"

	This I have done.  No more volunteers for the project need apply ;-)

	The new limit on symbol length is 32 characters!  There is still
	a limit (but it is _much_ more reasonable now) simply because of
	address space constraints - it needs to be possible to hold 
	at least one of the 'symbol' or 'string' tables in memory in many
	cases (nice to hold both, but - i know, get a 486;-)).

	It must be noted though that it is almost trivial now to raise
	the limit if that is desired - the programs which need to know
	the maximum length of a symbol string all have an easily changed
	#define statement now (usually MAXSYMLEN but there are a couple
	exceptions).  The 'string table' format itself doesn't care how 
	long the strings are.  The actual a.out format won't have to 
	change again to accomodate a higher limit on symbol name length!

	The "string table" object file format has been ported and all
	the necessary changes made throughout the entire system.

	The changes were *massive* and widespread.  Programs affected
	of course included the assembler and compiler.  Other programs
	affected were anything which accessed a symbol table entry either
	via nlist(3) [ps, pstat, fstat, vmstat, etc] or by reading
	object files [ld, ranlib, nm, adb, strip, etc].

	The actual changes to the compiler and assembler were minor
	because those programs had already been modified earlier 
	(updates #142, 143, 152, 153).  The compiler only needed to have
	the maximum size of a symbol name raised.  The assembler
	already knew how to generate 'string table' object files - all
	that needed to be done in 'as' was to flip a bit telling it
	to generate the new object format instead of the old style.

	+++++++++++++++
	And now for a bit of a narrative about what was done.   The
	detailed instructions for applying this part (#5 of 19) of the
	update kit follow the 'story' below.  This started out as
	a semi-organized accounting of what was done but then devolved
	into a semi-rambling tale due to the sheer bulk of the changes.

	You can skip to the details for applying #162 by searching for
	the string "=======" below - this header is replicated in all
	parts of this kit.
	+++++++++++++++

	Alas, the remaining changes were not so simple.  Complete
	replacements for ranlib(1), ar(1), nlist(3) were ported from
	the Net-2 release.  Other programs such as symorder(1) and
	two new programs 'symcompact' and 'strcompact' (used to
	compress/compact symbol and string tables) were written from
	scratch.

	Perhaps the two hardest parts of the whole effort were
	rewriting the linker 'ld' and making *large* modifications
	to the debugger 'adb'.  This was a very difficult job.
	'ld needed to scan new style ranlib archives, as well as
	using the "virtual memory" facility (the 'libvmf' routines 
	posted earlier) for symbol table management and so on.  'adb'
	was a MESS (having been written in a pseudo block structured
	macro language).  Since the new symbol table entry could be
	so much larger than the old it was no longer possible for adb
	to hold as much of the symbol table in memory - an alternate 
	method took a while to develope and implement, more on that
	in the patch which deals with adb (actually the changes to
	adb are so large there are two substantial parts of this update
	kit just for adb!).

	After the basic programs (ar, ld, ranlib, etc) were running
	the system had to be completely recompiled from sources, beginning
	with the object libraries.  After those were done the process
	of recompiling the rest of the system could proceed.

	Guess what happens when you recreate libc.a with a buggy linker?
	Yep - the system is rendered useless until backup copies of
	everything can be reloaded.  Don't let this happen to you - be
	sure (and i'll repeat the point later) to back up the system
	(or at least key executables and .a files) before installing
	this upgrade.

	In all there were about 330 files modified during the change of
	object file format.  Some of these were not directly related
	to the new object file format.  There were a number of (obsolete)
	references to "BSD2_10" lingering in the system.  Those 
	have been replaced with "pdp11" and the 'BSD2_10' define has
	been removed from the C preprocessor (cpp).  DO NOT use 'BSD2_10'
	to #ifdef pdp-11 sensitive code, use "pdp11" instead.

	During the recompile of the libraries a fairly large number of
	"shortened" names were lengthened - these included syscall routines
	such as "gethostname" which no longer had to be munged into
	"gethname".  Also a surprising number of typographical errors
	were uncovered (mainly in the Fortran libraries) where an extra
	character (beyond the 7th character) was left off or accidentally
	added.  These were all fixed and eventually, after a couple
	evenings, the libraries were built and installed.

	After the libraries were done it was the application programs'
	turn to be recompiled.  This took the better part of a couple 
	weeks to finally make it thru due to (as it turned out) the iterative 
	nature of the task.  A symbol would come up undefined and have
	to be tracked down exactly where the wrong definition/use was
	coming from.  Finally, however, the task was done and it was
	time to move on to the kernel.

	The kernel proved to be suprisingly easy - no real complications
	arose except when it came time to reboot, a bug had been introduced
	into 'autoconfig' (who uses 'nlist' to scan the kernel symbol table).
	Ouch!  That was another couple late nights.  Since the compiler
	supports unsigned longs now a number of small changes which
	ifdef'd 'u_long' to 'long' were removed.

	REMEMBER - you need to recompile 'autoconfig' and install it
	before rebooting the new kernel ;-)

	The performance of 'ps' though (and anything else which used
	nlist(3), 'fstat', 'w' are good examples) was unacceptably slow.

	So, amidst other delays (real work, the earthquake - which almost
	tossed the disc drive to the floor, etc) the "symorder" program
	was written (with ideas borrowed from the Net-2 version).  The
	symorder(1) program rather insists on holding both the symbol
	and string tables in memory - this was a problem (or could be
	if the kernel symbol table grows much more) so two new and 
	original programs were written:  'symcompact' and 'strcompact'.

	The first program compacts the symbol table by removing 
	'register' local variables (they're of no use to anyone - the debugger
	doesn't/can't do anything with them) and redundant global text
	symbols (symbols in an overlaid program which are in the root
	segment do not need both the '~' and '_' symbols present).

	The second program 'strcompact' is one that any 'string table'
	based object file system can use.  It implements "shared strings"
	for symbols - if a program has many references to 'error' as a
	local symbol, why store the string 'error' more than once?  Simply
	store one instance and then update the symbol table entries to
	all point to the same string!

	Using both 'strcompact' and 'symcompact' on the /unix image
	resulted in a file that was 15kb smaller.  Running 'symorder'
	then puts the most frequently used symbols at the front of the
	symbol table, the performance of 'w', 'pstat', and other programs
	which nlist(3) the kernel was now acceptable.

	Some of the parts of this kit are large.  The large patch files have
	been split into pieces which the 'patch' will handle, other parts
	(the replacement 'ar' sources) were left as a single 'shar' file
	rather than split them up.

	Each part of this kit consists of:

		a 'patchfile' - this is used with the "patch" program to
		update files.

		an optional 'script' - this is run ("sh script") to perform
		initialization, remove files, create directories and so on.

		an optional 'new.sources' - this is a "shar" file containing
		complete sources for a program.

	ALL pathnames are _absolute_ - this way you do not have to "cd"
	around the system, you should be able to apply all the patches
	while you are in /tmp (or /usr/tmp - wherever you have the most
	free space).

	Be sure that you have at least 40mb free on /usr before 
	rebuilding the system - if you do not then building in stages
	will be necessary.

	Part 19 contains the detailed instructions for rebuilding the
	system _after_ the previous 18 patches have been applied.

	The patches (#158 thru #175) should be applied in order following
	the directions in each part.

	DO NOT recompile anything once the patching has begun until requested
	to do so in part 19.  Many of the system include files are modified
	and the object file format is being changed - recompilation will not
	be possible until the transformation of the system and object libraries
	is complete.

	AT A MINIMUM you will want to back up the following files (unless
	you have a known good backup already made) in case you need to
	recompile something before part 19 is done:

		/bin/ar
		/bin/ld
		/bin/nm
		/bin/as
		/usr/bin/ranlib
		/lib/c0
		/lib/crt0.o
		/lib/mcrt0.o
		/lib/libc.a
		/bin/nm
		/usr/include/*.h
		/usr/include/sys/*.h

	In part 19 there is a *complete* list of all files affected
	(all 336 of them) - you may wish to back those up also.

	And now the common header ('boilerplate') is over (at last ;-)),
	let the installation guide begin.

	As always, the complete 2.11BSD updates are available via 
	anonymous FTP to 'ftp.iipo.gtegsc.com' in the directory /pub/2.11BSD

==========  #162 (Part #5 of 19)

	This part updates the following files.  BACK THESE UP if you
	have any worries about the proceedure or do not have a bootable
	backup already at hand.

/usr/src/bin/adb/*

	This is the second part of the 'adb' changes.  ADB was almost
	a rewrite!  Lots of changes as one would expect for a program
	with an intimate knowledge of object files and symbol tables.

	While I was at it I cleaned things up considerably.  Parts of
	'adb' were (finally) written in C rather than the screwy macro
	(pseudo Pascal/Cobol/whatever) language it had been written in.
	The include files were collapsed into a single .h file and
	redundant/unneeded declarations/typedefs removed.

	Searching the new 'string table' object format is quite slow
	compared to the old style.  To speed this up a symbol string
	cache was implemented - the last 50 symbols referenced are
	cached.

	0) Be in a temp directory ("cd /tmp" or "cd /usr/tmp")

	1) Save the following shar archive to a file (/tmp/162 for example)

	2) Unpack the archive:  sh 162

	3) Patch the files:  patch -p0 < patchfile

	4) rm 162 patchfile

	Part 5 of 19 is done.  DO NOT rebuild or compile _anything_
	at this point!

========cut here
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	patchfile
# This archive created: Fri Feb  4 22:06:08 1994
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'patchfile'
then
	echo shar: "will not over-write existing file 'patchfile'"
else
sed 's/^X//' << \SHAR_EOF > 'patchfile'
Xdiff -r -c /usr/src/bin/adb.old/output.c /usr/src/bin/adb/output.c
X*** /usr/src/bin/adb.old/output.c	Mon Aug  3 07:06:44 1987
X--- /usr/src/bin/adb/output.c	Wed Jan 12 20:10:46 1994
X***************
X*** 1,51 ****
X- /*
X-  *
X-  *	UNIX debugger
X-  *
X-  */
X- 
X  #include "defs.h"
X  
X  
X- INT		mkfault;
X- INT		infile;
X- INT		outfile = 1;
X- INT		maxpos;
X- 
X- CHAR		printbuf[MAXLIN];
X- CHAR		*printptr = printbuf;
X- CHAR		*digitptr;
X- MSG		TOODEEP;
X- L_INT		var[];
X- 
X- 
X- eqstr(s1, s2)
X- 	REG STRING	s1, s2;
X- {
X- 	REG STRING	 es1;
X- 	es1 = s1+8;
X- 	WHILE *s1++ == *s2
X- 	DO IF *s2++ == 0 ORF s1>=es1
X- 	   THEN return(1);
X- 	   FI
X- 	OD
X- 	return(0);
X- }
X- 
X- length(s)
X- 	STRING		s;
X- {
X- 	INT		n = 0;
X- 	WHILE *s++ DO n++; OD
X- 	return(n);
X- }
X- 
X  printc(c)
X! 	CHAR		c;
X  {
X! 	CHAR		d;
X! 	STRING		q;
X! 	INT		posn, tabs, p;
X  
X  	IF mkfault
X  	THEN	return;
X--- 1,21 ----
X  #include "defs.h"
X  
X+ 	int	mkfault;
X+ 	int	infile;
X+ 	int	outfile = 1;
X+ 	int	maxpos;
X+ 	char	printbuf[MAXLIN];
X+ 	char	*printptr = printbuf;
X+ 	char	*digitptr;
X+ 	MSG	TOODEEP;
X+ 	long	var[];
X  
X  printc(c)
X! 	char	c;
X  {
X! 	char	d;
X! 	char	*q;
X! 	int	posn, tabs, p;
X  
X  	IF mkfault
X  	THEN	return;
X***************
X*** 78,87 ****
X  	FI
X  }
X  
X- charpos()
X- {	return(printptr-printbuf);
X- }
X- 
X  flushbuf()
X  {	IF printptr!=printbuf
X  	THEN printc(EOR);
X--- 48,53 ----
X***************
X*** 88,109 ****
X  	FI
X  }
X  
X  printf(fmat,a1)
X! 	STRING		fmat;
X! 	STRING		*a1;
X  {
X! 	STRING		fptr, s;
X! 	INT		*vptr;
X! 	L_INT		*dptr;
X! 	L_REAL		*rptr;
X! 	INT		width, prec;
X! 	CHAR		c, adj;
X! 	INT		x, decpt, n;
X! 	L_INT		lx;
X! 	CHAR		digits[64];
X! 	STRING		ecvt();
X  
X! 	fptr = fmat; vptr = (INT*)&a1;
X  
X  	WHILE c = *fptr++
X  	DO  IF c!='%'
X--- 54,76 ----
X  	FI
X  }
X  
X+ /*VARARGS*/
X  printf(fmat,a1)
X! 	char	*fmat;
X! 	char	**a1;
X  {
X! 	char	*fptr, *s;
X! 	int	*vptr;
X! 	long	*dptr;
X! 	double	*rptr;
X! 	int	width, prec;
X! 	char	c, adj;
X! 	int	x, decpt, n;
X! 	long	lx;
X! 	char	digits[64];
X! 	char	*ecvt();
X  
X! 	fptr = fmat; vptr = (int *)&a1;
X  
X  	WHILE c = *fptr++
X  	DO  IF c!='%'
X***************
X*** 110,121 ****
X  	    THEN printc(c);
X  	    ELSE IF *fptr=='-' THEN adj='l'; fptr++; ELSE adj='r'; FI
X  		 width=convert(&fptr);
X! 		 IF *fptr=='.' THEN fptr++; prec=convert(&fptr); ELSE prec = -1; FI
X  		 digitptr=digits;
X! 		 dptr=(L_INT*)(rptr=(L_REAL*)vptr); lx = *dptr; x = *vptr++;
X  		 s=0;
X  		 switch (c = *fptr++) {
X- 
X  		    case 'd':
X  		    case 'u':
X  			printnum(x,c,10); break;
X--- 77,103 ----
X  	    THEN printc(c);
X  	    ELSE IF *fptr=='-' THEN adj='l'; fptr++; ELSE adj='r'; FI
X  		 width=convert(&fptr);
X! 		 if	(*fptr == '*')
X! 			{
X! 			width = *vptr++;
X! 			fptr++;
X! 			}
X! 		 if	(*fptr == '.')
X! 			{
X! 			fptr++;
X! 			prec = convert(&fptr);
X! 			if	(*fptr == '*')
X! 				{
X! 				prec = *vptr++;
X! 				fptr++;
X! 				}
X! 			}
X! 		else
X! 			prec = -1;
X  		 digitptr=digits;
X! 		 dptr=(long *)(rptr=(double *)vptr); lx = *dptr; x = *vptr++;
X  		 s=0;
X  		 switch (c = *fptr++) {
X  		    case 'd':
X  		    case 'u':
X  			printnum(x,c,10); break;
X***************
X*** 139,145 ****
X  		    case 'c':
X  			printc(x); break;
X  		    case 's':
X! 			s=(STRING)x; break;
X  		    case 'f':
X  		    case 'F':
X  			vptr += 7;
X--- 121,127 ----
X  		    case 'c':
X  			printc(x); break;
X  		    case 's':
X! 			s=(char *)x; break;
X  		    case 'f':
X  		    case 'F':
X  			vptr += 7;
X***************
X*** 166,172 ****
X  			ELSE vptr--;
X  			FI
X  			IF width
X! 			THEN width -= charpos()%width;
X  			FI
X  			break;
X  		    default:
X--- 148,154 ----
X  			ELSE vptr--;
X  			FI
X  			IF width
X! 			THEN width -= ((printptr - printbuf) % width);
X  			FI
X  			break;
X  		    default:
X***************
X*** 176,182 ****
X  		IF s==0
X  		THEN *digitptr=0; s=digits;
X  		FI
X! 		n=length(s);
X  		n=(prec<n ANDF prec>=0 ? prec : n);
X  		width -= n;
X  		IF adj=='r'
X--- 158,164 ----
X  		IF s==0
X  		THEN *digitptr=0; s=digits;
X  		FI
X! 		n = strlen(s);
X  		n=(prec<n ANDF prec>=0 ? prec : n);
X  		width -= n;
X  		IF adj=='r'
X***************
X*** 191,222 ****
X  }
X  
X  printdate(tvec)
X! 	L_INT		tvec;
X  {
X! 	REG INT		i;
X! 	REG STRING	timeptr;
X! 	STRING		ctime();
X  	timeptr = ctime(&tvec);
X  	FOR i=20; i<24; i++ DO *digitptr++ = *(timeptr+i); OD
X  	FOR i=3; i<19; i++ DO *digitptr++ = *(timeptr+i); OD
X- } /*printdate*/
X- 
X- prints(s)
X- char *s;
X- {	printf("%s",s);
X  }
X  
X- newline()
X- {
X- 	printc(EOR);
X- }
X- 
X  convert(cp)
X! REG STRING	*cp;
X  {
X! 	REG CHAR	c;
X! 	INT		n;
X! 	n=0;
X  	WHILE ((c = *(*cp)++)>='0') ANDF (c<='9') DO n=n*10+c-'0'; OD
X  	(*cp)--;
X  	return(n);
X--- 173,195 ----
X  }
X  
X  printdate(tvec)
X! 	long	tvec;
X  {
X! 	register int i;
X! 	register char	*timeptr;
X! 	extern	char	*ctime();
X! 
X  	timeptr = ctime(&tvec);
X  	FOR i=20; i<24; i++ DO *digitptr++ = *(timeptr+i); OD
X  	FOR i=3; i<19; i++ DO *digitptr++ = *(timeptr+i); OD
X  }
X  
X  convert(cp)
X! 	register char **cp;
X  {
X! 	register char c;
X! 	int	n = 0;
X! 
X  	WHILE ((c = *(*cp)++)>='0') ANDF (c<='9') DO n=n*10+c-'0'; OD
X  	(*cp)--;
X  	return(n);
X***************
X*** 223,238 ****
X  }
X  
X  printnum(n,fmat,base)
X! 	REG INT		n;
X  {
X! 	REG CHAR	k;
X! 	REG INT		*dptr;
X! 	INT		digs[15];
X  	dptr=digs;
X  	IF n<0 ANDF fmat=='d' THEN n = -n; *digitptr++ = '-'; FI
X  	WHILE n
X! 	DO  *dptr++ = ((POS)n)%base;
X! 	    n=((POS)n)/base;
X  	OD
X  	IF dptr==digs THEN *dptr++=0; FI
X  	WHILE dptr!=digs
X--- 196,212 ----
X  }
X  
X  printnum(n,fmat,base)
X! 	register int n;
X  {
X! 	register char k;
X! 	register int *dptr;
X! 	int digs[15];
X! 
X  	dptr=digs;
X  	IF n<0 ANDF fmat=='d' THEN n = -n; *digitptr++ = '-'; FI
X  	WHILE n
X! 	DO  *dptr++ = ((u_int)n)%base;
X! 	    n=((u_int)n)/base;
X  	OD
X  	IF dptr==digs THEN *dptr++=0; FI
X  	WHILE dptr!=digs
X***************
X*** 242,253 ****
X  }
X  
X  printoct(o,s)
X! 	L_INT		o;
X! 	INT		s;
X  {
X! 	INT		i;
X! 	L_INT		po = o;
X! 	CHAR		digs[12];
X  
X  	IF s
X  	THEN IF po<0
X--- 216,227 ----
X  }
X  
X  printoct(o,s)
X! 	long	o;
X! 	int	s;
X  {
X! 	int	i;
X! 	long	po = o;
X! 	char	digs[12];
X  
X  	IF s
X  	THEN IF po<0
X***************
X*** 265,273 ****
X  }
X  
X  printdbl(lx,ly,fmat,base)
X! INT lx, ly; char fmat; int base;
X! {	int digs[20]; int *dptr; char k;
X! 	L_REAL f ,g; long q;
X  	dptr=digs;
X  	IF fmat!='D'
X  	THEN	f=leng(lx); f *= itol(1,0); f += leng(ly);
X--- 239,253 ----
X  }
X  
X  printdbl(lx,ly,fmat,base)
X! 	int	lx, ly;
X! 	char	fmat;
X! 	int	base;
X! {
X! 	int digs[20], *dptr;
X! 	char k;
X! 	double	f ,g;
X! 	long q;
X! 
X  	dptr=digs;
X  	IF fmat!='D'
X  	THEN	f=leng(lx); f *= itol(1,0); f += leng(ly);
X***************
X*** 289,299 ****
X  
X  #define	MAXIFD	5
X  struct {
X! 	INT	fd;
X! 	L_INT	r9;
X  } istack[MAXIFD];
X- INT	ifiledepth;
X  
X  iclose(stack, err)
X  {
X  	IF err
X--- 269,280 ----
X  
X  #define	MAXIFD	5
X  struct {
X! 	int	fd;
X! 	long	r9;
X  } istack[MAXIFD];
X  
X+ 	int	ifiledepth;
X+ 
X  iclose(stack, err)
X  {
X  	IF err
X***************
X*** 337,343 ****
X  
X  endline()
X  {
X! 	IF charpos()>=maxpos
X! 	THEN printf("\n");
X! 	FI
X  }
X--- 318,323 ----
X  
X  endline()
X  {
X! 	if	((printptr - printbuf) >= maxpos)
X! 		printc('\n');
X  }
Xdiff -r -c /usr/src/bin/adb.old/pcs.c /usr/src/bin/adb/pcs.c
X*** /usr/src/bin/adb.old/pcs.c	Sun Feb  8 14:25:47 1987
X--- /usr/src/bin/adb/pcs.c	Fri Dec 31 11:12:12 1993
X***************
X*** 1,47 ****
X- /*
X-  *
X-  *	UNIX debugger
X-  *
X-  */
X- 
X  #include "defs.h"
X  
X  
X- MSG		NOBKPT;
X- MSG		SZBKPT;
X- MSG		EXBKPT;
X- MSG		NOPCS;
X- MSG		BADMOD;
X- 
X  /* breakpoints */
X! BKPTR		bkpthead;
X  
X! CHAR		*lp;
X! CHAR		lastc;
X! POS		corhdr[ctob(USIZE)/sizeof(POS)];
X! POS		*endhdr;
X! MAP		txtmap;
X  
X- INT		signo;
X- L_INT		dot;
X- INT		pid;
X- L_INT		cntval;
X- L_INT		loopcnt;
X- int		overlay;
X- 
X- OVTAG		curov, symov;
X- 
X- 
X  /* sub process control */
X  
X  subpcs(modif)
X  {
X! 	REG INT		check;
X! 	INT		execsig;
X! 	INT		runmode;
X! 	REG BKPTR	bkptr;
X! 	STRING		comptr;
X! 	CHAR		*sbrk();
X  	execsig=0; loopcnt=cntval;
X  
X  	switch(modif) {
X--- 1,35 ----
X  #include "defs.h"
X  
X+ 	MSG	NOBKPT;
X+ 	MSG	SZBKPT;
X+ 	MSG	EXBKPT;
X+ 	MSG	NOPCS;
X+ 	MSG	BADMOD;
X  
X  /* breakpoints */
X! 	BKPTR	bkpthead;
X  
X! 	char	*lp;
X! 	char	lastc;
X! 	u_int	corhdr[ctob(USIZE)/sizeof(u_int)];
X! 	MAP	txtmap;
X! 	int	signo;
X! 	long	dot;
X! 	int	pid;
X! 	long	cntval;
X! 	long	loopcnt;
X! 	int	overlay;
X! 	char	curov, symov;
X  
X  /* sub process control */
X  
X  subpcs(modif)
X  {
X! 	register int check;
X! 	int	execsig, runmode;
X! 	register BKPTR	bkptr;
X! 	char	*comptr;
X! 
X  	execsig=0; loopcnt=cntval;
X  
X  	switch(modif) {
X***************
X*** 71,77 ****
X  		   FI
X  		OD
X  		IF bkptr==0
X! 		THEN IF (bkptr=(BKPTR)sbrk(sizeof *bkptr)) == -1
X  		     THEN error(SZBKPT);
X  		     ELSE bkptr->nxtbkpt=bkpthead;
X  			  bkpthead=bkptr;
X--- 59,65 ----
X  		   FI
X  		OD
X  		IF bkptr==0
X! 		THEN IF (bkptr=(BKPTR)malloc(sizeof *bkptr)) == (BKPTR)NULL
X  		     THEN error(SZBKPT);
X  		     ELSE bkptr->nxtbkpt=bkpthead;
X  			  bkpthead=bkptr;
Xdiff -r -c /usr/src/bin/adb.old/print.c /usr/src/bin/adb/print.c
X*** /usr/src/bin/adb.old/print.c	Sun Dec 25 20:52:13 1988
X--- /usr/src/bin/adb/print.c	Wed Jan 12 23:30:43 1994
X***************
X*** 1,39 ****
X- /*
X-  * adb: UNIX debugger
X-  */
X- 
X  #include "defs.h"
X  
X! MSG             LONGFIL;
X! MSG             NOTOPEN;
X! MSG             A68BAD;
X! MSG             A68LNK;
X! MSG             BADMOD;
X  
X! MAP             txtmap;
X! MAP             datmap;
X! OVTAG           curov;
X! int             overlay;
X! 
X! SYMTAB          symbol;
X! INT             lastframe;
X! INT             kernel;
X! INT             callpc;
X! 
X! INT             infile;
X! INT             outfile;
X! CHAR            *lp;
X! INT             maxoff;
X! INT             maxpos;
X! INT             octal;
X! 
X! /* symbol management */
X! L_INT           localval;
X! 
X! /* breakpoints */
X! BKPTR           bkpthead;
X! 
X! REGLIST reglist [] = {
X  		"ps", RPS,
X  		"pc", PC,
X  		"sp", R6,
X--- 1,46 ----
X  #include "defs.h"
X+ #include <sys/file.h>
X  
X! 	MSG	LONGFIL;
X! 	MSG     NOTOPEN;
X! 	MSG     A68BAD;
X! 	MSG     A68LNK;
X! 	MSG     BADMOD;
X! 	MAP     txtmap;
X! 	MAP     datmap;
X! 	char	curov;
X! 	int	overlay;
X! extern	struct	SYMbol	*symbol;
X! 	int	lastframe;
X! 	int     kernel;
X! 	int	callpc;
X! 	int	infile;
X! 	int	outfile;
X! 	char	*lp;
X! 	int	maxoff;
X! 	int	maxpos;
X! 	int	octal;
X! 	long	localval;
X! 	BKPTR   bkpthead;
X! static	char	frnames[] = { 0, 3, 4, 5, 1, 2 };
X! 	char    lastc;
X! 	u_int	corhdr[];
X! 	u_int	*uar0;
X! 	int	fcor;
X! 	char	*errflg;
X! 	int	signo;
X! 	long	dot;
X! 	long	var[];
X! 	char	*symfil;
X! 	char	*corfil;
X! 	int	pid;
X! 	long	adrval;
X! 	int	adrflg;
X! 	long	cntval;
X! 	int	cntflg;
X! 	int     overlay;
X  
X! 	REGLIST reglist [] = {
X  		"ps", RPS,
X  		"pc", PC,
X  		"sp", R6,
X***************
X*** 43,51 ****
X  		"r2", R2,
X  		"r1", R1,
X  		"r0", R0
X! };
X  
X! REGLIST kregs[] = {
X  		"sp", KSP,
X  		"r5", KR5,
X  		"r4", KR4,
X--- 50,58 ----
X  		"r2", R2,
X  		"r1", R1,
X  		"r0", R0
X! 		};
X  
X! 	REGLIST kregs[] = {
X  		"sp", KSP,
X  		"r5", KR5,
X  		"r4", KR4,
X***************
X*** 53,98 ****
X  		"r2", KR2,
X  		"r1", KR1,
X  		"r0", KR0
X! };
X  
X- STRING  ovname  = "ov";   /* not in reglist (not from kernel stack) */
X- INT             frnames[] = { 0, 3, 4, 5, 1, 2 };
X  
X- char            lastc;
X- POS             corhdr[];
X- POS             *uar0;
X- 
X- INT             fcor;
X- STRING          errflg;
X- INT             signo;
X- 
X- 
X- L_INT           dot;
X- L_INT           var[];
X- STRING          symfil;
X- STRING          corfil;
X- INT             pid;
X- L_INT           adrval;
X- INT             adrflg;
X- L_INT           cntval;
X- INT             cntflg;
X- int             overlay;
X- 
X- 
X  /* general printing routines ($) */
X  
X  printtrace(modif)
X  {
X! 	INT             narg, i, stat, name, limit;
X! 	POS             dynam;
X! 	REG BKPTR       bkptr;
X! 	CHAR            hi, lo;
X! 	INT             word;
X! 	INT		stack;
X! 	STRING          comptr;
X! 	L_INT           argp, frame, link;
X! 	SYMPTR          symp;
X! 	OVTAG           savov;
X  
X  	IF cntflg==0 THEN cntval = -1; FI
X  
X--- 60,81 ----
X  		"r2", KR2,
X  		"r1", KR1,
X  		"r0", KR0
X! 	};
X  
X  
X  /* general printing routines ($) */
X  
X  printtrace(modif)
X  {
X! 	int	narg, i, stat, name, limit;
X! 	u_int	dynam;
X! 	register BKPTR       bkptr;
X! 	char	hi, lo;
X! 	int	word, stack;
X! 	char	*comptr;
X! 	long	argp, frame, link;
X! 	register struct	SYMbol	*symp;
X! 	char	savov;
X  
X  	IF cntflg==0 THEN cntval = -1; FI
X  
X***************
X*** 112,121 ****
X  			/* fall thru ... */
X  	    case '>':
X  		{
X! 			CHAR		file[64];
X! 			CHAR		Ifile[128];
X! 			extern CHAR	*Ipath;
X! 			INT             index;
X  
X  			index=0;
X  			IF rdc()!=EOR
X--- 95,104 ----
X  			/* fall thru ... */
X  	    case '>':
X  		{
X! 			char		file[64];
X! 			char		Ifile[128];
X! 			extern char	*Ipath;
X! 			int             index;
X  
X  			index=0;
X  			IF rdc()!=EOR
X***************
X*** 145,155 ****
X  						FI
X  					FI
X  				ELSE    oclose();
X! 					outfile=open(file,1);
X! 					IF outfile<0
X! 					THEN    outfile=creat(file,0644);
X! 					ELSE    lseek(outfile,0L,2);
X! 					FI
X  				FI
X  
X  			ELSE	IF modif == '<'
X--- 128,135 ----
X  						FI
X  					FI
X  				ELSE    oclose();
X! 					outfile = open(file, O_CREAT|O_WRONLY, 0644);
X! 					lseek(outfile,0L,2);
X  				FI
X  
X  			ELSE	IF modif == '<'
X***************
X*** 179,185 ****
X  		break;
X  
X  	    case 'v': 
X! 		prints("variables\n");
X  		FOR i=0;i<=35;i++
X  		DO IF var[i]
X  		   THEN printc((i<=9 ? '0' : 'a'-10) + i);
X--- 159,165 ----
X  		break;
X  
X  	    case 'v': 
X! 		printf("variables\n");
X  		FOR i=0;i<=35;i++
X  		DO IF var[i]
X  		   THEN printc((i<=9 ? '0' : 'a'-10) + i);
X***************
X*** 196,202 ****
X  	    case 0: case '?':
X  		IF pid
X  		THEN printf("pcs id = %d\n",pid);
X! 		ELSE prints("no process\n");
X  		FI
X  		sigprint(); flushbuf();
X  
X--- 176,182 ----
X  	    case 0: case '?':
X  		IF pid
X  		THEN printf("pcs id = %d\n",pid);
X! 		ELSE printf("no process\n");
X  		FI
X  		sigprint(); flushbuf();
X  
X***************
X*** 217,223 ****
X  		DO      chkerr();
X   			printf("%07O: ", frame); /* Add frame address info */
X  			narg = findroutine(frame);
X! 			printf("%.8s(", symbol.symc);
X  			argp = frame+4;
X  			IF --narg >= 0
X  			THEN    printf("%o", get(argp, DSP));
X--- 197,203 ----
X  		DO      chkerr();
X   			printf("%07O: ", frame); /* Add frame address info */
X  			narg = findroutine(frame);
X! 			printf("%s(", cache_sym(symbol));
X  			argp = frame+4;
X  			IF --narg >= 0
X  			THEN    printf("%o", get(argp, DSP));
X***************
X*** 231,251 ****
X   			 * max possible offset.  Overlay has already been set
X   			 * properly by findfn.
X   			 */
X!  			prints(") from ");
X   			{
X! 				INT savmaxoff = maxoff;
X  
X   				maxoff = ((unsigned)-1)>>1;
X!  				psymoff((L_INT)callpc,ISYM,"");
X   				maxoff = savmaxoff;
X   			}
X!  			prints("\n");
X  
X  			IF modif=='C'
X  			THEN WHILE localsym(frame)
X  			     DO word=get(localval,DSP);
X! 				printf("%8t%.8s:%10t", symbol.symc);
X! 				IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%o\n",word); FI
X  			     OD
X  			FI
X  
X--- 211,231 ----
X   			 * max possible offset.  Overlay has already been set
X   			 * properly by findfn.
X   			 */
X!  			printf(") from ");
X   			{
X! 				int	savmaxoff = maxoff;
X  
X   				maxoff = ((unsigned)-1)>>1;
X!  				psymoff((long)callpc,ISYM,"");
X   				maxoff = savmaxoff;
X   			}
X!  			printc('\n');
X  
X  			IF modif=='C'
X  			THEN WHILE localsym(frame)
X  			     DO word=get(localval,DSP);
X! 				printf("%8t%s:%10t", cache_sym(symbol));
X! 				IF errflg THEN printf("?\n"); errflg=0; ELSE printf("%o\n",word); FI
X  			     OD
X  			FI
X  
X***************
X*** 264,271 ****
X  		symset();
X  		WHILE (symp=symget())
X  		DO chkerr();
X! 		   IF (symp->symf)==043 ORF (symp->symf)==044
X! 		   THEN printf("%.8s:%12t%o\n", symp->symc, get(leng(symp->symv),DSP));
X  		   FI
X  		OD
X  		break;
X--- 244,252 ----
X  		symset();
X  		WHILE (symp=symget())
X  		DO chkerr();
X! 		   IF (symp->type == N_EXT|N_DATA) || (symp->type== N_EXT|N_BSS)
X! 		   THEN printf("%s:%12t%o\n", no_cache_sym(symp),
X! 				get(leng(symp->value),DSP));
X  		   FI
X  		OD
X  		break;
X***************
X*** 286,292 ****
X  		   THEN IF get(link-2,ISP)!=04775
X  			THEN error(A68LNK);
X  			ELSE /*compute entry point of routine*/
X! 			     prints(" ? ");
X  			FI
X  		   ELSE printf("%8t");
X  			valpr(name=shorten(link)+get(link-2,ISP),ISYM);
X--- 267,273 ----
X  		   THEN IF get(link-2,ISP)!=04775
X  			THEN error(A68LNK);
X  			ELSE /*compute entry point of routine*/
X! 			     printf(" ? ");
X  			FI
X  		   ELSE printf("%8t");
X  			valpr(name=shorten(link)+get(link-2,ISP),ISYM);
X***************
X*** 332,338 ****
X  }
X  
X  printmap(s,amap)
X! STRING  s; MAP *amap;
X  {
X  	int file;
X  	file=amap->ufd;
X--- 313,320 ----
X  }
X  
X  printmap(s,amap)
X! 	char	*s;
X! 	MAP	*amap;
X  {
X  	int file;
X  	file=amap->ufd;
X***************
X*** 353,361 ****
X  
X  printfregs(longpr)
X  {
X! #ifndef NONFP
X! 	REG i;
X! 	L_REAL f;
X  	struct Lfp *pfp;
X  
X  	pfp = (struct Lfp *)&((U*)corhdr)->u_fps.u_fpsr;
X--- 335,342 ----
X  
X  printfregs(longpr)
X  {
X! 	register int i;
X! 	double f;
X  	struct Lfp *pfp;
X  
X  	pfp = (struct Lfp *)&((U*)corhdr)->u_fps.u_fpsr;
X***************
X*** 367,379 ****
X  		FI
X  		printf("fr%-8d%-32.18f\n", i, f);
X  	OD
X- #endif
X  }
X  
X  printregs()
X  {
X! 	REG REGPTR      p;
X! 	INT             v;
X  
X  	IF kernel
X  	THEN    FOR p=kregs; p<&kregs[7]; p++
X--- 348,359 ----
X  		FI
X  		printf("fr%-8d%-32.18f\n", i, f);
X  	OD
X  }
X  
X  printregs()
X  {
X! 	register REGPTR      p;
X! 	int	v;
X  
X  	IF kernel
X  	THEN    FOR p=kregs; p<&kregs[7]; p++
X***************
X*** 389,395 ****
X  		IF overlay
X  		THEN    setovmap(((U *)corhdr)->u_ovdata.uo_curov);
X  			var[VARC] = curov;
X! 			printf("%s%8t%o\n", ovname, curov);
X  		FI
X  		printpc();
X  	FI
X--- 369,375 ----
X  		IF overlay
X  		THEN    setovmap(((U *)corhdr)->u_ovdata.uo_curov);
X  			var[VARC] = curov;
X! 			printf("ov%8t%o\n", curov);
X  		FI
X  		printpc();
X  	FI
X***************
X*** 397,405 ****
X  
X  getreg(regnam)
X  {
X! 	REG REGPTR      p;
X! 	REG STRING      regptr;
X! 	CHAR            regnxt;
X  
X  	IF kernel THEN return(NOREG); FI        /* not supported */
X  	regnxt=readchar();
X--- 377,385 ----
X  
X  getreg(regnam)
X  {
X! 	register REGPTR      p;
X! 	register char	*regptr;
X! 	char	regnxt;
X  
X  	IF kernel THEN return(NOREG); FI        /* not supported */
X  	regnxt=readchar();
X***************
X*** 409,416 ****
X  		THEN    return(p->roffs);
X  		FI
X  	OD
X! 	IF regnam==ovname[0] ANDF regnxt==ovname[1]
X! 	THEN    return((POS *)&(((U *)corhdr)->u_ovdata.uo_curov) - uar0);
X  	FI
X  	lp--;
X  	return(NOREG);
X--- 389,396 ----
X  		THEN    return(p->roffs);
X  		FI
X  	OD
X! 	IF regnam == 'o' && regnxt == 'v'
X! 	THEN    return((u_int *)&(((U *)corhdr)->u_ovdata.uo_curov) - uar0);
X  	FI
X  	lp--;
X  	return(NOREG);
X***************
X*** 419,425 ****
X  printpc()
X  {
X  	dot=uar0[PC];
X! 	psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP));
X  	printc(EOR);
X  }
X  
X--- 399,405 ----
X  printpc()
X  {
X  	dot=uar0[PC];
X! 	psymoff(dot,ISYM,":%16t"); printins(ISP,chkget(dot,ISP));
X  	printc(EOR);
X  }
X  
Xdiff -r -c /usr/src/bin/adb.old/runpcs.c /usr/src/bin/adb/runpcs.c
X*** /usr/src/bin/adb.old/runpcs.c	Tue Aug  4 19:58:04 1987
X--- /usr/src/bin/adb/runpcs.c	Wed Jan 12 21:30:33 1994
X***************
X*** 1,62 ****
X- /*
X-  *
X-  *      UNIX debugger
X-  *
X-  */
X- 
X  #include "defs.h"
X  
X  
X- MSG             NOFORK;
X- MSG             ENDPCS;
X- MSG             BADWAIT;
X- 
X- CHAR            *lp;
X- INT             sigint;
X- INT             sigqit;
X- 
X- /* breakpoints */
X- BKPTR           bkpthead;
X- 
X- REGLIST         reglist[];
X- 
X- CHAR            lastc;
X- POS             corhdr[];
X- POS             *uar0;
X- int             overlay;
X- OVTAG           curov;
X- 
X- INT             fcor;
X- INT             fsym;
X- STRING          errflg;
X- INT             errno;
X- INT             signo;
X- 
X- L_INT           dot;
X- STRING          symfil;
X- INT             wtflag;
X- INT             pid;
X- L_INT           expv;
X- INT             adrflg;
X- L_INT           loopcnt;
X- L_INT           var[];
X- 
X- 
X- 
X- 
X- 
X  /* service routines for sub process control */
X  
X  getsig(sig)
X! {       return(expr(0) ? shorten(expv) : sig);
X! }
X  
X- INT             userpc=1;
X- 
X  runpcs(runmode, execsig)
X  {
X! 	INT             rc;
X! 	REG BKPTR       bkpt;
X  	IF adrflg
X  	THEN userpc=shorten(dot);
X  	FI
X--- 1,46 ----
X  #include "defs.h"
X+ #include <sys/file.h>
X  
X+ 	MSG	NOFORK;
X+ 	MSG	ENDPCS;
X+ 	MSG     BADWAIT;
X+ 	char    *lp;
X+ 	int	sigint;
X+ 	int	sigqit;
X+ 	BKPTR   bkpthead;
X+ 	REGLIST reglist[];
X+ 	char	lastc;
X+ 	u_int	corhdr[];
X+ 	u_int	*uar0;
X+ 	int     overlay;
X+ 	char	curov;
X+ 	int	fcor;
X+ 	int	fsym;
X+ 	char	*errflg;
X+ 	int	signo;
X+ 	long	dot;
X+ 	char	*symfil;
X+ 	int	wtflag;
X+ 	int	pid;
X+ 	long	expv;
X+ 	int	adrflg;
X+ 	long	loopcnt;
X+ 	long	var[];
X+ 	int	userpc=1;
X+ extern	int	errno;
X  
X  /* service routines for sub process control */
X  
X  getsig(sig)
X! 	{
X! 	return(expr(0) ? shorten(expv) : sig);
X! 	}
X  
X  runpcs(runmode, execsig)
X  {
X! 	int	rc;
X! 	register BKPTR       bkpt;
X! 
X  	IF adrflg
X  	THEN userpc=shorten(dot);
X  	FI
X***************
X*** 92,98 ****
X  
X  endpcs()
X  {
X! 	REG BKPTR       bkptr;
X  	IF pid
X  	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
X  	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X--- 76,83 ----
X  
X  endpcs()
X  {
X! 	register BKPTR       bkptr;
X! 
X  	IF pid
X  	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
X  	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X***************
X*** 105,110 ****
X--- 90,96 ----
X  
X  setup()
X  {
X+ 
X  	close(fsym); fsym = -1;
X  	IF (pid = fork()) == 0
X  	THEN ptrace(SETTRC,0,0,0);
X***************
X*** 116,122 ****
X  	     fsym=open(symfil,wtflag);
X  	     IF errflg
X  	     THEN printf("%s: cannot execute\n",symfil);
X! 		  endpcs(); error(0);
X  	     FI
X  	FI
X  }
X--- 102,108 ----
X  	     fsym=open(symfil,wtflag);
X  	     IF errflg
X  	     THEN printf("%s: cannot execute\n",symfil);
X! 		  endpcs(); error((char *)0);
X  	     FI
X  	FI
X  }
X***************
X*** 123,129 ****
X  
X  execbkpt(bkptr)
X  BKPTR   bkptr;
X! {       INT             bkptloc;
X  #ifdef DEBUG
X  	printf("exbkpt: %d\n",bkptr->count);
X  #endif
X--- 109,116 ----
X  
X  execbkpt(bkptr)
X  BKPTR   bkptr;
X! {
X! 	int	bkptloc;
X  #ifdef DEBUG
X  	printf("exbkpt: %d\n",bkptr->count);
X  #endif
X***************
X*** 136,147 ****
X  	bkptr->flag=BKPTSET;
X  }
X  
X- 
X  doexec()
X  {
X! 	STRING          argl[MAXARG];
X! 	CHAR            args[LINSIZ];
X! 	STRING          p, *ap, filnam;
X  	ap=argl; p=args;
X  	*ap++=symfil;
X  	REP     IF rdc()==EOR THEN break; FI
X--- 123,134 ----
X  	bkptr->flag=BKPTSET;
X  }
X  
X  doexec()
X  {
X! 	char	*argl[MAXARG];
X! 	char	args[LINSIZ];
X! 	char	*p, **ap, *filnam;
X! 
X  	ap=argl; p=args;
X  	*ap++=symfil;
X  	REP     IF rdc()==EOR THEN break; FI
X***************
X*** 161,167 ****
X  			p = *ap;
X  		ELIF **ap=='>'
X  		THEN    close(1);
X! 			IF creat(filnam,0666)<0
X  			THEN    printf("%s: cannot create\n",filnam); exit(0);
X  			FI
X  			p = *ap;
X--- 148,154 ----
X  			p = *ap;
X  		ELIF **ap=='>'
X  		THEN    close(1);
X! 			IF open(filnam, O_CREAT|O_WRONLY, 0666)<0
X  			THEN    printf("%s: cannot create\n",filnam); exit(0);
X  			FI
X  			p = *ap;
X***************
X*** 174,180 ****
X  
X  BKPTR   scanbkpt(adr)
X  {
X! 	REG BKPTR       bkptr;
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag ANDF bkptr->loc==adr ANDF 
X  	  (bkptr->ovly == 0 || bkptr->ovly==curov)
X--- 161,168 ----
X  
X  BKPTR   scanbkpt(adr)
X  {
X! 	register BKPTR       bkptr;
X! 
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag ANDF bkptr->loc==adr ANDF 
X  	  (bkptr->ovly == 0 || bkptr->ovly==curov)
X***************
X*** 186,192 ****
X  
X  delbp()
X  {
X! 	REG BKPTR       bkptr;
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag
X  	   THEN del1bp(bkptr);
X--- 174,181 ----
X  
X  delbp()
X  {
X! 	register BKPTR       bkptr;
X! 
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag
X  	   THEN del1bp(bkptr);
X***************
X*** 204,210 ****
X  
X  /* change overlay in subprocess */
X  choverlay(ovno)
X! OVTAG ovno;
X  {
X  	errno = 0;
X  	if (overlay && pid && ovno>0 && ovno<=NOVL)
X--- 193,199 ----
X  
X  /* change overlay in subprocess */
X  choverlay(ovno)
X! 	char	ovno;
X  {
X  	errno = 0;
X  	if (overlay && pid && ovno>0 && ovno<=NOVL)
X***************
X*** 216,222 ****
X  
X  setbp()
X  {
X! 	REG BKPTR       bkptr;
X  
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag
X--- 205,211 ----
X  
X  setbp()
X  {
X! 	register BKPTR       bkptr;
X  
X  	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
X  	DO IF bkptr->flag
X***************
X*** 227,233 ****
X  set1bp(bkptr)
X  BKPTR bkptr;
X  {
X! 	REG INT         a;
X  	a = bkptr->loc;
X  	if (bkptr->ovly)
X  		choverlay(bkptr->ovly);
X--- 216,223 ----
X  set1bp(bkptr)
X  BKPTR bkptr;
X  {
X! 	register int         a;
X! 
X  	a = bkptr->loc;
X  	if (bkptr->ovly)
X  		choverlay(bkptr->ovly);
X***************
X*** 234,240 ****
X  	bkptr->ins = ptrace(RIUSER, pid, a, 0);
X  	ptrace(WIUSER, pid, a, BPT);
X  	IF errno
X! 	THEN prints("cannot set breakpoint: ");
X  	     psymoff(leng(bkptr->loc),ISYM,"\n");
X  	FI
X  }
X--- 224,230 ----
X  	bkptr->ins = ptrace(RIUSER, pid, a, 0);
X  	ptrace(WIUSER, pid, a, BPT);
X  	IF errno
X! 	THEN printf("cannot set breakpoint: ");
X  	     psymoff(leng(bkptr->loc),ISYM,"\n");
X  	FI
X  }
X***************
X*** 241,248 ****
X  
X  bpwait()
X  {
X! 	REG INT w;
X! 	INT stat;
X  
X  	signal(SIGINT, SIG_IGN);
X  	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
X--- 231,238 ----
X  
X  bpwait()
X  {
X! 	register int w;
X! 	int stat;
X  
X  	signal(SIGINT, SIG_IGN);
X  	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
X***************
X*** 257,263 ****
X  	     THEN sigprint();
X  	     FI
X  	     IF stat&0200
X! 	     THEN prints(" - core dumped");
X  		  close(fcor);
X  		  setcor();
X  	     FI
X--- 247,253 ----
X  	     THEN sigprint();
X  	     FI
X  	     IF stat&0200
X! 	     THEN printf(" - core dumped");
X  		  close(fcor);
X  		  setcor();
X  	     FI
X***************
X*** 275,281 ****
X  readregs()
X  {
X  	/*get REG values from pcs*/
X! 	REG i;
X  	FOR i=0; i<NREG; i++
X  	DO uar0[reglist[i].roffs] =
X  		    ptrace(RUREGS, pid,
X--- 265,273 ----
X  readregs()
X  {
X  	/*get REG values from pcs*/
X! 	register int i;
X! 	char	ovno;
X! 
X  	FOR i=0; i<NREG; i++
X  	DO uar0[reglist[i].roffs] =
X  		    ptrace(RUREGS, pid,
X***************
X*** 284,290 ****
X  	OD
X  	/* if overlaid, get ov */
X  	IF overlay
X! 	THEN    OVTAG ovno;
X  		ovno = ptrace(RUREGS, pid,
X  		    &(((struct user *)0)->u_ovdata.uo_curov),0);
X  		var[VARC] = ovno;
X--- 276,282 ----
X  	OD
X  	/* if overlaid, get ov */
X  	IF overlay
X! 	THEN
X  		ovno = ptrace(RUREGS, pid,
X  		    &(((struct user *)0)->u_ovdata.uo_curov),0);
X  		var[VARC] = ovno;
X***************
X*** 292,302 ****
X  		setovmap(ovno);
X  	FI
X  
X- #ifndef NONFP
X  	/* REALing poINT                */
X  	FOR i=FROFF; i<FRLEN+FROFF; i++
X  	DO corhdr[i] = ptrace(RUREGS,pid,i,0); OD
X- #endif
X  }
X- 
X- 
X--- 284,290 ----
Xdiff -r -c /usr/src/bin/adb.old/setup.c /usr/src/bin/adb/setup.c
X*** /usr/src/bin/adb.old/setup.c	Thu Apr  5 21:55:51 1990
X--- /usr/src/bin/adb/setup.c	Fri Dec 31 11:08:43 1993
X***************
X*** 1,164 ****
X- /*
X-  *
X-  *      UNIX debugger
X-  *
X-  */
X- 
X  #include "defs.h"
X  
X  
X- MSG             BADNAM;
X- MSG             BADFIL;
X- 
X- MAP             txtmap;
X- MAP             datmap;
X- SYMSLAVE        *symvec;
X- INT             wtflag;
X- INT             kernel;
X- INT             fcor;
X- INT             fsym;
X- L_INT           maxfile;
X- L_INT           maxstor;
X- L_INT           txtsiz;
X- L_INT           datsiz;
X- L_INT           bss;
X- L_INT           datbas;
X- L_INT           stksiz;
X- STRING          errflg;
X- INT             magic;
X- L_INT           symbas;
X- L_INT           symnum;
X- L_INT           entrypt;
X- L_INT           var[];
X- 
X- long tell();
X- INT             argcount;
X- INT             signo;
X- POS             corhdr[ctob(USIZE)/sizeof(POS)];
X- POS             *uar0 = UAR0;
X- 
X- STRING          symfil  = "a.out";
X- STRING          corfil  = "core";
X- 
X- OVLVEC          ovlseg;
X- L_INT           ovlsiz;
X- L_INT           ovloff[NOVL+1];
X- OVTAG           startov;
X- int             overlay;
X- 
X- #define TXTHDRSIZ       (sizeof(TXTHDR))
X- #define OVLHDRSIZ       (sizeof(ovlseg))
X- 
X- #define HBIT    0100
X- 
X  setsym()
X  {
X! 	INT             relflg;
X! 	SYMSLAVE        *symptr;
X! 	SYMPTR          symp;
X! 	TXTHDR          txthdr;
X! 	CHAR		*sbrk();
X  
X  	fsym=getfile(symfil,1);
X  	txtmap.ufd=fsym;
X! 	IF read(fsym, txthdr, TXTHDRSIZ)==TXTHDRSIZ
X! 	THEN    magic=txthdr[0];
X! 		txtsiz = txthdr[1];
X! 		datsiz = txthdr[2];
X! 		bss = txthdr[3];
X! 		symnum = txthdr[4]/SYMTABSIZ;
X! 		entrypt = txthdr[5];
X! 		relflg = txthdr[7];
X! 		symbas = txtsiz+datsiz;
X! 		switch (magic)
X  		{
X! 			INT ovly;
X  
X  			case 0407:
X- 				txtmap.b1 = txtmap.b2 = 0;
X  				txtmap.e1 = txtmap.e2 = txtsiz+datsiz;
X! 				txtmap.f1 = txtmap.f2 = TXTHDRSIZ;
X  				break;
X- 
X  			case 0410:
X- 				txtmap.b1 = 0;
X  				txtmap.e1 = txtsiz;
X- 				txtmap.f1 = TXTHDRSIZ;
X  				txtmap.b2 = round(txtsiz, TXTRNDSIZ);
X  				txtmap.e2 = txtmap.b2+datsiz;
X! 				txtmap.f2 = txtsiz+TXTHDRSIZ;
X  				break;
X- 
X  			case 0405:
X  			case 0411:
X- 				txtmap.b1 = 0;
X  				txtmap.e1 = txtsiz;
X- 				txtmap.f1 = TXTHDRSIZ;
X- 				txtmap.b2 = 0;
X  				txtmap.e2 = datsiz;
X! 				txtmap.f2 = txtsiz+TXTHDRSIZ;
X  				break;
X- 
X  			case 0430:
X  			case 0431:
X! 				IF read(fsym, &ovlseg, OVLHDRSIZ) == OVLHDRSIZ
X! 				THEN    txtmap.b1 = 0;
X! 					txtmap.e1 = txtsiz;
X! 					txtmap.f1 = TXTHDRSIZ+OVLHDRSIZ;
X! 					txtmap.bo = round(txtsiz, TXTRNDSIZ);
X! 					txtmap.eo = 0;
X! 					txtmap.fo = 0;
X! 					FOR ovly = 0; ovly < NOVL; ovly++
X! 					DO      ovloff[ovly] = ovlsiz + txtsiz 
X! 							+TXTHDRSIZ+OVLHDRSIZ;
X! 						ovlsiz += ovlseg.ov[ovly];
X! 					OD
X! 					IF magic == 0430
X! 					THEN    txtmap.b2 =
X! 						round(txtmap.bo+(long)ovlseg.max, TXTRNDSIZ);
X! 					ELSE    txtmap.b2 = 0;
X! 					FI
X! 					txtmap.f2 = TXTHDRSIZ+OVLHDRSIZ+txtsiz+ovlsiz;
X! 					symbas += ovlsiz+OVLHDRSIZ;
X! 					txtmap.e2 = txtmap.b2 + datsiz;
X! 					overlay = 1;
X! 					break;
X  				FI
X! 
X! 			default:        magic = 0;
X! 					txtsiz = 0;
X! 					datsiz = 0;
X! 					bss = 0;
X! 					symnum = 0;
X! 					entrypt = 0;
X! 					relflg = 0;
X! 					symbas = 0;
X! 		}
X  		datbas = txtmap.b2;
X! 		IF relflg!=1 THEN symbas <<= 1; FI
X! 		symbas += TXTHDRSIZ;
X! 
X! 		/* set up symvec */
X! 		symvec=(SYMSLAVE *)sbrk(shorten((1+symnum))*sizeof (SYMSLAVE));
X! 		IF (symptr=symvec)==-1
X! 		THEN    printf("%s\n",BADNAM);
X! 			symptr=symvec=(SYMSLAVE *)sbrk(sizeof (SYMSLAVE));
X! 		ELSE if (symnum != 0) {
X! 			symset();
X! 			WHILE (symp=symget()) ANDF errflg==0
X! 			DO  symptr->valslave=symp->symv;
X! 			    symptr->typslave=SYMTYPE(symp->symf);
X! 			    symptr->ovlslave = symp->ovnumb;
X! 			    symptr++;
X! 			OD
X! 		    }
X! 		FI
X! 		symptr->typslave=ESYM;
X! 	FI
X  	IF magic==0 THEN txtmap.e1=maxfile; FI
X  }
X  
X- 
X  setcor()
X  {
X  	fcor=getfile(corfil,2);
X--- 1,106 ----
X  #include "defs.h"
X+ #include <sys/file.h>
X  
X+ 	MAP	txtmap;
X+ 	MAP	datmap;
X+ 	int	wtflag;
X+ 	int	kernel;
X+ 	int	fcor;
X+ 	int	fsym;
X+ 	long	maxfile;
X+ 	long	maxstor;
X+ 	long	txtsiz;
X+ 	long	datsiz;
X+ 	long	bss;
X+ 	long	datbas;
X+ 	long	stksiz;
X+ 	char	*errflg;
X+ 	int	magic;
X+ 	long	entrypt;
X+ 	long	var[];
X+ 	int	argcount;
X+ 	int	signo;
X+ 	u_int	corhdr[ctob(USIZE)/sizeof(u_int)];
X+ 	u_int	*uar0 = UAR0;
X+ 	char	*symfil  = "a.out";
X+ 	char	*corfil  = "core";
X+ 	struct	ovlhdr	ovlseg;
X+ 	long	ovlsiz;
X+ 	long	ovloff[NOVL+1];
X+ 	char	startov;
X+ 	int	overlay;
X+ 	off_t	symoff, stroff;
X  
X  setsym()
X  {
X! 	struct	xexec	hdr;
X! 	int ovly;
X  
X+ 	bzero(&txtmap, sizeof (txtmap));
X  	fsym=getfile(symfil,1);
X  	txtmap.ufd=fsym;
X! 
X! 	if	(read(fsym, &hdr, sizeof (hdr)) >= (int)sizeof (hdr.e))
X  		{
X! 		magic= hdr.e.a_magic;
X! 		txtsiz = hdr.e.a_text;
X! 		datsiz = hdr.e.a_data;
X! 		bss = hdr.e.a_bss;
X! 		entrypt = hdr.e.a_entry;
X  
X+ 		txtmap.f1 = N_TXTOFF(hdr.e);
X+ 		symoff = N_SYMOFF(hdr);
X+ 		stroff = N_STROFF(hdr);
X+ 
X+ 		switch (magic)
X+ 			{
X  			case 0407:
X  				txtmap.e1 = txtmap.e2 = txtsiz+datsiz;
X! 				txtmap.f2 = txtmap.f1;
X  				break;
X  			case 0410:
X  				txtmap.e1 = txtsiz;
X  				txtmap.b2 = round(txtsiz, TXTRNDSIZ);
X  				txtmap.e2 = txtmap.b2+datsiz;
X! 				txtmap.f2 = txtsiz + txtmap.f1;
X  				break;
X  			case 0405:
X  			case 0411:
X  				txtmap.e1 = txtsiz;
X  				txtmap.e2 = datsiz;
X! 				txtmap.f2 = txtsiz + txtmap.f1;
X  				break;
X  			case 0430:
X  			case 0431:
X! 				ovlseg = hdr.o;
X! 				txtmap.e1 = txtsiz;
X! 				txtmap.bo = round(txtsiz, TXTRNDSIZ);
X! 				FOR ovly = 0; ovly < NOVL; ovly++
X! 				DO      ovloff[ovly] = ovlsiz + txtsiz 
X! 						+ txtmap.f1;
X! 					ovlsiz += ovlseg.ov_siz[ovly];
X! 				OD
X! 				IF magic == 0430
X! 				THEN    txtmap.b2 =
X! 					round(txtmap.bo+(long)ovlseg.max_ovl, TXTRNDSIZ);
X  				FI
X! 				txtmap.f2 = txtmap.f1 + txtsiz+ovlsiz;
X! 				txtmap.e2 = txtmap.b2 + datsiz;
X! 				overlay = 1;
X! 				break;
X! 			default:
X! 				magic = 0;
X! 				txtsiz = 0;
X! 				datsiz = 0;
X! 				bss = 0;
X! 				entrypt = 0;
X! 			}
X  		datbas = txtmap.b2;
X! 		symINI(&hdr);
X! 		}
X  	IF magic==0 THEN txtmap.e1=maxfile; FI
X  }
X  
X  setcor()
X  {
X  	fcor=getfile(corfil,2);
X***************
X*** 178,186 ****
X  			datmap.e2 = 0140000L + ctob(USIZE);
X  		FI
X  		switch (magic)
X! 		{
X! 			INT ovly;
X! 
X  			case 0407:
X  				datmap.b1 = 0;
X  				datmap.e1 = txtsiz+datsiz;
X--- 120,126 ----
X  			datmap.e2 = 0140000L + ctob(USIZE);
X  		FI
X  		switch (magic)
X! 			{
X  			case 0407:
X  				datmap.b1 = 0;
X  				datmap.e1 = txtsiz+datsiz;
X***************
X*** 211,217 ****
X  
X  			case 0430:
X  				datmap.b1 = round(round(txtsiz,
X! 					TXTRNDSIZ)+ovlseg.max,
X  					TXTRNDSIZ);
X  				datmap.e1 = datmap.b1+datsiz;
X  				IF kernel
X--- 151,157 ----
X  
X  			case 0430:
X  				datmap.b1 = round(round(txtsiz,
X! 					TXTRNDSIZ)+ovlseg.max_ovl,
X  					TXTRNDSIZ);
X  				datmap.e1 = datmap.b1+datsiz;
X  				IF kernel
X***************
X*** 230,236 ****
X  				datmap.b2 = 0;
X  				datmap.e2 = 0;
X  				datmap.f2 = 0;
X! 		}
X  		datbas = datmap.b1;
X  		if (!kernel && magic) {
X  			/*
X--- 170,176 ----
X  				datmap.b2 = 0;
X  				datmap.e2 = 0;
X  				datmap.f2 = 0;
X! 			}
X  		datbas = datmap.b1;
X  		if (!kernel && magic) {
X  			/*
X***************
X*** 239,250 ****
X  			 * since the user structure no longer contains
X  			 * the exec header ...
X  			 */
X! 			register POS *ar0;
X! 			ar0 = (POS *)(((U *)corhdr)->u_ar0);
X! 			if (ar0 > (POS *)0140000
X! 			    && ar0 < (POS *)(0140000 + ctob(USIZE))
X  			    && !((unsigned)ar0&01))
X! 				uar0 = (POS *)&corhdr[ar0-(POS *)0140000];
X  			if (overlay) {
X  				startov = ((U *)corhdr)->u_ovdata.uo_curov;
X  				var[VARC] = (long)startov;
X--- 179,190 ----
X  			 * since the user structure no longer contains
X  			 * the exec header ...
X  			 */
X! 			register u_int *ar0;
X! 			ar0 = (u_int *)(((U *)corhdr)->u_ar0);
X! 			if (ar0 > (u_int *)0140000
X! 			    && ar0 < (u_int *)(0140000 + ctob(USIZE))
X  			    && !((unsigned)ar0&01))
X! 				uar0 = (u_int *)&corhdr[ar0-(u_int *)0140000];
X  			if (overlay) {
X  				startov = ((U *)corhdr)->u_ovdata.uo_curov;
X  				var[VARC] = (long)startov;
X***************
X*** 256,286 ****
X  	FI
X  }
X  
X- create(f)
X- STRING  f;
X- {       int fd;
X- 	IF (fd=creat(f,0644))>=0
X- 	THEN close(fd); return(open(f,wtflag));
X- 	ELSE return(-1);
X- 	FI
X- }
X- 
X  getfile(filnam,cnt)
X! STRING  filnam;
X  {
X! 	REG INT         fsym;
X  
X! 	IF !eqstr("-",filnam)
X! 	THEN    fsym=open(filnam,wtflag);
X! 		IF fsym<0 ANDF argcount>cnt
X  		THEN    IF wtflag
X! 			THEN    fsym=create(filnam);
X  			FI
X! 			IF fsym<0
X  			THEN printf("cannot open `%s'\n", filnam);
X  			FI
X  		FI
X! 	ELSE    fsym = -1;
X  	FI
X! 	return(fsym);
X  }
X--- 196,218 ----
X  	FI
X  }
X  
X  getfile(filnam,cnt)
X! 	char	*filnam;
X! 	int	cnt;
X  {
X! 	register int f;
X  
X! 	IF strcmp("-",filnam)
X! 	THEN    f = open(filnam,wtflag);
X! 		IF f < 0 ANDF argcount>cnt
X  		THEN    IF wtflag
X! 			THEN    f = open(filnam, O_CREAT|O_TRUNC|wtflag,644);
X  			FI
X! 			IF f < 0
X  			THEN printf("cannot open `%s'\n", filnam);
X  			FI
X  		FI
X! 	ELSE    f = -1;
X  	FI
X! 	return(f);
X  }
Xdiff -r -c /usr/src/bin/adb.old/sym.c /usr/src/bin/adb/sym.c
X*** /usr/src/bin/adb.old/sym.c	Sun Feb  8 14:25:47 1987
X--- /usr/src/bin/adb/sym.c	Sun Jan 16 17:03:07 1994
X***************
X*** 1,56 ****
X! #
X! /*
X!  *
X!  *	UNIX debugger
X!  *
X!  */
X! 
X! long lseek();
X  #include "defs.h"
X  
X  
X! MSG		BADFIL;
X  
X! SYMTAB		symbol;
X! BOOL		localok;
X! INT		lastframe;
X! SYMSLAVE		*symvec;
X! POS		maxoff;
X! L_INT		maxstor;
X! MAP		txtmap;
X! OVTAG		curov;
X! int		overlay;
X  
X! /* symbol management */
X! L_INT		symbas;
X! L_INT		symcnt;
X! L_INT		symnum;
X! L_INT		localval;
X! char		symrqd = -1;
X! SYMTAB		symbuf[SYMSIZ];
X! SYMPTR		symnxt;
X! SYMPTR		symend;
X  
X  
X- INT		fsym;
X- STRING		errflg;
X- POS		findsym();
X- 
X- 
X  /* symbol table and file handling service routines */
X  
X- longseek(f, a)
X- L_INT a;
X- {
X- 	return(lseek(f,a,0) != -1L);
X- }
X- 
X  valpr(v,idsp)
X  {
X! 	POS		d;
X  	d = findsym(v,idsp);
X  	IF d < maxoff
X! 	THEN	printf("%.8s", symbol.symc);
X  		IF d
X  		THEN	printf(OFFMODE, d);
X  		FI
X--- 1,51 ----
X! #include <stdio.h>
X  #include "defs.h"
X+ #include <fcntl.h>
X+ #include <sys/file.h>
X  
X+ 	struct	SYMbol	*symbol;
X+ 	char	localok;
X+ 	int	lastframe;
X+ 	u_int	maxoff;
X+ 	long	maxstor;
X+ 	MAP	txtmap;
X+ 	char	curov;
X+ 	int	overlay;
X+ 	long	localval;
X+ 	char	*errflg;
X+ 	u_int	findsym();
X  
X! 	struct	SYMcache
X! 		{
X! 		char	*name;
X! 		int	used;
X! 		struct	SYMbol *syment;
X! 		};
X  
X! #ifndef	NUM_SYMS_CACHE
X! #define	NUM_SYMS_CACHE	50
X! #endif
X  
X! static	struct	SYMcache symcache[NUM_SYMS_CACHE];
X! static	struct	SYMcache *endcache = &symcache[NUM_SYMS_CACHE];
X! static	struct	SYMbol	*symtab;
X! static	FILE	*strfp;
X! static	int	symcnt;
X! static	int	symnum;
X! static	char	*sgets();
X  
X+ extern	char	*myname, *symfil, *strdup();
X+ extern	off_t	symoff, stroff;
X  
X  /* symbol table and file handling service routines */
X  
X  valpr(v,idsp)
X  {
X! 	u_int	d;
X! 
X  	d = findsym(v,idsp);
X  	IF d < maxoff
X! 	THEN	printf("%s", cache_sym(symbol));
X  		IF d
X  		THEN	printf(OFFMODE, d);
X  		FI
X***************
X*** 58,174 ****
X  }
X  
X  localsym(cframe)
X! L_INT cframe;
X  {
X! 	INT symflg;
X! 	WHILE nextsym() ANDF localok
X! 		ANDF symbol.symc[0]!='~'
X! 		ANDF (symflg=(int)symbol.symf)!=037
X  	DO IF symflg>=2 ANDF symflg<=4
X! 	   THEN localval=symbol.symv;
X  		return(TRUE);
X  	   ELIF symflg==1
X! 	   THEN localval=leng(shorten(cframe)+symbol.symv);
X  		return(TRUE);
X  	   ELIF symflg==20 ANDF lastframe
X! 	   THEN localval=leng(lastframe+2*symbol.symv-(overlay?12:10));
X  		return(TRUE);
X  	   FI
X  	OD
X  	return(FALSE);
X  }
X  psymoff(v,type,s)
X! L_INT v; int type; char *s;
X  {
X! 	POS		w;
X  	w = findsym(shorten(v),type);
X  	IF w >= maxoff
X  	THEN printf(LPRMODE,v);
X! 	ELSE printf("%.8s", symbol.symc);
X  	     IF w THEN printf(OFFMODE,w); FI
X  	FI
X  	printf(s);
X  }
X  
X! POS	findsym(svalue,type)
X! POS	svalue;
X! INT	type;
X! {
X! 	L_INT		diff, value, symval, offset;
X! 	SYMFLG		symtyp;
X! 	REG SYMSLAVE	*symptr;
X! 	SYMSLAVE	*symsav;
X! 	OVTAG		ov = 0;
X! 	IF txtmap.bo ANDF type==ISYM ANDF svalue>=txtmap.bo
X! 	THEN	ov=curov; FI
X! 	value=svalue; diff = 0377777L; symsav=0;
X! 	IF type!=NSYM ANDF (symptr=symvec)
X! 	THEN	WHILE diff ANDF (symtyp=symptr->typslave)!=ESYM
X! 		DO  IF symtyp==type ANDF (!ov ORF ov==symptr->ovlslave)
X! 		    THEN symval=leng(symptr->valslave);
X! 			 IF value-symval<diff
X! 			    ANDF value>=symval
X! 			 THEN diff = value-symval;
X! 			      symsav=symptr;
X! 			 FI
X! 		    FI
X! 		    symptr++;
X! 		OD
X! 		IF symsav
X! 		THEN	offset=leng(symsav-symvec);
X! 			symcnt=symnum-offset;
X! 			longseek(fsym, symbas+offset*SYMTABSIZ);
X! 			read(fsym,&symbol,SYMTABSIZ);
X! 		FI
X! 	FI
X  /*
X! printf("name=%s,type=%d,ovl=%d,value=%o\n",symbol.symc,symbol.symf,symbol.ovnumb,symbol.symv);
X  */
X! 	return(shorten(diff));
X! }
X  
X! nextsym()
X! {
X! 	IF (--symcnt)<0
X! 	THEN	return(FALSE);
X! 	ELSE	return(longseek(fsym, symbas+(symnum-symcnt)*SYMTABSIZ)!=0 ANDF
X! 			read(fsym,&symbol,SYMTABSIZ)==SYMTABSIZ);
X! 	FI
X! }
X  
X  
X  
X! /* sequential search through file */
X! symset()
X! {
X! 	symcnt = symnum;
X! 	symnxt = symbuf;
X! 	IF symrqd
X! 	THEN	longseek(fsym, symbas);
X! 		symread(); symrqd=FALSE;
X! 	ELSE	longseek(fsym, symbas+sizeof symbuf);
X! 	FI
X! }
X  
X! SYMPTR	symget()
X! {
X! 	REG INT	rc;
X! 	IF symnxt >= symend
X! 	THEN	rc=symread(); symrqd=TRUE;
X! 	ELSE	rc=TRUE;
X! 	FI
X! 	IF --symcnt>0 ANDF rc==0 THEN errflg=BADFIL; FI
X! 	return( (symcnt>=0 && rc) ? symnxt++ : 0);
X! }
X  
X! symread()
X! {
X! 	INT		symlen;
X  
X! 	IF (symlen=read(fsym,symbuf,sizeof symbuf))>=SYMTABSIZ
X! 	THEN	symnxt = symbuf;
X! 		symend = &symbuf[symlen/SYMTABSIZ];
X! 		return(TRUE);
X! 	ELSE	return(FALSE);
X! 	FI
X! }
X--- 53,351 ----
X  }
X  
X  localsym(cframe)
X! 	long	cframe;
X  {
X! 	int symflg;
X! 
X! 	WHILE symget() && localok && (symflg= (int)symbol->type) != N_FN
X! 		&& *no_cache_sym(symbol) != '~'
X  	DO IF symflg>=2 ANDF symflg<=4
X! 	   THEN localval=symbol->value;
X  		return(TRUE);
X  	   ELIF symflg==1
X! 	   THEN localval=leng(shorten(cframe)+symbol->value);
X  		return(TRUE);
X  	   ELIF symflg==20 ANDF lastframe
X! 	   THEN localval=leng(lastframe+2*symbol->value - (overlay?12:10));
X  		return(TRUE);
X  	   FI
X  	OD
X  	return(FALSE);
X  }
X+ 
X  psymoff(v,type,s)
X! 	long v;
X! 	int type;
X! 	char *s;
X  {
X! 	u_int	w;
X! 
X  	w = findsym(shorten(v),type);
X  	IF w >= maxoff
X  	THEN printf(LPRMODE,v);
X! 	ELSE printf("%s", cache_sym(symbol));
X  	     IF w THEN printf(OFFMODE,w); FI
X  	FI
X  	printf(s);
X  }
X  
X! u_int
X! findsym(svalue,type)
X! 	u_int	svalue;
X! 	int	type;
X! 	{
X! 	long	diff, value, symval;
X! 	register struct SYMbol	*sp;
X! 	struct	SYMbol *symsav;
X! 	int	i;
X! 	char	ov = 0;
X! 
X! 	if	(txtmap.bo && type==ISYM && svalue>=txtmap.bo)
X! 		ov=curov;
X! 	value = svalue;
X! 	diff = 0377777L;
X! 
X! 	if	(type != NSYM && symnum)
X! 		{
X! 		for	(i = 0, sp = symtab; diff && i < symnum; i++, sp++)
X! 			{
X! 			if	(SYMTYPE(sp->type) == type && 
X! 					(!ov || ov == sp->ovno))
X! 				{
X! 				symval = leng(sp->value);
X! 				if	((value - symval) < diff && 
X! 						value >= symval)
X! 					{
X! 					diff = value - symval;
X! 					symsav = sp;
X! 					}
X! 				}
X! 			}
X! 		}
X! 	if	(symsav)
X! 		symcnt =  symsav - symtab;
X! 	symbol = symsav;
X! 	return(shorten(diff));
X! 	}
X! 
X! /* sequential search through table */
X! symset()
X! 	{
X! 
X! 	symcnt = -1;
X! 	}
X! 
X! struct SYMbol *
X! symget()
X! 	{
X! 
X! 	if	(symcnt >= symnum || !symnum)
X! 		return(NULL);
X! 	symcnt++;
X! 	symbol = &symtab[symcnt];
X! 	return(symbol);
X! 	}
X! 
X  /*
X!  * This only _looks_ expensive ;-)  The extra scan over the symbol
X!  * table allows us to cut down the amount of memory needed.  This is
X!  * where symbols with string table offsets over 64kb are excluded.  Also,
X!  * a late addition to the program excludes register symbols - the assembler
X!  * generates *lots* of them and they're useless to us.
X  */
X! symINI(ex)
X! 	struct	exec	*ex;
X! 	{
X! 	register struct	SYMbol	*sp;
X! 	register FILE	*fp;
X! 	struct	nlist	sym;
X! 	int	i, nused, globals_only = 0;
X  
X! 	fp = fopen(symfil, "r");
X! 	strfp = fp;
X! 	if	(!fp)
X! 		return;
X! 	fcntl(fileno(fp), F_SETFD, 1);
X  
X+ 	symnum = ex->a_syms / sizeof (sym);
X  
X+ 	fseek(fp, symoff, L_SET);
X+ 	nused = 0;
X+ 	for	(i = 0; i < symnum; i++)
X+ 		{
X+ 		fread(&sym, sizeof (sym), 1, fp);
X+ 		if	(sym.n_type == N_REG)
X+ 			continue;
X+ 		if	(sym.n_un.n_strx >= 0200000L)
X+ 			printf("symbol %d string offset > 64k - ignored\n",i);
X+ 		else
X+ 			nused++;
X+ 		}
X+ 	fseek(fp, symoff, L_SET);
X  
X! 	symtab = (struct SYMbol *)malloc(nused * sizeof (struct SYMbol));
X! 	if	(!symtab)
X! 		{
X! 		globals_only = 1;
X! 		nused = 0;
X! 		for	(symcnt = 0; symcnt < symnum; symcnt++)
X! 			{
X! 			fread(&sym, 1, sizeof (sym), fp);
X! 			if	(sym.n_type == N_REG)
X! 				continue;
X! 			if	((sym.n_type & N_EXT) == 0)
X! 				continue;
X! 			if	(sym.n_un.n_strx >= 0200000L)
X! 				continue;
X! 			nused++;
X! 			}
X! 		symtab = (struct SYMbol *)malloc(nused * sizeof(struct SYMbol));
X! 		if	(!symtab)
X! 			{
X! 			printf("%s: no memory for symbols\n", myname);
X! 			symnum = 0;
X! 			return;
X! 			}
X! 		}
X! 	fseek(fp, symoff, L_SET);
X! 	sp = symtab;
X! 	for	(symcnt = 0; symcnt < symnum; symcnt++)
X! 		{
X! 		fread(&sym, 1, sizeof (sym), fp);
X! 		if	(sym.n_type == N_REG)
X! 			continue;
X! 		if	(globals_only && !(sym.n_type & N_EXT))
X! 			continue;
X! 		if	(sym.n_un.n_strx >= 0200000L)
X! 			continue;
X! 		sp->value = sym.n_value;
X! 		sp->ovno = sym.n_ovly;
X! 		sp->type = sym.n_type;
X! 		sp->soff = shorten(sym.n_un.n_strx);
X! 		sp++;
X! 		}
X! 	symnum = nused;
X! #ifdef	debug
X! 	printf("%d symbols loaded\n", nused);
X! #endif
X! 	if	(globals_only)
X! 		printf("%s: could only do global symbols\n", myname);
X! 	symset();
X! 	return(0);
X! 	}
X  
X! /*
X!  * Look in the cache for a symbol in memory.  If it is not found use
X!  * the least recently used entry in the cache and update it with the
X!  * symbol name.
X! */
X! char	*
X! cache_sym(symp)
X! 	register struct	SYMbol *symp;
X! 	{
X! 	register struct SYMcache *sc = symcache;
X! 	struct	SYMcache *current;
X! 	int	lru;
X  
X! 	if	(!symp)
X! 		return("?");
X! 	for	(current = NULL, lru = 30000 ; sc < endcache; sc++)
X! 		{
X! 		if	(sc->syment == symp)
X! 			{
X! 			sc->used++;
X! 			if	(sc->used >= 30000)
X! 				sc->used = 10000;
X! 			return(sc->name);
X! 			}
X! 		if	(sc->used < lru)
X! 			{
X! 			lru = sc->used;
X! 			current = sc;
X! 			}
X! 		}
X! 	sc = current;
X! 	if	(sc->name)
X! 		free(sc->name);
X! 	sc->used = 1;
X! 	sc->syment = symp;
X! 	sc->name = strdup(sgets(symp->soff));
X! 	return(sc->name);
X! 	}
X  
X! /*
X!  * We take a look in the cache but do not update the cache on a miss.
X!  * This is done when scanning thru the symbol table (printing all externals
X!  * for example) for large numbers of symbols which probably won't be
X!  * used again any time soon.
X! */
X! char	*
X! no_cache_sym(symp)
X! 	register struct	SYMbol *symp;
X! 	{
X! 	register struct SYMcache *sc = symcache;
X! 
X! 	if	(!symp)
X! 		return("?");
X! 	for	( ; sc < endcache; sc++)
X! 		{
X! 		if	(sc == symp)
X! 			{
X! 			sc->used++;
X! 			if	(sc->used >= 30000)
X! 				sc->used = 10000;
X! 			return(sc->name);
X! 			}
X! 		}
X! 	return(sgets(symp->soff));
X! 	}
X! 
X! /*
X!  * Looks in the cache for a match by string value rather than string
X!  * file offset. 
X! */
X! 
X! struct	SYMbol *
X! cache_by_string(str, ovsym)
X! 	char	*str;
X! 	int	ovsym;
X! 	{
X! 	register struct SYMcache *sc;
X! 
X! 	for	(sc = symcache; sc < endcache; sc++)
X! 		{
X! 		if	(!sc->name)
X! 			continue;
X! 		if	(eqsym(sc->name, str, ovsym ? '~' : '_'))
X! 			break;
X! 		}
X! 	if	(sc < endcache)
X! 		{
X! 		sc->used++;
X! 		if	(sc->used > 30000)
X! 			sc->used = 10000;
X! 		return(sc->syment);
X! 		}
X! 	return(0);
X! 	}
X! 
X! static char *
X! sgets(soff)
X! 	u_short	soff;
X! 	{
X! 	static	char	symname[MAXSYMLEN + 2];
X! 	register char	*buf = symname;
X! 	int	c;
X! 	register int i;
X! 
X! 	fseek(strfp, stroff + soff, L_SET);
X! 	for	(i = 0; i < MAXSYMLEN; i++)
X! 		{
X! 		c = getc(strfp);
X! 		*buf++ = c;
X! 		if	(c == '\0')
X! 			break;
X! 		}
X! 	*buf = '\0';
X! 	return(symname);
X! 	}
SHAR_EOF
fi
exit 0
#	End of shell archive
