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=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=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 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 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; iu_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; ivalslave=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 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 X #include "defs.h" X+ #include X+ #include 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=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