Subject: adb incorrect prints function arguments, local variables and external symbols
Index:	 src/bin/adb/expr.c,findfn.c,print.c,sym.c

Description:
	1) $c and $C do not show argc and argv for main().

	2) $C prints the wrong values for local variables and is offset by
	   a stackframe.

	3) $e displays far too much information unrelated to the names and 
	   values of external variables.

Repeat-By:
	This has been broken almost forever.  Amazing it's not been commented
	on before this.

	Compile the following program and invoke adb

-------- x.c ------
main(argc, argv)
	int argc;
	char **argv;
	{
	int i = 0;

	foo(i);
	exit(0);
	}

foo(j)
    int j;
    {
    j++;
    }
---------

cc x.c
adb a.out
foo+4:b
:r

a.out: running
breakpoint      ~foo+04:        br      ~foo+016
adb>$c
vernon.4-> ./adb a.out
0177342: ~foo(0) from ~main+022
0177362: ~main() from start+0104

	note that main() has no arguments displayed

adb> $C
0177450: ~foo(0) from ~main+022
        argc:       0
        argv:       0
        i:          0522
0177470: ~main() from start+0104

	note that argc and argv are displayed for the function foo() rather than
	main().  Also observe the value of 'i' local variable  is given as 0522
	instead of 0

adb> $e
crt0.o:     0170011
x.o:        04567
~main:      04567
argc:       04
argv:       010600
i:          036505
~foo:       04567
j:          04
rindex.o:   016600
exit.o:     04567
fakcu.o:    04567
fakcu.o:    0170011
~_cleanup:  04567
_exit.o:    0104401
_exit.o:    0170011
csv.o:      012700
_environ:   0177400
___progname:            0177424
_strrchr:   016600
_exit:      04567
_main:      04567
start:      0170011
mcount:     0207
_moncontrol:            0207
csv:        010501
_foo:       04567
cret:       010502
_rindex:    016600
__cleanup:  04567
__exit:     0104401
_errno:     0
x_norm:     0103004
x_error:    010067
__ovno:     0
_etext:     0177424
ovhndlr1:   012700
ovhndlr2:   012700
ovhndlr3:   012700
ovhndlr4:   012700
ovhndlr5:   012700
ovhndlr6:   012700
ovhndlr7:   012700
ovhndlr8:   012700
ovhndlr9:   012700
ovhndlra:   012700
ovhndlrb:   012700
ovhndlrc:   012700
ovhndlrd:   012700
ovhndlre:   012700
ovhndlrf:   012700
:   0177777
data address not found

	AFTER applying the patch below:

vernon.3-> adb a.out
adb> foo+4:b  
adb> :r
a.out: running
breakpoint      ~foo+04:        br      ~foo+016

adb> $c
0177450: ~foo(0) from ~main+022
0177470: ~main(01,0177502) from start+0104

adb> $C
0177450: ~foo(0) from ~main+022
        j:          0
0177470: ~main(01,0177502) from start+0104
        argc:       01
        argv:       0177502
        i:          0

adb> $e
_environ:       0177400
___progname:    0177424
_errno:         0
__ovno:         0

Fix:
	Many thanks to martin@teckelworks.com for providing the fix with
	this description:

   The $c/$C issues were that the code that tries to figure out how many 
   arguments there was looking at the instructions that set up the call stack.
   In the case of main(), it was thinking there 0 arguments because crt0.s 
   doesn't do the normal call routine it was expecting. I fixed it by hard 
   coding 2 if the previous frame pointer is 0 as that is how crt0 sets it up.

   The other $c/$C issue was that the routine that was printing the caller in 
   the call stack was resetting the symbol table pointer position which 
   is why everything was off by one frame. There are WAY too many globals in 
   that code!

   $e was printing a bunch of other stuff besides the external data and bss 
   variables.

	Cut where indicated and save to a file (/tmp/486.patch).  Then:

cd /
patch -p0 < /tmp/486.patch
cd /usr/src/bin/adb
make install
make clean

	This and previous updates to 2.11BSD are available at the following
	locations:
	
	ftp://ftp.dfupdate.se/pub/pdp11/2.11BSD
	https://www.tuhs.org/Archive/Distributions/UCB/2.11BSD/Patches/
	ftp://ftp.2bsd.com/2.11BSD
	http://www.2bsd.com/2.11BSD

	Most (all) Web browsers have removed ftp: URL support and will need to
	use the http: links.  Commandline users with an ftp client  (found at
	https://ftp.gnu.org/gnu/inetutils/) can use anonymous ftp as always.

---------------------------cut here--------------------
*** ./usr/src/bin/adb/expr.c.old	Fri Jan 14 00:59:27 1994
--- ./usr/src/bin/adb/expr.c	Wed Mar 19 06:16:02 2025
***************
*** 247,253 ****
  {
  	register struct SYMbol *symp, *sc;
  
! 	symset();
  	while	(symp = symget())
  		{
  	   	if	(overlay && (symp->type == ISYM))
--- 247,253 ----
  {
  	register struct SYMbol *symp, *sc;
  
! 	symset(-1);
  	while	(symp = symget())
  		{
  	   	if	(overlay && (symp->type == ISYM))
*** ./usr/src/bin/adb/print.c.old	Sun Jul 25 23:10:45 1999
--- ./usr/src/bin/adb/print.c	Wed Mar 19 06:16:02 2025
***************
*** 213,222 ****
--- 213,230 ----
   			printf(") from ");
   			{
  				int	savmaxoff = maxoff;
+ 				int	save_symcnt;
  
+ 				/* we need to save symcnt variable as psymoff
+ 				** is going to change it and then the local
+ 				** symbol dump is going to be off by a frame */
+ 
+ 				save_symcnt = sympos();
+ 
   				maxoff = ((unsigned)-1)>>1;
   				psymoff((long)callpc,ISYM,"");
   				maxoff = savmaxoff;
+ 				symset(save_symcnt);
   			}
   			printc('\n');
  
***************
*** 240,250 ****
  
  	    /*print externals*/
  	    case 'e': case 'E':
! 		symset();
  		WHILE (symp=symget())
  		DO chkerr();
! 		   IF (symp->type == N_EXT|N_DATA) || (symp->type== N_EXT|N_BSS)
! 		   THEN printf("%s:%12t%o\n", no_cache_sym(symp),
  				get(leng(symp->value),DSP));
  		   FI
  		OD
--- 248,258 ----
  
  	    /*print externals*/
  	    case 'e': case 'E':
! 		symset(-1);
  		WHILE (symp=symget())
  		DO chkerr();
! 		   IF (symp->type == (N_EXT|N_DATA)) || (symp->type == (N_EXT|N_BSS))
! 		   THEN printf("%s:%16t%o\n", no_cache_sym(symp),
  				get(leng(symp->value),DSP));
  		   FI
  		OD
*** ./usr/src/bin/adb/sym.c.old	Sun Jan 16 19:03:07 1994
--- ./usr/src/bin/adb/sym.c	Wed Mar 19 06:16:02 2025
***************
*** 129,140 ****
  	}
  
  /* sequential search through table */
! symset()
  	{
  
! 	symcnt = -1;
  	}
  
  struct SYMbol *
  symget()
  	{
--- 129,145 ----
  	}
  
  /* sequential search through table */
! symset(int cnt)
  	{
  
! 	symcnt = cnt;
  	}
  
+ int sympos()
+ {
+ 	return symcnt;
+ }
+ 
  struct SYMbol *
  symget()
  	{
***************
*** 230,236 ****
  #endif
  	if	(globals_only)
  		printf("%s: could only do global symbols\n", myname);
! 	symset();
  	return(0);
  	}
  
--- 235,241 ----
  #endif
  	if	(globals_only)
  		printf("%s: could only do global symbols\n", myname);
! 	symset(-1);
  	return(0);
  	}
  
*** ./usr/src/bin/adb/findfn.c.old	Wed Jan 12 21:52:31 1994
--- ./usr/src/bin/adb/findfn.c	Wed Mar 19 06:16:02 2025
***************
*** 33,39 ****
  	IF (inst=get(leng(callpc-4), ISP)) == 04737	/* jsr pc,*$... */
  	THEN	narg = 1;
  	ELIF (inst&~077)==04700			/* jsr pc,... */
! 	THEN	narg=0; v=(inst!=04767);
  	ELIF (back2&~077)==04700
  	THEN	narg=0; v=TRUE;
  	ELSE	errflg=NOCFN;
--- 33,40 ----
  	IF (inst=get(leng(callpc-4), ISP)) == 04737	/* jsr pc,*$... */
  	THEN	narg = 1;
  	ELIF (inst&~077)==04700			/* jsr pc,... */
! 	THEN	narg=(get(cframe, DSP) ? 0 : 2); /* top fp? main(argc, argv)? */
! 		v=(inst!=04767);
  	ELIF (back2&~077)==04700
  	THEN	narg=0; v=TRUE;
  	ELSE	errflg=NOCFN;
*** ./VERSION.old	Fri Mar 14 16:27:46 2025
--- ./VERSION	Fri Mar 21 06:33:48 2025
***************
*** 1,5 ****
! Current Patch Level: 485
! Date: March 14, 2025
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 486
! Date: March 21, 2025
  
  2.11 BSD
  ============
