xref: /inferno-os/utils/5coff/auxi.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"auxi.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth Prog *firstp, *textp, *curtext, *lastp, *etextp;
4*74a4d8c2SCharles.Forsyth Symx *hash[NHASH];
5*74a4d8c2SCharles.Forsyth Auto *lasta;
6*74a4d8c2SCharles.Forsyth long autosize;
7*74a4d8c2SCharles.Forsyth int version = 0;
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth static int
private(char * s)10*74a4d8c2SCharles.Forsyth private(char *s)
11*74a4d8c2SCharles.Forsyth {
12*74a4d8c2SCharles.Forsyth 	return strcmp(s, "safe") == 0 || strcmp(s, "ret") == 0 || strcmp(s, "string") == 0;
13*74a4d8c2SCharles.Forsyth }
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth static int
zlen(char * s)16*74a4d8c2SCharles.Forsyth zlen(char *s)
17*74a4d8c2SCharles.Forsyth {
18*74a4d8c2SCharles.Forsyth 	int i;
19*74a4d8c2SCharles.Forsyth 
20*74a4d8c2SCharles.Forsyth 	for(i=1; s[i] != 0 || s[i+1] != 0; i += 2)
21*74a4d8c2SCharles.Forsyth 		;
22*74a4d8c2SCharles.Forsyth 	i++;
23*74a4d8c2SCharles.Forsyth 	return i+1;
24*74a4d8c2SCharles.Forsyth }
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth static Symx*
allocsym(char * symb,int l,int v)27*74a4d8c2SCharles.Forsyth allocsym(char *symb, int l, int v)
28*74a4d8c2SCharles.Forsyth {
29*74a4d8c2SCharles.Forsyth 	Symx *s;
30*74a4d8c2SCharles.Forsyth 
31*74a4d8c2SCharles.Forsyth 	s = malloc(sizeof(Symx));
32*74a4d8c2SCharles.Forsyth 	s->name = malloc(l);
33*74a4d8c2SCharles.Forsyth 	memmove(s->name, symb, l);
34*74a4d8c2SCharles.Forsyth 	s->name[l-1] = '\0';
35*74a4d8c2SCharles.Forsyth 	s->type = 0;
36*74a4d8c2SCharles.Forsyth 	s->version = v;
37*74a4d8c2SCharles.Forsyth 	s->value = 0;
38*74a4d8c2SCharles.Forsyth 	s->link = nil;
39*74a4d8c2SCharles.Forsyth 	return s;
40*74a4d8c2SCharles.Forsyth }
41*74a4d8c2SCharles.Forsyth 
42*74a4d8c2SCharles.Forsyth Symx*
lookupsym(char * symb,int v)43*74a4d8c2SCharles.Forsyth lookupsym(char *symb, int v)
44*74a4d8c2SCharles.Forsyth {
45*74a4d8c2SCharles.Forsyth 	Symx *s, **as;
46*74a4d8c2SCharles.Forsyth 	char *p;
47*74a4d8c2SCharles.Forsyth 	long h;
48*74a4d8c2SCharles.Forsyth 	int c, l;
49*74a4d8c2SCharles.Forsyth 
50*74a4d8c2SCharles.Forsyth 	h = v;
51*74a4d8c2SCharles.Forsyth 	for(p=symb; c = *p; p++)
52*74a4d8c2SCharles.Forsyth 		h = h+h+h + c;
53*74a4d8c2SCharles.Forsyth 	l = (p - symb) + 1;
54*74a4d8c2SCharles.Forsyth 	if(h < 0)
55*74a4d8c2SCharles.Forsyth 		h = ~h;
56*74a4d8c2SCharles.Forsyth 	h %= NHASH;
57*74a4d8c2SCharles.Forsyth 	for(s = hash[h]; s != nil; s = s->link)
58*74a4d8c2SCharles.Forsyth 		if(s->version == v)
59*74a4d8c2SCharles.Forsyth 		if(memcmp(s->name, symb, l) == 0)
60*74a4d8c2SCharles.Forsyth 			return s;
61*74a4d8c2SCharles.Forsyth 	s = allocsym(symb, l, v);
62*74a4d8c2SCharles.Forsyth 	for(as = &hash[h]; *as != nil; as = &((*as)->link))
63*74a4d8c2SCharles.Forsyth 		;
64*74a4d8c2SCharles.Forsyth 	*as = s;
65*74a4d8c2SCharles.Forsyth 	// s->link = hash[h];
66*74a4d8c2SCharles.Forsyth 	// hash[h] = s;
67*74a4d8c2SCharles.Forsyth 	return s;
68*74a4d8c2SCharles.Forsyth }
69*74a4d8c2SCharles.Forsyth 
70*74a4d8c2SCharles.Forsyth static void
addauto(Auto ** aut,Symx * s,int t,long v)71*74a4d8c2SCharles.Forsyth addauto(Auto **aut, Symx *s, int t, long v)
72*74a4d8c2SCharles.Forsyth {
73*74a4d8c2SCharles.Forsyth 	Auto *a, **aa;
74*74a4d8c2SCharles.Forsyth 
75*74a4d8c2SCharles.Forsyth 	a = (Auto*)malloc(sizeof(Auto));
76*74a4d8c2SCharles.Forsyth 	a->asym = s;
77*74a4d8c2SCharles.Forsyth 	a->link = nil;
78*74a4d8c2SCharles.Forsyth 	a->aoffset = v;
79*74a4d8c2SCharles.Forsyth 	a->type = t;
80*74a4d8c2SCharles.Forsyth 	for(aa = aut; *aa != nil; aa = &((*aa)->link))
81*74a4d8c2SCharles.Forsyth 		;
82*74a4d8c2SCharles.Forsyth 	*aa = a;
83*74a4d8c2SCharles.Forsyth }
84*74a4d8c2SCharles.Forsyth 
85*74a4d8c2SCharles.Forsyth static Prog*
newprog(int as,long pc,long ln)86*74a4d8c2SCharles.Forsyth newprog(int as, long pc, long ln)
87*74a4d8c2SCharles.Forsyth {
88*74a4d8c2SCharles.Forsyth 	Prog *p;
89*74a4d8c2SCharles.Forsyth 
90*74a4d8c2SCharles.Forsyth 	p = (Prog *)malloc(sizeof(Prog));
91*74a4d8c2SCharles.Forsyth 	p->as = as;
92*74a4d8c2SCharles.Forsyth 	p->pc = pc;
93*74a4d8c2SCharles.Forsyth 	p->line = ln;
94*74a4d8c2SCharles.Forsyth 	p->link = p->cond = P;
95*74a4d8c2SCharles.Forsyth 	if(firstp == P)
96*74a4d8c2SCharles.Forsyth 		firstp = p;
97*74a4d8c2SCharles.Forsyth 	else
98*74a4d8c2SCharles.Forsyth 		lastp->link = p;
99*74a4d8c2SCharles.Forsyth 	lastp = p;
100*74a4d8c2SCharles.Forsyth 	if(as == ATEXT){
101*74a4d8c2SCharles.Forsyth 		if(textp == P)
102*74a4d8c2SCharles.Forsyth 			textp = p;
103*74a4d8c2SCharles.Forsyth 		else
104*74a4d8c2SCharles.Forsyth 			etextp->cond = p;
105*74a4d8c2SCharles.Forsyth 		etextp = p;
106*74a4d8c2SCharles.Forsyth 	}
107*74a4d8c2SCharles.Forsyth 	return p;
108*74a4d8c2SCharles.Forsyth }
109*74a4d8c2SCharles.Forsyth 
110*74a4d8c2SCharles.Forsyth static int
line(long pc)111*74a4d8c2SCharles.Forsyth line(long pc)
112*74a4d8c2SCharles.Forsyth {
113*74a4d8c2SCharles.Forsyth 	char buf[1024], *s;
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth 	// return pc2line(pc);
116*74a4d8c2SCharles.Forsyth 	if(fileline(buf, sizeof(buf), pc)){
117*74a4d8c2SCharles.Forsyth 		for(s = buf; *s != ':' && *s != '\0'; s++)
118*74a4d8c2SCharles.Forsyth 			;
119*74a4d8c2SCharles.Forsyth 		if(*s != ':')
120*74a4d8c2SCharles.Forsyth 			return -1;
121*74a4d8c2SCharles.Forsyth 		return atoi(s+1);
122*74a4d8c2SCharles.Forsyth 	}
123*74a4d8c2SCharles.Forsyth 	return -1;
124*74a4d8c2SCharles.Forsyth }
125*74a4d8c2SCharles.Forsyth 
126*74a4d8c2SCharles.Forsyth static void
lines(long v)127*74a4d8c2SCharles.Forsyth lines(long v)
128*74a4d8c2SCharles.Forsyth {
129*74a4d8c2SCharles.Forsyth 	long ll, nl, pc;
130*74a4d8c2SCharles.Forsyth 	if(etextp != P){
131*74a4d8c2SCharles.Forsyth 		ll = 0;
132*74a4d8c2SCharles.Forsyth 		for(pc = etextp->pc; pc < v; pc += 4){
133*74a4d8c2SCharles.Forsyth 			nl = line(pc);
134*74a4d8c2SCharles.Forsyth 			if(nl != -1 && nl != ll){
135*74a4d8c2SCharles.Forsyth 				newprog(ATEXT-1, pc, nl);
136*74a4d8c2SCharles.Forsyth 				ll = nl;
137*74a4d8c2SCharles.Forsyth 			}
138*74a4d8c2SCharles.Forsyth 		}
139*74a4d8c2SCharles.Forsyth 		pc -= 4;
140*74a4d8c2SCharles.Forsyth 		if(lastp->pc != pc){
141*74a4d8c2SCharles.Forsyth 			nl = line(pc);
142*74a4d8c2SCharles.Forsyth 			if(nl != -1)
143*74a4d8c2SCharles.Forsyth 				newprog(ATEXT-1, pc, nl);
144*74a4d8c2SCharles.Forsyth 		}
145*74a4d8c2SCharles.Forsyth 	}
146*74a4d8c2SCharles.Forsyth }
147*74a4d8c2SCharles.Forsyth 
148*74a4d8c2SCharles.Forsyth void
beginsym(void)149*74a4d8c2SCharles.Forsyth beginsym(void)
150*74a4d8c2SCharles.Forsyth {
151*74a4d8c2SCharles.Forsyth }
152*74a4d8c2SCharles.Forsyth 
153*74a4d8c2SCharles.Forsyth /* create the same structures as in 5l so we can use same coff.c source file */
154*74a4d8c2SCharles.Forsyth void
newsym(int i,char * nm,long v,int t)155*74a4d8c2SCharles.Forsyth newsym(int i, char *nm, long v, int t)
156*74a4d8c2SCharles.Forsyth {
157*74a4d8c2SCharles.Forsyth 	long l, ver;
158*74a4d8c2SCharles.Forsyth 	char *os;
159*74a4d8c2SCharles.Forsyth 	Symx *s;
160*74a4d8c2SCharles.Forsyth 	Prog *p;
161*74a4d8c2SCharles.Forsyth 
162*74a4d8c2SCharles.Forsyth 	if(i == 0 && (t == 't' || t == 'T') && strcmp(nm, "etext") == 0)
163*74a4d8c2SCharles.Forsyth 		return;
164*74a4d8c2SCharles.Forsyth 	if(nm[0] == '.' && private(nm+1))
165*74a4d8c2SCharles.Forsyth 		return;
166*74a4d8c2SCharles.Forsyth // print("%s %ld %c\n", nm, v, t);
167*74a4d8c2SCharles.Forsyth 	ver = 0;
168*74a4d8c2SCharles.Forsyth 	if(t == 't' || t == 'l' || t == 'd' || t == 'b'){
169*74a4d8c2SCharles.Forsyth 		ver = ++version;
170*74a4d8c2SCharles.Forsyth 		if(ver == 0)
171*74a4d8c2SCharles.Forsyth 			diag("0 version for static");
172*74a4d8c2SCharles.Forsyth 	}
173*74a4d8c2SCharles.Forsyth 	if(t == 'a' || t == 'p')
174*74a4d8c2SCharles.Forsyth 		s = allocsym(nm, strlen(nm)+1, 0);
175*74a4d8c2SCharles.Forsyth 	else if(t == 'z' || t == 'Z')
176*74a4d8c2SCharles.Forsyth 		s = allocsym(nm, zlen(nm), 0);
177*74a4d8c2SCharles.Forsyth 	else if(t != 'm'){
178*74a4d8c2SCharles.Forsyth 		s = lookupsym(nm, ver);
179*74a4d8c2SCharles.Forsyth 		if(s->type != 0)
180*74a4d8c2SCharles.Forsyth 			diag("seen sym before in newsym");
181*74a4d8c2SCharles.Forsyth 		s->value = v;
182*74a4d8c2SCharles.Forsyth 	}
183*74a4d8c2SCharles.Forsyth 	else
184*74a4d8c2SCharles.Forsyth 		s = nil;
185*74a4d8c2SCharles.Forsyth 	switch(t){
186*74a4d8c2SCharles.Forsyth 	case 'T':
187*74a4d8c2SCharles.Forsyth 	case 'L':
188*74a4d8c2SCharles.Forsyth 	case 't':
189*74a4d8c2SCharles.Forsyth 	case 'l':
190*74a4d8c2SCharles.Forsyth 		lines(v);
191*74a4d8c2SCharles.Forsyth 		if(t == 'l' || t == 'L')
192*74a4d8c2SCharles.Forsyth 			s->type = SLEAF;
193*74a4d8c2SCharles.Forsyth 		else
194*74a4d8c2SCharles.Forsyth 			s->type = STEXT;
195*74a4d8c2SCharles.Forsyth 		p = newprog(ATEXT, v, line(v));
196*74a4d8c2SCharles.Forsyth 		p->from.sym = s;
197*74a4d8c2SCharles.Forsyth 		p->to.autom = lasta;
198*74a4d8c2SCharles.Forsyth 		lasta = nil;
199*74a4d8c2SCharles.Forsyth 		break;
200*74a4d8c2SCharles.Forsyth 	case 'D':
201*74a4d8c2SCharles.Forsyth 	case 'd':
202*74a4d8c2SCharles.Forsyth 		s->type = SDATA;
203*74a4d8c2SCharles.Forsyth 		s->value -= INITDAT;
204*74a4d8c2SCharles.Forsyth 		break;
205*74a4d8c2SCharles.Forsyth 	case 'B':
206*74a4d8c2SCharles.Forsyth 	case 'b':
207*74a4d8c2SCharles.Forsyth 		s->type = SBSS;
208*74a4d8c2SCharles.Forsyth 		s->value -= INITDAT;
209*74a4d8c2SCharles.Forsyth 		break;
210*74a4d8c2SCharles.Forsyth 	case 'f':
211*74a4d8c2SCharles.Forsyth 		// version++;
212*74a4d8c2SCharles.Forsyth 		s->type = SFILE;
213*74a4d8c2SCharles.Forsyth 		os = s->name;
214*74a4d8c2SCharles.Forsyth 		l = strlen(os)+1;
215*74a4d8c2SCharles.Forsyth 		s->name = malloc(l+1);
216*74a4d8c2SCharles.Forsyth 		s->name[0] = '>';
217*74a4d8c2SCharles.Forsyth 		memmove(s->name+1, os, l);
218*74a4d8c2SCharles.Forsyth 		free(os);
219*74a4d8c2SCharles.Forsyth 		break;
220*74a4d8c2SCharles.Forsyth /*
221*74a4d8c2SCharles.Forsyth 	case 'f'+'a'-'A':
222*74a4d8c2SCharles.Forsyth 		s->type = SFILE;
223*74a4d8c2SCharles.Forsyth 		break;
224*74a4d8c2SCharles.Forsyth */
225*74a4d8c2SCharles.Forsyth 	case 'z':
226*74a4d8c2SCharles.Forsyth 		addauto(&lasta, s, D_FILE, v);
227*74a4d8c2SCharles.Forsyth 		break;
228*74a4d8c2SCharles.Forsyth 	case 'Z':
229*74a4d8c2SCharles.Forsyth 		addauto(&lasta, s, D_FILE1, v);
230*74a4d8c2SCharles.Forsyth 		break;
231*74a4d8c2SCharles.Forsyth 	case 'a':
232*74a4d8c2SCharles.Forsyth 		addauto(&(etextp->to.autom), s, D_AUTO, -v);
233*74a4d8c2SCharles.Forsyth 		break;
234*74a4d8c2SCharles.Forsyth 	case 'p':
235*74a4d8c2SCharles.Forsyth 		addauto(&(etextp->to.autom), s, D_PARAM, v);
236*74a4d8c2SCharles.Forsyth 		break;
237*74a4d8c2SCharles.Forsyth 	case 'm':
238*74a4d8c2SCharles.Forsyth 		etextp->to.offset = v-4;
239*74a4d8c2SCharles.Forsyth 		autosize = v;
240*74a4d8c2SCharles.Forsyth 		break;
241*74a4d8c2SCharles.Forsyth 	default:
242*74a4d8c2SCharles.Forsyth 		diag("bad case in newsym");
243*74a4d8c2SCharles.Forsyth 		break;
244*74a4d8c2SCharles.Forsyth 	}
245*74a4d8c2SCharles.Forsyth }
246*74a4d8c2SCharles.Forsyth 
247*74a4d8c2SCharles.Forsyth void
endsym(void)248*74a4d8c2SCharles.Forsyth endsym(void)
249*74a4d8c2SCharles.Forsyth {
250*74a4d8c2SCharles.Forsyth 	lines(INITTEXT+textsize);
251*74a4d8c2SCharles.Forsyth }
252