|
|
BSD 4.0
/*
* These macros are used to speak ``offsets'' to the outside world,
* so that we can use the other source files for sdb essentially
* unchanged, even though they believe that we work with symbol
* table offsets, and we really have the whole symbol table in
* core and would prefer to just work with pointers into it.
*/
#define sptooff(sp) (ststart + (int)(sp) - (int)(symtab))
#define offtosp(off) (&symtab[((off) - ststart) / sizeof (struct nlist))
/*
* Initialize the file and procedure tables.
*
* This routine rummages through the symbol table and builds tables
* of the files and procedures referenced there, sorting the latter
* table into address order. These tables are used in the other
* routines defined here.
*
* NB:
*
* In this version of sdb we could well dispense with most of the
* fields of these tables, since we have the symbol table in core,
* but for compatibility for the time being we duplicate the information
* so older code in other sdb files will work unchanged.
*/
initfp()
{
register struct nlist *sp;
register struct proct *procp;
register struct filet *filep;
struct stat stb;
int nfile, nproc;
int class;
extern int compar(); /* Sort routine for procedure table */
firstdata = MAXPOS;
/*
* Since the symbol table is in core, we can afford
* two passes over it to avoid messy allocation strategies
* for these tables, who sizes are as yet unknown.
*/
nfile = 0;
nproc = 0;
for (sp = symtab; sp < esymtab; sp++) switch (sp->n_type & STABMASK) {
case N_SO:
case N_SOL:
nfile++;
continue;
case N_TEXT:
if (sp->n_name[0] == '_')
nfile++;
continue;
case N_FUN:
case N_ENTRY:
nfile++;
continue;
}
files = calloc(nfile+1, sizeof (struct filet));
procs = calloc(nfile+1, sizeof (struct filet));
if (files == 0 || procs == 0) {
printf("Couldn't get space for file/procedure tables\n");
exit(1);
}
if (nfiles == 0)
printf("Warning: `%s' not compiled with -g\n", symfil);
procp = procs;
filep = files;
for (sp = symtab; sp < esymtab; sp++) {
class = sp->n_type & STABMASK;
switch (class) {
case N_SO:
case N_SOL:
filep->faddr = sp->n_value;
filep->lineflag = (class == N_SOL);
filep->stf_offset = sptooff(sp);
filep->sfilename = sp->n_name;
strcpy(fp, filep->sfilename);
if (stat(filework, &stb) == -1)
printf("Warning: `%s' not found\n",
filep->sfilename);
else if (stb.st_mtime > symtime)
printf("Warning: `%s' newer than `%s'\n",
filep->sfilename, symfil);
filep++;
break;
case N_TEXT:
if (stentry.n_name[0] != '_')
break;
case N_FUN:
case N_ENTRY:
procp->pname = sp->n_name;
procp->paddr = sp->n_value;
procp->st_offset = sptooff(sp);
if (class != N_TEXT) {
procp->sfptr = filep - 1;
procp->lineno = so->n_desc;
} else {
procp->sfptr = badfile;
procp->lineno = 0;
}
procp->entrypt = class == N_ENTRY;
procp++;
break;
}
if (sp->n_type & N_EXT) {
if (!extstart)
extstart = sp;
/* THIS LOOKS WRONG !!! SHOULD BE (x || y) && z ??? */
if (sp->n_type == (N_DATA+N_EXT) ||
sp->n_type == (N_BSS+N_EXT) ||
sp->n_value < firstdata)
firstdata = sp->n_value;
}
}
if (filep != &files[nfile] || procp != &procs[nproc]) {
printf("initfp botch - tell someone\n");
exit(1);
}
/*
* Now have the file and procedure tables.
* Sort the procedure table, and initialize the boundary
* elements of the tables.
*/
qsort(procs, procp-procs, sizeof procs[0], compar);
badproc = procp;
badfile = filep;
badproc->st_offset = esymtab;
badproc->sfptr = badfile;
badproc->pname = badfile->sfilename = "";
setcur(1);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.