|
|
researchv8 Dan Cross
/*
* adb - symbol table routines
*/
#include "defs.h"
#include <a.out.h>
#include <stab.h>
#include <sys/types.h>
/*
* Lookup a symbol by name
* leave a pointer to the symbol in cursym
*/
struct nlist *
lookup(symstr)
register char *symstr;
{
register struct nlist *sp;
cursym = 0;
if (symtab)
for (sp = symtab; sp < esymtab; sp++)
switch (sp->n_type &~ N_EXT) {
case N_FUN:
case N_STSYM:
case N_TEXT:
case N_DATA:
case N_BSS:
case N_ABS:
if (eqsym(sp->n_un.n_name, symstr, '_'))
return(cursym = sp);
}
return (0);
}
/*
* find the symbols for a routine
*/
int
findrtn(rtn)
char *rtn;
{
register struct nlist *sp;
cursym = 0;
if (symtab)
for (sp = symtab; sp < esymtab; sp++)
switch (sp->n_type &~ N_EXT) {
case N_FUN:
case N_TEXT:
if (eqsym(sp->n_un.n_name, rtn, '_')) {
cursym = sp;
return (1);
}
}
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.
*/
WORD
findsym(val, type)
register WORD val;
int type;
{
register WORD diff;
register struct nlist *sp;
cursym = 0;
diff = HUGE;
if ((type & SPTYPE) == NOSP || symtab == 0)
return (diff);
for (sp = symtab; sp < esymtab; sp++)
switch (sp->n_type) {
case N_TEXT|N_EXT:
case N_DATA|N_EXT:
case N_BSS|N_EXT:
case N_ABS|N_EXT:
case N_FUN:
case N_STSYM:
/* data objects? */
/* should look at type here */
if (val - sp->n_value < diff && val >= sp->n_value) {
diff = val - sp->n_value;
cursym = sp;
if (diff == 0)
break;
}
}
if (cursym && cursym->n_value == 0 && diff != 0)
return (HUGE);
return (diff);
}
/*
* advance cursym to the next local variable
* return 0 if the next variable is a global
*/
int
localsym()
{
register struct nlist *sp;
if (cursym == NULL)
return (0);
for (sp = cursym; ++sp < esymtab; )
switch (sp->n_type) {
case N_TEXT:
case N_DATA:
if (sp->n_un.n_name[0] == '_') /* C global */
return (0);
continue;
case N_LSYM:
case N_PSYM:
case N_RSYM:
case N_STSYM:
cursym = sp;
return (1);
case N_FUN:
case N_EFUN:
return (0);
}
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.
*/
psymoff(v, type, s)
WORD v;
int type;
char *s;
{
WORD w;
int r;
if ((type & SPTYPE) == REGSP) {
printf("%%%R", v);
printf(s);
return;
}
if (v)
w = findsym(v, type);
if (v==0 || w >= maxoff)
printf("%R", v);
else {
printf("%s", cursym->n_un.n_name);
if (w)
printf("+%R", 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)
WORD v;
{
WORD d;
d = findsym(v, idsp);
if (d >= maxoff)
return;
printf("%s", cursym->n_un.n_name);
if (d)
printf("+%R", d);
}
eqsym(s1, s2, c)
register char *s1, *s2;
{
if (!strcmp(s1,s2))
return (1);
if (*s1 == c && !strcmp(s1+1, s2))
return (1);
return (0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.