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