4.4BSD/usr/src/old/sdb/TESTS/new

/*
 * 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);
}