]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8c/list.c
[125678kqv][cl]: fix sprint() and strcpy() buffer overflows
[plan9front.git] / sys / src / cmd / 8c / list.c
1 #define EXTERN
2 #include "gc.h"
3
4 void
5 listinit(void)
6 {
7
8         fmtinstall('A', Aconv);
9         fmtinstall('B', Bconv);
10         fmtinstall('P', Pconv);
11         fmtinstall('S', Sconv);
12         fmtinstall('D', Dconv);
13         fmtinstall('R', Rconv);
14 }
15
16 int
17 Bconv(Fmt *fp)
18 {
19         char str[STRINGSZ], ss[STRINGSZ], *s;
20         Bits bits;
21         int i;
22
23         memset(str, 0, sizeof str);
24         bits = va_arg(fp->args, Bits);
25         while(bany(&bits)) {
26                 i = bnum(bits);
27                 if(str[0])
28                         strncat(str, " ", sizeof str - 1);
29                 if(var[i].sym == S) {
30                         snprint(ss, sizeof(ss), "$%ld", var[i].offset);
31                         s = ss;
32                 } else
33                         s = var[i].sym->name;
34                 strncat(str, s, sizeof str - 1);
35                 bits.b[i/32] &= ~(1L << (i%32));
36         }
37         return fmtstrcpy(fp, str);
38 }
39
40 int
41 Pconv(Fmt *fp)
42 {
43         char str[STRINGSZ];
44         Prog *p;
45
46         p = va_arg(fp->args, Prog*);
47         if(p->as == ADATA)
48                 snprint(str, sizeof(str), "     %A      %D/%d,%D",
49                         p->as, &p->from, p->from.scale, &p->to);
50         else if(p->as == ATEXT)
51                 snprint(str, sizeof(str), "     %A      %D,%d,%D",
52                         p->as, &p->from, p->from.scale, &p->to);
53         else
54                 snprint(str, sizeof(str), "     %A      %D,%D",
55                         p->as, &p->from, &p->to);
56         return fmtstrcpy(fp, str);
57 }
58
59 int
60 Aconv(Fmt *fp)
61 {
62         int i;
63
64         i = va_arg(fp->args, int);
65         return fmtstrcpy(fp, anames[i]);
66 }
67
68 int
69 Dconv(Fmt *fp)
70 {
71         char str[40];
72         Adr *a;
73         int i;
74
75         a = va_arg(fp->args, Adr*);
76         i = a->type;
77         if(i >= D_INDIR) {
78                 if(a->offset)
79                         snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
80                 else
81                         snprint(str, sizeof(str), "(%R)", i-D_INDIR);
82                 goto brk;
83         }
84         switch(i) {
85
86         default:
87                 if(a->offset)
88                         snprint(str, sizeof(str), "$%ld,%R", a->offset, i);
89                 else
90                         snprint(str, sizeof(str), "%R", i);
91                 break;
92
93         case D_NONE:
94                 str[0] = 0;
95                 break;
96
97         case D_BRANCH:
98                 snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
99                 break;
100
101         case D_EXTERN:
102                 snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
103                 break;
104
105         case D_STATIC:
106                 snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name, a->offset);
107                 break;
108
109         case D_AUTO:
110                 snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
111                 break;
112
113         case D_PARAM:
114                 if(a->sym)
115                         snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
116                 else
117                         snprint(str, sizeof(str), "%ld(FP)", a->offset);
118                 break;
119
120         case D_CONST:
121                 snprint(str, sizeof(str), "$%ld", a->offset);
122                 break;
123
124         case D_FCONST:
125                 snprint(str, sizeof(str), "$(%.17e)", a->dval);
126                 break;
127
128         case D_SCONST:
129                 snprint(str, sizeof(str), "$\"%S\"", a->sval);
130                 break;
131
132         case D_ADDR:
133                 a->type = a->index;
134                 a->index = D_NONE;
135                 snprint(str, sizeof(str), "$%D", a);
136                 a->index = a->type;
137                 a->type = D_ADDR;
138                 goto conv;
139         }
140 brk:
141         if(a->index != D_NONE)
142                 return fmtprint(fp, "%s(%R*%d)", str, (int)a->index, (int)a->scale);
143 conv:
144         return fmtstrcpy(fp, str);
145 }
146
147 char*   regstr[] =
148 {
149         "AL",   /*[D_AL]*/      
150         "CL",
151         "DL",
152         "BL",
153         "AH",
154         "CH",
155         "DH",
156         "BH",
157
158         "AX",   /*[D_AX]*/
159         "CX",
160         "DX",
161         "BX",
162         "SP",
163         "BP",
164         "SI",
165         "DI",
166
167         "F0",   /*[D_F0]*/
168         "F1",
169         "F2",
170         "F3",
171         "F4",
172         "F5",
173         "F6",
174         "F7",
175
176         "CS",   /*[D_CS]*/
177         "SS",
178         "DS",
179         "ES",
180         "FS",
181         "GS",
182
183         "GDTR", /*[D_GDTR]*/
184         "IDTR", /*[D_IDTR]*/
185         "LDTR", /*[D_LDTR]*/
186         "MSW",  /*[D_MSW] */
187         "TASK", /*[D_TASK]*/
188
189         "CR0",  /*[D_CR]*/
190         "CR1",
191         "CR2",
192         "CR3",
193         "CR4",
194         "CR5",
195         "CR6",
196         "CR7",
197
198         "DR0",  /*[D_DR]*/
199         "DR1",
200         "DR2",
201         "DR3",
202         "DR4",
203         "DR5",
204         "DR6",
205         "DR7",
206
207         "TR0",  /*[D_TR]*/
208         "TR1",
209         "TR2",
210         "TR3",
211         "TR4",
212         "TR5",
213         "TR6",
214         "TR7",
215
216         "NONE", /*[D_NONE]*/
217 };
218
219 int
220 Rconv(Fmt *fp)
221 {
222         char str[20];
223         int r;
224
225         r = va_arg(fp->args, int);
226         if(r >= D_AL && r <= D_NONE)
227                 snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
228         else
229                 snprint(str, sizeof(str), "gok(%d)", r);
230
231         return fmtstrcpy(fp, str);
232 }
233
234 int
235 Sconv(Fmt *fp)
236 {
237         int i, c;
238         char str[30], *p, *a;
239
240         a = va_arg(fp->args, char*);
241         p = str;
242         for(i=0; i<sizeof(double); i++) {
243                 c = a[i] & 0xff;
244                 if(c >= 'a' && c <= 'z' ||
245                    c >= 'A' && c <= 'Z' ||
246                    c >= '0' && c <= '9') {
247                         *p++ = c;
248                         continue;
249                 }
250                 *p++ = '\\';
251                 switch(c) {
252                 default:
253                         if(c < 040 || c >= 0177)
254                                 break;  /* not portable */
255                         p[-1] = c;
256                         continue;
257                 case 0:
258                         *p++ = 'z';
259                         continue;
260                 case '\\':
261                 case '"':
262                         *p++ = c;
263                         continue;
264                 case '\n':
265                         *p++ = 'n';
266                         continue;
267                 case '\t':
268                         *p++ = 't';
269                         continue;
270                 }
271                 *p++ = (c>>6) + '0';
272                 *p++ = ((c>>3) & 7) + '0';
273                 *p++ = (c & 7) + '0';
274         }
275         *p = 0;
276         return fmtstrcpy(fp, str);
277 }