File:  [Research Unix] / researchv9 / jtools / src / pi / ed8symtab.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "ed8.h"
#include "symtab.pri"
#include "dtype.pri"
#include "symbol.h"
SRCFILE("ed8symtab.c")

char *N_Name(int n_type)
{
	char *type;
	static char name[64];

	switch( n_type&~N_EXT ){
		default:	type = Name("N_0x%X", n_type );
		case N_ABS:	type = "ABS";		break;
		case N_BCOMM:	type = "BCOMM";		break;
		case N_BSS:	type = "BSS";		break;
		case N_BSTR:	type = "BSTR";		break;
		case N_COMM:	type = "COMM";		break;
		case N_DATA:	type = "DATA";		break;
		case N_DIM:	type = "DIM";		break;
		case N_ECOML:	type = "ECOML";		break;
		case N_ECOMM:	type = "ECOMM";		break;
		case N_BFUN:	type = "BFUN";		break;
		case N_EFUN:	type = "EFUN";		break;
		case N_ENTRY:	type = "ENTRY";		break;
		case N_ESO:	type = "ESO";		break;
		case N_ESTR:	type = "ESTR";		break;
		case N_FN:	type = "FN";		break;
		case N_FNAME:	type = "FNAME";		break;
		case N_GSYM:	type = "GSYM";		break;
		case N_LBRAC:	type = "LBRAC";		break;
		case N_LCSYM:	type = "LCSYM";		break;
		case N_LENG:	type = "LENG";		break;
		case N_LSYM:	type = "LSYM";		break;
		case N_PSYM:	type = "PSYM";		break;
		case N_RBRAC:	type = "RBRAC";		break;
		case N_RFUN:	type = "RFUN";		break;
		case N_RSYM:	type = "RSYM";		break;
		case N_SFLD:	type = "SFLD";		break;
		case N_SLINE:	type = "SLINE";		break;
		case N_SO:	type = "SO";		break;
		case N_SOL:	type = "SOL";		break;
		case N_SSYM:	type = "SSYM";		break;
		case N_STSYM:	type = "STSYM";		break;
		case N_TEXT:	type = "TEXT";		break;
		case N_TYID:	type = "TYID";		break;
		case N_UNDF:	type = "UNDF";		break;
		case N_VER:	type = "VER";		break;
	}
	sprintf( name, "%s%s", type, n_type&N_EXT ? "'" : "" );
	return name;
}

DType Ed8SymTab::chain(int t, nlist *n)
{
	DType d;

	trace( "%d.chain(0%o,%d) %s", this, t, n, PccName(t) );
	if( t&TMASK ){
		d.pcc = t&TMASK;
		d.univ = new DType;
		*(d.ref()) = chain(DECREF(t), n);
	} else {
		d.pcc = t;
		if((t==STRTY || t==ENUMTY || t==UNIONTY) && (++n)->n_type==N_TYID) 
			d.univ = idtosym(U_UTYPE,n->n_un.n_name,0);
	}
	return d;
}

DType Ed8SymTab::gatherdtype(nlist *n)
{
	DType d, *dp;

	trace( "%d.gatherdtype(%d)", this, n);
	d = chain(n->n_desc,n);
	if( (++n)->n_type==N_TYID ) ++n;
	for( dp = &d; dp; dp = dp->ref() )
		if( dp->isary() && n->n_type==N_DIM )
			dp->dim = n++->n_value;
	trace( "%s", d.text() );
	return d;
}

Ed8SymTab::Ed8SymTab(Core* c, int fd, SymTab *i):(c, fd, i)
{
	hdr = new exec;
}

Ed8SymTab::~Ed8SymTab() { delete hdr; }

char *Ed8SymTab::gethdr()
{
	trace( "%d.gethdr()", this );	OK( "Ed8SymTab::gethdr" );
	if( lseek( fd, 0L, 0 ) == -1 || !ReadOK(fd, (char*)hdr, sizeof *hdr) )
		return SysErr( "symbol table: " );
	_magic = hdr->a_magic;
	if( N_BADMAG(*hdr) || hdr->a_trsize || hdr->a_drsize )
		return "symbol table: not executable text";
	entries = hdr->a_syms/sizeof(nlist);
	return 0;
}

Block *Ed8SymTab::gatherfunc(Func *func)
{
	register struct nlist *f, *n;
	register Block *ablk, *lblk;
	Var *arg = 0, *lcl = 0;
	register Stmt *stmt = 0;
	long bfun = func->begin, size = func->size, i, inasrc = 1;
	char *so = func->source()->_text;

	++FunctionGathered;
	SymbolStats();
	trace( "%d.gatherfunc(%d,%d,%s)", this, bfun, size, so );	OK(0);
	IF_LIVE( bfun < 0 || bfun+size > entries ) return 0;
	if (size == 0)
		return fakeblk();
	if( !(n = f = nlistvector(bfun,size)) ) return 0;
	IF_LIVE( n->n_type != N_BFUN ) return 0;
	ablk = new Block( this, 0, 0, sf("%s().arg_blk",n->n_un.n_name) );
	lblk = new Block( this, ablk, 0, sf("%s().lcl_blk",n->n_un.n_name) );
	ablk->child = lblk;
	for( i = 0; i < size; ++i, ++n ){
		if( n->n_type == N_SOL ){
			inasrc = eqstr( n->n_un.n_name, so );
			n->n_type = N_SLINE;
		}
		if( !inasrc ) continue;
		switch( n->n_type ){
		case N_PSYM:
			gathervar( n, &arg, ablk, U_ARG );
			break;
		case N_LSYM:
			gathervar( n, &lcl, lblk, U_AUT );
			lcl->range.lo = - lcl->range.lo;	/* VAX */
			break;
		case N_STSYM:
		case N_LCSYM:
			gathervar( n, &lcl, lblk, U_STA );
			break;
		case N_RSYM:
			gathervar( n, &lcl, lblk, U_REG );
			break;
		case N_BFUN:
		case N_RFUN:
		case N_SLINE:					// cfront screws up
			if( stmt && n->n_desc > stmt->lineno )
				func->lines.hi = n->n_desc;
			if( stmt ) stmt->range.hi = n->n_value;
			stmt = new Stmt(this,lblk,stmt);
			if( !ablk->stmt ) ablk->stmt = stmt;
			stmt->lineno = n->n_desc;
			stmt->range.lo = n->n_value;
			if( !ablk->range.lo )
				ablk->range.lo = n->n_value;
			ablk->range.hi = n->n_value;
			break;
		case N_EFUN:
			if( stmt ) stmt->range.hi = n->n_value;
			goto BreakOut;
		}
	}
BreakOut:
	delete f;
	uncfront( ablk->var, (char *)0 );
	uncfront( lblk->var, (char *)0 );
	return ablk;
}

void Ed8SymTab::gathervar( nlist *n, Var **v, Block *b, UDisc d )
{
	trace( "%d.gathervar(%d,%d,%d,%d)", n, v, b, d ); VOK;
	IF_LIVE( !v ) return;
	*v = new Var( this, b, *v, d, n->n_un.n_name );
	if( b && !b->var ) b->var = *v;
	(*v)->range.lo = n->n_value;
	(*v)->type = gatherdtype(n);
}

char *Ed8SymTab::gettbl()
{
	trace( "%d.gettbl()" ); OK("SymTab.gettbl");
	base = new nlist[entries];
	symoff = (nlist*)N_SYMOFF(*hdr);
	if( lseek(fd, (long)symoff, 0) == 1
	 || !ReadOK(fd, (char*)base, hdr->a_syms)
	 || !ReadOK(fd, (char*)&strsize, 4) ){
		delete base; base = 0;
		return SysErr( "symbol table: " );
	}
	strings = new char[strsize];
	if( lseek( fd, -4, 1 ) == -1 || !ReadOK(fd, strings, strsize) ){
		delete strings; strings = 0;
		delete base; base = 0;
		return SysErr( "strings table: " );
	}
	strcpy( strings, "???" );	/* zero string index */
	return 0;
}

Source *Ed8SymTab::tree()
{
	register nlist	*n, *base_entries, *r;
	Source		*src = 0;
	Func		*func = 0;
	Block		*fake = fakeblk();
	Var		*glb = 0, *fst = 0, *resolve;
	UType		*u;
	register long	regstrings, inafunc = 0, inasrc = 0;
	
	trace( "%d.tree()", this ); OK(0);
	if( _warn = gettbl() ) return 0;
	base_entries = base+entries;
	regstrings = (long) strings;
	glb = globregs(_blk, 18 );
	for( n = base; n < base_entries; ++n ){
		n->n_un.n_strx += (long) regstrings;
		switch( n->n_type ){
		case N_BSTR:
			for( r = n+1; r->n_type != N_ESTR; ++r ) {}
			if( u = (UType*) idtosym(U_UTYPE,n->n_un.n_name,0) ){
				if( u->size<r+1-n ){	/* use the biggest */
					u->size = r+1-n;
					u->begin = n-base;
					u->range.lo = r->n_value;
					u->type.pcc = n->n_desc;
				}
				break;
			}
			++UTypeStubs;
			u = new UType(this, n-base, r+1-n, n->n_un.n_name );
			u->range.lo = r->n_value;
			u->type.pcc = n->n_desc;
			u->type.univ = u;
			u->rsib = utype;
			utype = u;
		}
	}
	for( n = base; n < base_entries; ++n ){
		switch( n->n_type ){
		case N_ABS|N_EXT:
			if( n->n_un.n_name[0] != '_' ) break;	/* ? */
		case N_BSS|N_EXT:
		case N_DATA|N_EXT:
			if( *n->n_un.n_name == '_' ) ++n->n_un.n_name;
			resolve = (Var*)idtosym(U_GLB, n->n_un.n_name, 0);
			if( resolve ){
				if( !resolve->range.lo )
					resolve->range.lo = n->n_value;
			} else {
				n->n_desc = LONG;
				gathervar( n, &glb, _blk, U_GLB );
				break;
			}
			break;
		case N_GSYM:
			if( !inasrc || inafunc ) break;
			if( !idtosym(U_GLB, n->n_un.n_name, 0) )
				gathervar( n, &glb, _blk, U_GLB );
			break;
		case N_LCSYM:
		case N_STSYM:
			if( !inasrc || inafunc || !src || !src->blk ) break;
			gathervar( n, &fst, src->blk, U_FST );
			break;

		case N_SO:
			inasrc = 1;
			src = new Source(this,src,n->n_un.n_name,0);
			func = 0;
			inafunc = 0;
			fst = 0;
			break;
		case N_SOL:
			inasrc = src && eqstr(src->_text,n->n_un.n_name);
			break;
		case N_TEXT|N_EXT:
			if( *n->n_un.n_name == '_' ) ++n->n_un.n_name;
			if( idtosym(U_FUNC, n->n_un.n_name, 0) ) break;
			func = new Func(this,0,0,0,n->n_un.n_name);
			func->range.lo = n->n_value;
			func->_blk = fake;
			DType *t = new DType;
			t->pcc = LONG;
			func->type = t->incref();
			func->type.pcc = FTN;
			break;
		case N_BFUN:
			if( !inasrc || !src ) break;
			inafunc = 1;
			++FunctionStubs;
			func = new Func(this,src,func,n-base,n->n_un.n_name);
			if( !src->child ) src->child = src->linefunc = func;
			func->range.lo = n->n_value;
			func->lines.lo = n->n_desc;
			if( !strcmp(n->n_un.n_name,(n+1)->n_un.n_name) )
				func->type = gatherdtype(++n);
			break;
		case N_ESO:
			inasrc = inafunc = 0;
			break;
		case N_EFUN:
			/* if( !inasrc ) break; screws yyparse() */
			if( !inafunc || !func ) break;
			inafunc = 0;
			func->lines.hi = n->n_desc;
			func->size = n-base - func->begin + 1;
		}
	}
	while( src && src->lsib ) src = (Source*) src->lsib;
	if( base ) { delete base; base = 0; }
	return src;
}

Var *Ed8SymTab::gatherutype(UType *u)
{
	nlist *f, *n;
	Var *first = 0, *v = 0;
	long bstr = u->begin, size = u->size;

	++UTypeGathered;
	SymbolStats();
	trace( "%d.gatherutype(%d %d)", this, bstr, size );
	if( !(f = n = nlistvector(bstr,size)) ) return 0;
	for( ++n; n->n_type != N_ESTR; ++n ){
		switch( n->n_type ){
		case N_SFLD:
			int length = n->n_desc>>BTSHIFT;
			n->n_value = (32 - (n->n_value & 0x1f) - length) +
				(n->n_value & ~0x1f);
			switch( n->n_desc & BTMASK ){
			case INT:	n->n_desc = BITS; break;
			case UNSIGNED:	n->n_desc = UBITS;
			}
			gathervar(n, &v, 0, U_MOT);
			v->type.dim = length;
			break;
		case N_SSYM:
			gathervar(n, &v, 0, U_MOT);
		}
		if( !first ) first = v;
	}
	delete f;
	uncfront(first, u->_text);
	return first;
}

nlist *Ed8SymTab::nlistvector(long start, long size )
{
	struct nlist *n;
	int i;

	trace( "%d.nlistvector(%d,%d) %d", this, start, size, symoff );
	lseek(fd, (long) (symoff + start), 0);
	n = new nlist[size];
	IF_LIVE( !ReadOK(fd, (char*) n, size * sizeof *n) ){
		delete n;
		return 0;
	}
	for( i = 0; i < size; ++i )
		n[i].n_un.n_strx += (long) strings;
	return n;
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.