]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/acid/util.c
acid: handle buffer overflow with ridiculous long symbol names (thanks mischief)
[plan9front.git] / sys / src / cmd / acid / util.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ctype.h>
5 #include <mach.h>
6 #define Extern extern
7 #include "acid.h"
8 #include "y.tab.h"
9
10 static int syren;
11
12 Lsym*
13 unique(char *buf, Sym *s)
14 {
15         Lsym *l;
16         int i, renamed;
17
18         renamed = 0;
19         strcpy(buf, s->name);
20         for(;;) {
21                 l = look(buf);
22                 if(l == 0 || (l->lexval == Tid && l->v->set == 0))
23                         break;
24
25                 if(syren == 0 && !quiet) {
26                         print("Symbol renames:\n");
27                         syren = 1;
28                 }
29                 i = strlen(buf)+1;
30                 memmove(buf+1, buf, i);
31                 buf[0] = '$';
32                 renamed++;
33                 if(renamed > 5 && !quiet) {
34                         print("Too many renames; must be X source!\n");
35                         break;
36                 }
37         }
38         if(renamed && !quiet)
39                 print("\t%s=%s %c/%llux\n", s->name, buf, s->type, s->value);
40         if(l == 0)
41                 l = enter(buf, Tid);
42         return l;       
43 }
44
45 void
46 varsym(void)
47 {
48         int i;
49         Sym *s;
50         long n;
51         Lsym *l;
52         uvlong v;
53         char buf[1024];
54         List *list, **tail, *l2, *tl;
55
56         tail = &l2;
57         l2 = 0;
58
59         symbase(&n);
60         for(i = 0; i < n; i++) {
61                 s = getsym(i);
62                 switch(s->type) {
63                 case 'T':
64                 case 'L':
65                 case 'D':
66                 case 'B':
67                 case 'b':
68                 case 'd':
69                 case 'l':
70                 case 't':
71                         if(s->name[0] == '.')
72                                 continue;
73
74                         if(strlen(s->name) >= sizeof(buf)-6){
75                                 if(!quiet)
76                                         print("Symbol name too long: %s\n", s->name);
77                                 continue;
78                         }
79
80                         v = s->value;
81                         tl = al(TLIST);
82                         *tail = tl;
83                         tail = &tl->next;
84
85                         l = unique(buf, s);
86
87                         l->v->set = 1;
88                         l->v->type = TINT;
89                         l->v->ival = v;
90                         if(l->v->comt == 0)
91                                 l->v->fmt = 'X';
92
93                         /* Enter as list of { name, type, value } */
94                         list = al(TSTRING);
95                         tl->l = list;
96                         list->string = strnode(buf);
97                         list->fmt = 's';
98                         list->next = al(TINT);
99                         list = list->next;
100                         list->fmt = 'c';
101                         list->ival = s->type;
102                         list->next = al(TINT);
103                         list = list->next;
104                         list->fmt = 'X';
105                         list->ival = v;
106
107                 }
108         }
109         l = mkvar("symbols");
110         l->v->set = 1;
111         l->v->type = TLIST;
112         l->v->l = l2;
113         if(l2 == 0)
114                 print("no symbol information\n");
115 }
116
117 void
118 varreg(void)
119 {
120         Lsym *l;
121         Value *v;
122         Reglist *r;
123         List **tail, *li;
124
125         l = mkvar("registers");
126         v = l->v;
127         v->set = 1;
128         v->type = TLIST;
129         v->l = 0;
130         tail = &v->l;
131
132         for(r = mach->reglist; r->rname; r++) {
133                 l = mkvar(r->rname);
134                 v = l->v;
135                 v->set = 1;
136                 v->ival = r->roffs;
137                 v->fmt = r->rformat;
138                 v->type = TINT;
139
140                 li = al(TSTRING);
141                 li->string = strnode(r->rname);
142                 li->fmt = 's';
143                 *tail = li;
144                 tail = &li->next;
145         }
146
147         if(machdata == 0)
148                 return;
149
150         l = mkvar("bpinst");    /* Breakpoint text */
151         v = l->v;
152         v->type = TSTRING;
153         v->fmt = 's';
154         v->set = 1;
155         v->string = gmalloc(sizeof(String));
156         v->string->len = machdata->bpsize;
157         v->string->string = gmalloc(machdata->bpsize);
158         memmove(v->string->string, machdata->bpinst, machdata->bpsize);
159 }
160
161 void
162 loadvars(void)
163 {
164         Lsym *l;
165         Value *v;
166
167         l =  mkvar("proc");
168         v = l->v;
169         v->type = TINT;
170         v->fmt = 'X';
171         v->set = 1;
172         v->ival = 0;
173
174         l = mkvar("pid");               /* Current process */
175         v = l->v;
176         v->type = TINT;
177         v->fmt = 'D';
178         v->set = 1;
179         v->ival = 0;
180
181         mkvar("notes");                 /* Pending notes */
182
183         l = mkvar("proclist");          /* Attached processes */
184         l->v->type = TLIST;
185 }
186
187 uvlong
188 rget(Map *map, char *reg)
189 {
190         Lsym *s;
191         ulong x;
192         uvlong v;
193         int ret;
194
195         s = look(reg);
196         if(s == 0)
197                 fatal("rget: %s\n", reg);
198
199         switch(s->v->fmt){
200         default:
201                 ret = get4(map, s->v->ival, &x);
202                 v = x;
203                 break;
204         case 'V':
205         case 'W':
206         case 'Y':
207         case 'Z':
208                 ret = get8(map, s->v->ival, &v);
209                 break;
210         }
211         if(ret < 0)
212                 error("can't get register %s: %r", reg);
213         return v;
214 }
215
216 String*
217 strnodlen(char *name, int len)
218 {
219         String *s;
220
221         s = gmalloc(sizeof(String)+len+1);
222         s->string = (char*)s+sizeof(String);
223         s->len = len;
224         if(name != 0)
225                 memmove(s->string, name, len);
226         s->string[len] = '\0';
227
228         s->gclink = gcl;
229         gcl = s;
230
231         return s;
232 }
233
234 String*
235 strnode(char *name)
236 {
237         return strnodlen(name, strlen(name));
238 }
239
240 String*
241 runenode(Rune *name)
242 {
243         int len;
244         Rune *p;
245         String *s;
246
247         p = name;
248         for(len = 0; *p; p++)
249                 len++;
250
251         len++;
252         len *= sizeof(Rune);
253         s = gmalloc(sizeof(String)+len);
254         s->string = (char*)s+sizeof(String);
255         s->len = len;
256         memmove(s->string, name, len);
257
258         s->gclink = gcl;
259         gcl = s;
260
261         return s;
262 }
263
264 String*
265 stradd(String *l, String *r)
266 {
267         int len;
268         String *s;
269
270         len = l->len+r->len;
271         s = gmalloc(sizeof(String)+len+1);
272         s->gclink = gcl;
273         gcl = s;
274         s->len = len;
275         s->string = (char*)s+sizeof(String);
276         memmove(s->string, l->string, l->len);
277         memmove(s->string+l->len, r->string, r->len);
278         s->string[s->len] = 0;
279         return s;
280 }
281
282 String*
283 straddrune(String *l, Rune r)
284 {
285         int len;
286         String *s;
287
288         len = l->len+runelen(r);
289         s = gmalloc(sizeof(String)+len+1);
290         s->gclink = gcl;
291         gcl = s;
292         s->len = len;
293         s->string = (char*)s+sizeof(String);
294         memmove(s->string, l->string, l->len);
295         runetochar(s->string+l->len, &r);
296         s->string[s->len] = 0;
297         return s;
298 }
299
300 int
301 scmp(String *sr, String *sl)
302 {
303         if(sr->len != sl->len)
304                 return 0;
305
306         if(memcmp(sr->string, sl->string, sl->len))
307                 return 0;
308
309         return 1;
310 }