xref: /inferno-os/utils/6l/list.c (revision b370703f35244a5152bf72daf6a871fba74ed373)
1*b370703fSCharles.Forsyth #include	"l.h"
2*b370703fSCharles.Forsyth 
3*b370703fSCharles.Forsyth void
listinit(void)4*b370703fSCharles.Forsyth listinit(void)
5*b370703fSCharles.Forsyth {
6*b370703fSCharles.Forsyth 
7*b370703fSCharles.Forsyth 	fmtinstall('R', Rconv);
8*b370703fSCharles.Forsyth 	fmtinstall('A', Aconv);
9*b370703fSCharles.Forsyth 	fmtinstall('D', Dconv);
10*b370703fSCharles.Forsyth 	fmtinstall('S', Sconv);
11*b370703fSCharles.Forsyth 	fmtinstall('P', Pconv);
12*b370703fSCharles.Forsyth }
13*b370703fSCharles.Forsyth 
14*b370703fSCharles.Forsyth static	Prog	*bigP;
15*b370703fSCharles.Forsyth 
16*b370703fSCharles.Forsyth int
Pconv(Fmt * fp)17*b370703fSCharles.Forsyth Pconv(Fmt *fp)
18*b370703fSCharles.Forsyth {
19*b370703fSCharles.Forsyth 	char str[STRINGSZ];
20*b370703fSCharles.Forsyth 	Prog *p;
21*b370703fSCharles.Forsyth 
22*b370703fSCharles.Forsyth 	p = va_arg(fp->args, Prog*);
23*b370703fSCharles.Forsyth 	bigP = p;
24*b370703fSCharles.Forsyth 	switch(p->as) {
25*b370703fSCharles.Forsyth 	case ATEXT:
26*b370703fSCharles.Forsyth 		if(p->from.scale) {
27*b370703fSCharles.Forsyth 			sprint(str, "(%ld)	%A	%D,%d,%D",
28*b370703fSCharles.Forsyth 				p->line, p->as, &p->from, p->from.scale, &p->to);
29*b370703fSCharles.Forsyth 			break;
30*b370703fSCharles.Forsyth 		}
31*b370703fSCharles.Forsyth 	default:
32*b370703fSCharles.Forsyth 		sprint(str, "(%ld)	%A	%D,%D",
33*b370703fSCharles.Forsyth 			p->line, p->as, &p->from, &p->to);
34*b370703fSCharles.Forsyth 		break;
35*b370703fSCharles.Forsyth 	case ADATA:
36*b370703fSCharles.Forsyth 	case AINIT:
37*b370703fSCharles.Forsyth 	case ADYNT:
38*b370703fSCharles.Forsyth 		sprint(str, "(%ld)	%A	%D/%d,%D",
39*b370703fSCharles.Forsyth 			p->line, p->as, &p->from, p->from.scale, &p->to);
40*b370703fSCharles.Forsyth 		break;
41*b370703fSCharles.Forsyth 	}
42*b370703fSCharles.Forsyth 	bigP = P;
43*b370703fSCharles.Forsyth 	return fmtstrcpy(fp, str);
44*b370703fSCharles.Forsyth }
45*b370703fSCharles.Forsyth 
46*b370703fSCharles.Forsyth int
Aconv(Fmt * fp)47*b370703fSCharles.Forsyth Aconv(Fmt *fp)
48*b370703fSCharles.Forsyth {
49*b370703fSCharles.Forsyth 	int i;
50*b370703fSCharles.Forsyth 
51*b370703fSCharles.Forsyth 	i = va_arg(fp->args, int);
52*b370703fSCharles.Forsyth 	return fmtstrcpy(fp, anames[i]);
53*b370703fSCharles.Forsyth }
54*b370703fSCharles.Forsyth 
55*b370703fSCharles.Forsyth int
Dconv(Fmt * fp)56*b370703fSCharles.Forsyth Dconv(Fmt *fp)
57*b370703fSCharles.Forsyth {
58*b370703fSCharles.Forsyth 	char str[40], s[20];
59*b370703fSCharles.Forsyth 	Adr *a;
60*b370703fSCharles.Forsyth 	int i;
61*b370703fSCharles.Forsyth 
62*b370703fSCharles.Forsyth 	a = va_arg(fp->args, Adr*);
63*b370703fSCharles.Forsyth 	i = a->type;
64*b370703fSCharles.Forsyth 	if(i >= D_INDIR) {
65*b370703fSCharles.Forsyth 		if(a->offset)
66*b370703fSCharles.Forsyth 			sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
67*b370703fSCharles.Forsyth 		else
68*b370703fSCharles.Forsyth 			sprint(str, "(%R)", i-D_INDIR);
69*b370703fSCharles.Forsyth 		goto brk;
70*b370703fSCharles.Forsyth 	}
71*b370703fSCharles.Forsyth 	switch(i) {
72*b370703fSCharles.Forsyth 
73*b370703fSCharles.Forsyth 	default:
74*b370703fSCharles.Forsyth 		if(a->offset)
75*b370703fSCharles.Forsyth 			sprint(str, "$%lld,%R", a->offset, i);
76*b370703fSCharles.Forsyth 		else
77*b370703fSCharles.Forsyth 			sprint(str, "%R", i);
78*b370703fSCharles.Forsyth 		break;
79*b370703fSCharles.Forsyth 
80*b370703fSCharles.Forsyth 	case D_NONE:
81*b370703fSCharles.Forsyth 		str[0] = 0;
82*b370703fSCharles.Forsyth 		break;
83*b370703fSCharles.Forsyth 
84*b370703fSCharles.Forsyth 	case D_BRANCH:
85*b370703fSCharles.Forsyth 		if(bigP != P && bigP->pcond != P)
86*b370703fSCharles.Forsyth 			if(a->sym != S)
87*b370703fSCharles.Forsyth 				sprint(str, "%llux+%s", bigP->pcond->pc,
88*b370703fSCharles.Forsyth 					a->sym->name);
89*b370703fSCharles.Forsyth 			else
90*b370703fSCharles.Forsyth 				sprint(str, "%llux", bigP->pcond->pc);
91*b370703fSCharles.Forsyth 		else
92*b370703fSCharles.Forsyth 			sprint(str, "%lld(PC)", a->offset);
93*b370703fSCharles.Forsyth 		break;
94*b370703fSCharles.Forsyth 
95*b370703fSCharles.Forsyth 	case D_EXTERN:
96*b370703fSCharles.Forsyth 		sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
97*b370703fSCharles.Forsyth 		break;
98*b370703fSCharles.Forsyth 
99*b370703fSCharles.Forsyth 	case D_STATIC:
100*b370703fSCharles.Forsyth 		sprint(str, "%s<%d>+%lld(SB)", a->sym->name,
101*b370703fSCharles.Forsyth 			a->sym->version, a->offset);
102*b370703fSCharles.Forsyth 		break;
103*b370703fSCharles.Forsyth 
104*b370703fSCharles.Forsyth 	case D_AUTO:
105*b370703fSCharles.Forsyth 		sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
106*b370703fSCharles.Forsyth 		break;
107*b370703fSCharles.Forsyth 
108*b370703fSCharles.Forsyth 	case D_PARAM:
109*b370703fSCharles.Forsyth 		if(a->sym)
110*b370703fSCharles.Forsyth 			sprint(str, "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
111*b370703fSCharles.Forsyth 		else
112*b370703fSCharles.Forsyth 			sprint(str, "%lld(%s)", a->offset, paramspace);
113*b370703fSCharles.Forsyth 		break;
114*b370703fSCharles.Forsyth 
115*b370703fSCharles.Forsyth 	case D_CONST:
116*b370703fSCharles.Forsyth 		sprint(str, "$%lld", a->offset);
117*b370703fSCharles.Forsyth 		break;
118*b370703fSCharles.Forsyth 
119*b370703fSCharles.Forsyth 	case D_FCONST:
120*b370703fSCharles.Forsyth 		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
121*b370703fSCharles.Forsyth 		break;
122*b370703fSCharles.Forsyth 
123*b370703fSCharles.Forsyth 	case D_SCONST:
124*b370703fSCharles.Forsyth 		sprint(str, "$\"%S\"", a->scon);
125*b370703fSCharles.Forsyth 		break;
126*b370703fSCharles.Forsyth 
127*b370703fSCharles.Forsyth 	case D_ADDR:
128*b370703fSCharles.Forsyth 		a->type = a->index;
129*b370703fSCharles.Forsyth 		a->index = D_NONE;
130*b370703fSCharles.Forsyth 		sprint(str, "$%D", a);
131*b370703fSCharles.Forsyth 		a->index = a->type;
132*b370703fSCharles.Forsyth 		a->type = D_ADDR;
133*b370703fSCharles.Forsyth 		goto conv;
134*b370703fSCharles.Forsyth 	}
135*b370703fSCharles.Forsyth brk:
136*b370703fSCharles.Forsyth 	if(a->index != D_NONE) {
137*b370703fSCharles.Forsyth 		sprint(s, "(%R*%d)", a->index, a->scale);
138*b370703fSCharles.Forsyth 		strcat(str, s);
139*b370703fSCharles.Forsyth 	}
140*b370703fSCharles.Forsyth conv:
141*b370703fSCharles.Forsyth 	return fmtstrcpy(fp, str);
142*b370703fSCharles.Forsyth }
143*b370703fSCharles.Forsyth 
144*b370703fSCharles.Forsyth char*	regstr[] =
145*b370703fSCharles.Forsyth {
146*b370703fSCharles.Forsyth 	"AL",		/* [D_AL] */
147*b370703fSCharles.Forsyth 	"CL",
148*b370703fSCharles.Forsyth 	"DL",
149*b370703fSCharles.Forsyth 	"BL",
150*b370703fSCharles.Forsyth 	"SPB",
151*b370703fSCharles.Forsyth 	"BPB",
152*b370703fSCharles.Forsyth 	"SIB",
153*b370703fSCharles.Forsyth 	"DIB",
154*b370703fSCharles.Forsyth 	"R8B",
155*b370703fSCharles.Forsyth 	"R9B",
156*b370703fSCharles.Forsyth 	"R10B",
157*b370703fSCharles.Forsyth 	"R11B",
158*b370703fSCharles.Forsyth 	"R12B",
159*b370703fSCharles.Forsyth 	"R13B",
160*b370703fSCharles.Forsyth 	"R14B",
161*b370703fSCharles.Forsyth 	"R15B",
162*b370703fSCharles.Forsyth 
163*b370703fSCharles.Forsyth 	"AX",		/* [D_AX] */
164*b370703fSCharles.Forsyth 	"CX",
165*b370703fSCharles.Forsyth 	"DX",
166*b370703fSCharles.Forsyth 	"BX",
167*b370703fSCharles.Forsyth 	"SP",
168*b370703fSCharles.Forsyth 	"BP",
169*b370703fSCharles.Forsyth 	"SI",
170*b370703fSCharles.Forsyth 	"DI",
171*b370703fSCharles.Forsyth 	"R8",
172*b370703fSCharles.Forsyth 	"R9",
173*b370703fSCharles.Forsyth 	"R10",
174*b370703fSCharles.Forsyth 	"R11",
175*b370703fSCharles.Forsyth 	"R12",
176*b370703fSCharles.Forsyth 	"R13",
177*b370703fSCharles.Forsyth 	"R14",
178*b370703fSCharles.Forsyth 	"R15",
179*b370703fSCharles.Forsyth 
180*b370703fSCharles.Forsyth 	"AH",
181*b370703fSCharles.Forsyth 	"CH",
182*b370703fSCharles.Forsyth 	"DH",
183*b370703fSCharles.Forsyth 	"BH",
184*b370703fSCharles.Forsyth 
185*b370703fSCharles.Forsyth 	"F0",		/* [D_F0] */
186*b370703fSCharles.Forsyth 	"F1",
187*b370703fSCharles.Forsyth 	"F2",
188*b370703fSCharles.Forsyth 	"F3",
189*b370703fSCharles.Forsyth 	"F4",
190*b370703fSCharles.Forsyth 	"F5",
191*b370703fSCharles.Forsyth 	"F6",
192*b370703fSCharles.Forsyth 	"F7",
193*b370703fSCharles.Forsyth 
194*b370703fSCharles.Forsyth 	"M0",
195*b370703fSCharles.Forsyth 	"M1",
196*b370703fSCharles.Forsyth 	"M2",
197*b370703fSCharles.Forsyth 	"M3",
198*b370703fSCharles.Forsyth 	"M4",
199*b370703fSCharles.Forsyth 	"M5",
200*b370703fSCharles.Forsyth 	"M6",
201*b370703fSCharles.Forsyth 	"M7",
202*b370703fSCharles.Forsyth 
203*b370703fSCharles.Forsyth 	"X0",
204*b370703fSCharles.Forsyth 	"X1",
205*b370703fSCharles.Forsyth 	"X2",
206*b370703fSCharles.Forsyth 	"X3",
207*b370703fSCharles.Forsyth 	"X4",
208*b370703fSCharles.Forsyth 	"X5",
209*b370703fSCharles.Forsyth 	"X6",
210*b370703fSCharles.Forsyth 	"X7",
211*b370703fSCharles.Forsyth 	"X8",
212*b370703fSCharles.Forsyth 	"X9",
213*b370703fSCharles.Forsyth 	"X10",
214*b370703fSCharles.Forsyth 	"X11",
215*b370703fSCharles.Forsyth 	"X12",
216*b370703fSCharles.Forsyth 	"X13",
217*b370703fSCharles.Forsyth 	"X14",
218*b370703fSCharles.Forsyth 	"X15",
219*b370703fSCharles.Forsyth 
220*b370703fSCharles.Forsyth 	"CS",		/* [D_CS] */
221*b370703fSCharles.Forsyth 	"SS",
222*b370703fSCharles.Forsyth 	"DS",
223*b370703fSCharles.Forsyth 	"ES",
224*b370703fSCharles.Forsyth 	"FS",
225*b370703fSCharles.Forsyth 	"GS",
226*b370703fSCharles.Forsyth 
227*b370703fSCharles.Forsyth 	"GDTR",		/* [D_GDTR] */
228*b370703fSCharles.Forsyth 	"IDTR",		/* [D_IDTR] */
229*b370703fSCharles.Forsyth 	"LDTR",		/* [D_LDTR] */
230*b370703fSCharles.Forsyth 	"MSW",		/* [D_MSW] */
231*b370703fSCharles.Forsyth 	"TASK",		/* [D_TASK] */
232*b370703fSCharles.Forsyth 
233*b370703fSCharles.Forsyth 	"CR0",		/* [D_CR] */
234*b370703fSCharles.Forsyth 	"CR1",
235*b370703fSCharles.Forsyth 	"CR2",
236*b370703fSCharles.Forsyth 	"CR3",
237*b370703fSCharles.Forsyth 	"CR4",
238*b370703fSCharles.Forsyth 	"CR5",
239*b370703fSCharles.Forsyth 	"CR6",
240*b370703fSCharles.Forsyth 	"CR7",
241*b370703fSCharles.Forsyth 	"CR8",
242*b370703fSCharles.Forsyth 	"CR9",
243*b370703fSCharles.Forsyth 	"CR10",
244*b370703fSCharles.Forsyth 	"CR11",
245*b370703fSCharles.Forsyth 	"CR12",
246*b370703fSCharles.Forsyth 	"CR13",
247*b370703fSCharles.Forsyth 	"CR14",
248*b370703fSCharles.Forsyth 	"CR15",
249*b370703fSCharles.Forsyth 
250*b370703fSCharles.Forsyth 	"DR0",		/* [D_DR] */
251*b370703fSCharles.Forsyth 	"DR1",
252*b370703fSCharles.Forsyth 	"DR2",
253*b370703fSCharles.Forsyth 	"DR3",
254*b370703fSCharles.Forsyth 	"DR4",
255*b370703fSCharles.Forsyth 	"DR5",
256*b370703fSCharles.Forsyth 	"DR6",
257*b370703fSCharles.Forsyth 	"DR7",
258*b370703fSCharles.Forsyth 
259*b370703fSCharles.Forsyth 	"TR0",		/* [D_TR] */
260*b370703fSCharles.Forsyth 	"TR1",
261*b370703fSCharles.Forsyth 	"TR2",
262*b370703fSCharles.Forsyth 	"TR3",
263*b370703fSCharles.Forsyth 	"TR4",
264*b370703fSCharles.Forsyth 	"TR5",
265*b370703fSCharles.Forsyth 	"TR6",
266*b370703fSCharles.Forsyth 	"TR7",
267*b370703fSCharles.Forsyth 
268*b370703fSCharles.Forsyth 	"NONE",		/* [D_NONE] */
269*b370703fSCharles.Forsyth };
270*b370703fSCharles.Forsyth 
271*b370703fSCharles.Forsyth int
Rconv(Fmt * fp)272*b370703fSCharles.Forsyth Rconv(Fmt *fp)
273*b370703fSCharles.Forsyth {
274*b370703fSCharles.Forsyth 	char str[20];
275*b370703fSCharles.Forsyth 	int r;
276*b370703fSCharles.Forsyth 
277*b370703fSCharles.Forsyth 	r = va_arg(fp->args, int);
278*b370703fSCharles.Forsyth 	if(r >= D_AL && r <= D_NONE)
279*b370703fSCharles.Forsyth 		sprint(str, "%s", regstr[r-D_AL]);
280*b370703fSCharles.Forsyth 	else
281*b370703fSCharles.Forsyth 		sprint(str, "gok(%d)", r);
282*b370703fSCharles.Forsyth 
283*b370703fSCharles.Forsyth 	return fmtstrcpy(fp, str);
284*b370703fSCharles.Forsyth }
285*b370703fSCharles.Forsyth 
286*b370703fSCharles.Forsyth int
Sconv(Fmt * fp)287*b370703fSCharles.Forsyth Sconv(Fmt *fp)
288*b370703fSCharles.Forsyth {
289*b370703fSCharles.Forsyth 	int i, c;
290*b370703fSCharles.Forsyth 	char str[30], *p, *a;
291*b370703fSCharles.Forsyth 
292*b370703fSCharles.Forsyth 	a = va_arg(fp->args, char*);
293*b370703fSCharles.Forsyth 	p = str;
294*b370703fSCharles.Forsyth 	for(i=0; i<sizeof(double); i++) {
295*b370703fSCharles.Forsyth 		c = a[i] & 0xff;
296*b370703fSCharles.Forsyth 		if(c >= 'a' && c <= 'z' ||
297*b370703fSCharles.Forsyth 		   c >= 'A' && c <= 'Z' ||
298*b370703fSCharles.Forsyth 		   c >= '0' && c <= '9') {
299*b370703fSCharles.Forsyth 			*p++ = c;
300*b370703fSCharles.Forsyth 			continue;
301*b370703fSCharles.Forsyth 		}
302*b370703fSCharles.Forsyth 		*p++ = '\\';
303*b370703fSCharles.Forsyth 		switch(c) {
304*b370703fSCharles.Forsyth 		default:
305*b370703fSCharles.Forsyth 			if(c < 040 || c >= 0177)
306*b370703fSCharles.Forsyth 				break;	/* not portable */
307*b370703fSCharles.Forsyth 			p[-1] = c;
308*b370703fSCharles.Forsyth 			continue;
309*b370703fSCharles.Forsyth 		case 0:
310*b370703fSCharles.Forsyth 			*p++ = 'z';
311*b370703fSCharles.Forsyth 			continue;
312*b370703fSCharles.Forsyth 		case '\\':
313*b370703fSCharles.Forsyth 		case '"':
314*b370703fSCharles.Forsyth 			*p++ = c;
315*b370703fSCharles.Forsyth 			continue;
316*b370703fSCharles.Forsyth 		case '\n':
317*b370703fSCharles.Forsyth 			*p++ = 'n';
318*b370703fSCharles.Forsyth 			continue;
319*b370703fSCharles.Forsyth 		case '\t':
320*b370703fSCharles.Forsyth 			*p++ = 't';
321*b370703fSCharles.Forsyth 			continue;
322*b370703fSCharles.Forsyth 		}
323*b370703fSCharles.Forsyth 		*p++ = (c>>6) + '0';
324*b370703fSCharles.Forsyth 		*p++ = ((c>>3) & 7) + '0';
325*b370703fSCharles.Forsyth 		*p++ = (c & 7) + '0';
326*b370703fSCharles.Forsyth 	}
327*b370703fSCharles.Forsyth 	*p = 0;
328*b370703fSCharles.Forsyth 	return fmtstrcpy(fp, str);
329*b370703fSCharles.Forsyth }
330*b370703fSCharles.Forsyth 
331*b370703fSCharles.Forsyth void
diag(char * fmt,...)332*b370703fSCharles.Forsyth diag(char *fmt, ...)
333*b370703fSCharles.Forsyth {
334*b370703fSCharles.Forsyth 	char buf[STRINGSZ], *tn;
335*b370703fSCharles.Forsyth 	va_list arg;
336*b370703fSCharles.Forsyth 
337*b370703fSCharles.Forsyth 	tn = "??none??";
338*b370703fSCharles.Forsyth 	if(curtext != P && curtext->from.sym != S)
339*b370703fSCharles.Forsyth 		tn = curtext->from.sym->name;
340*b370703fSCharles.Forsyth 	va_start(arg, fmt);
341*b370703fSCharles.Forsyth 	vseprint(buf, buf+sizeof(buf), fmt, arg);
342*b370703fSCharles.Forsyth 	va_end(arg);
343*b370703fSCharles.Forsyth 	print("%s: %s\n", tn, buf);
344*b370703fSCharles.Forsyth 
345*b370703fSCharles.Forsyth 	nerrors++;
346*b370703fSCharles.Forsyth 	if(nerrors > 20) {
347*b370703fSCharles.Forsyth 		print("too many errors\n");
348*b370703fSCharles.Forsyth 		errorexit();
349*b370703fSCharles.Forsyth 	}
350*b370703fSCharles.Forsyth }
351