date and time created 81/05/14 15:19:59 by root
authorBill Joy <root@ucbvax.Berkeley.EDU>
Fri, 15 May 1981 06:19:59 +0000 (22:19 -0800)
committerBill Joy <root@ucbvax.Berkeley.EDU>
Fri, 15 May 1981 06:19:59 +0000 (22:19 -0800)
SCCS-vsn: old/adb/adb.vax/sym.c 4.1

usr/src/old/adb/adb.vax/sym.c [new file with mode: 0644]

diff --git a/usr/src/old/adb/adb.vax/sym.c b/usr/src/old/adb/adb.vax/sym.c
new file mode 100644 (file)
index 0000000..7b4a6f3
--- /dev/null
@@ -0,0 +1,148 @@
+static char sccsid[] = "@(#)sym.c 4.1 %G%";
+/*
+ * adb - symbol table routines
+ */
+#include "defs.h"
+#include <stab.h>
+
+/*
+ * Lookup a symbol by name.
+ */
+struct nlist *
+lookup(symstr)
+       char *symstr;
+{
+       register struct nlist *sp;
+
+       cursym = 0;
+       if (symtab)
+       for (sp = symtab; sp < esymtab; sp++)
+               /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
+               if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
+                       return(cursym = sp);
+       return (0);
+}
+
+/*
+ * Find the closest symbol to val, and return
+ * the difference between val and the symbol found.
+ * Leave a pointer to the symbol found as cursym.
+ */
+findsym(val, type)
+       long val;
+       int type;
+{
+       long diff;
+       register struct nlist *sp;
+
+       cursym = 0;
+       diff = MAXINT;
+       if (type == NSYM || symtab == 0)
+               return (diff);
+       for (sp = symtab; sp < esymtab; sp++) {
+               if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0)
+                       continue;
+               if (val - sp->n_value < diff && val >= sp->n_value) {
+                       diff = val - sp->n_value;
+                       cursym = sp;
+                       if (diff == 0)
+                               break;
+               }
+       }
+       return (diff);
+}
+
+/*
+ * Advance cursym to the next local variable.
+ * Leave its value in localval as a side effect.
+ * Return 0 at end of file.
+ */
+localsym(cframe, cargp)
+       ADDR cframe, cargp;
+{
+       register int type;
+       register struct nlist *sp;
+
+       if (cursym)
+       for (sp = cursym; ++sp < esymtab; ) {
+               if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN)
+                       return (0);
+               type = sp->n_type;
+               switch (sp->n_type) {
+
+               case N_TEXT:
+               case N_TEXT|N_EXT:
+               case N_DATA:
+               case N_DATA|N_EXT:
+               case N_BSS:
+               case N_BSS|N_EXT:
+                       localval = sp->n_value;
+                       cursym = sp;
+                       return (1);
+
+               case N_LSYM:
+                       localval = cframe - sp->n_value;
+                       cursym = sp;
+                       return (1);
+
+               case N_PSYM:
+                       /* code below works since n_value > 0 */
+               case N_ABS:
+                       if (sp->n_value < 0)
+                               localval = cframe + sp->n_value;
+                       else
+                               localval = cargp + sp->n_value;
+                       cursym = sp;
+                       return (1);
+               }
+       }
+       cursym = 0;
+       return (0);
+}
+
+/*
+ * Print value v and then the string s.
+ * If v is not zero, then we look for a nearby symbol
+ * and print name+offset if we find a symbol for which
+ * offset is small enough.
+ *
+ * For values which are just into kernel address space
+ * that they match exactly or that they be more than maxoff
+ * bytes into kernel space.
+ */
+psymoff(v, type, s)
+       long v;
+       int type;
+       char *s;
+{
+       long w;
+
+       if (v) 
+               w = findsym(v, type);
+       if (v==0 || w >= maxoff || (KVTOPH(v) < maxoff && w))
+               printf(LPRMODE, v);
+       else {
+               printf("%s", cursym->n_un.n_name);
+               if (w)
+                       printf(OFFMODE, w);
+       }
+       printf(s);
+}
+
+/*
+ * Print value v symbolically if it has a reasonable
+ * interpretation as name+offset.  If not, print nothing.
+ * Used in printing out registers $r.
+ */
+valpr(v, idsp)
+       long v;
+{
+       off_t d;
+
+       d = findsym(v, idsp);
+       if (d >= maxoff)
+               return;
+       printf("%s", cursym->n_un.n_name);
+       if (d)
+               printf(OFFMODE, d);
+}