Blame


1 7d6f5677 2005-11-28 devnull /*
2 7d6f5677 2005-11-28 devnull * gcc3 name demangler.
3 7d6f5677 2005-11-28 devnull */
4 7d6f5677 2005-11-28 devnull #include <u.h>
5 7d6f5677 2005-11-28 devnull #include <libc.h>
6 7d6f5677 2005-11-28 devnull #include <bio.h>
7 7d6f5677 2005-11-28 devnull #include <mach.h>
8 7d6f5677 2005-11-28 devnull
9 7d6f5677 2005-11-28 devnull typedef struct Chartab Chartab;
10 7d6f5677 2005-11-28 devnull struct Chartab
11 7d6f5677 2005-11-28 devnull {
12 7d6f5677 2005-11-28 devnull char c;
13 7d6f5677 2005-11-28 devnull char *s;
14 7d6f5677 2005-11-28 devnull };
15 7d6f5677 2005-11-28 devnull
16 7d6f5677 2005-11-28 devnull static char*
17 7d6f5677 2005-11-28 devnull chartabsearch(Chartab *ct, int c)
18 7d6f5677 2005-11-28 devnull {
19 7d6f5677 2005-11-28 devnull for(; ct->c; ct++)
20 7d6f5677 2005-11-28 devnull if(ct->c == c)
21 7d6f5677 2005-11-28 devnull return ct->s;
22 7d6f5677 2005-11-28 devnull return nil;
23 7d6f5677 2005-11-28 devnull }
24 7d6f5677 2005-11-28 devnull
25 7d6f5677 2005-11-28 devnull typedef struct Gccstate Gccstate;
26 7d6f5677 2005-11-28 devnull struct Gccstate
27 7d6f5677 2005-11-28 devnull {
28 7d6f5677 2005-11-28 devnull char *name[128];
29 7d6f5677 2005-11-28 devnull int nname;
30 7d6f5677 2005-11-28 devnull };
31 7d6f5677 2005-11-28 devnull static int gccname(char**, char**, Gccstate*);
32 7d6f5677 2005-11-28 devnull char*
33 7d6f5677 2005-11-28 devnull demanglegcc3(char *s, char *buf)
34 7d6f5677 2005-11-28 devnull {
35 7d6f5677 2005-11-28 devnull char *p, *os;
36 7d6f5677 2005-11-28 devnull Gccstate state;
37 fa325e9b 2020-01-10 cross
38 7d6f5677 2005-11-28 devnull state.nname = 0;
39 7d6f5677 2005-11-28 devnull os = s;
40 7d6f5677 2005-11-28 devnull /* mangled names always start with _Z */
41 7d6f5677 2005-11-28 devnull if(s[0] != '_' || s[1] != 'Z')
42 7d6f5677 2005-11-28 devnull return s;
43 7d6f5677 2005-11-28 devnull s += 2;
44 fa325e9b 2020-01-10 cross
45 7d6f5677 2005-11-28 devnull p = buf;
46 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, &state)){
47 7d6f5677 2005-11-28 devnull if(strchr(os, '@') == nil)
48 7d6f5677 2005-11-28 devnull fprint(2, "demangle: %s\n");
49 7d6f5677 2005-11-28 devnull return os;
50 7d6f5677 2005-11-28 devnull }
51 7d6f5677 2005-11-28 devnull if(*s){
52 7d6f5677 2005-11-28 devnull /* the rest of the name is the argument types */
53 7d6f5677 2005-11-28 devnull *p++ = '(';
54 7d6f5677 2005-11-28 devnull while(*s != 0 && gccname(&s, &p, &state))
55 7d6f5677 2005-11-28 devnull *p++ = ',';
56 7d6f5677 2005-11-28 devnull if(*(p-1) == ',')
57 7d6f5677 2005-11-28 devnull p--;
58 7d6f5677 2005-11-28 devnull *p++ = ')';
59 7d6f5677 2005-11-28 devnull }
60 7d6f5677 2005-11-28 devnull *p = 0;
61 7d6f5677 2005-11-28 devnull return buf;
62 7d6f5677 2005-11-28 devnull }
63 7d6f5677 2005-11-28 devnull
64 7d6f5677 2005-11-28 devnull static Chartab stdnames[] =
65 7d6f5677 2005-11-28 devnull {
66 7d6f5677 2005-11-28 devnull 'a', "std::allocator",
67 7d6f5677 2005-11-28 devnull 'b', "std::basic_string",
68 7d6f5677 2005-11-28 devnull 'd', "std::iostream",
69 7d6f5677 2005-11-28 devnull 'i', "std::istream",
70 7d6f5677 2005-11-28 devnull 'o', "std::ostream",
71 7d6f5677 2005-11-28 devnull 's', "std::string",
72 7d6f5677 2005-11-28 devnull 0, 0
73 7d6f5677 2005-11-28 devnull };
74 7d6f5677 2005-11-28 devnull
75 7d6f5677 2005-11-28 devnull static Chartab typetab[] =
76 7d6f5677 2005-11-28 devnull {
77 7d6f5677 2005-11-28 devnull 'b', "bool",
78 7d6f5677 2005-11-28 devnull 'c', "char",
79 7d6f5677 2005-11-28 devnull 'd', "double",
80 7d6f5677 2005-11-28 devnull 'i', "int",
81 7d6f5677 2005-11-28 devnull 'j', "uint",
82 7d6f5677 2005-11-28 devnull 'v', "void",
83 7d6f5677 2005-11-28 devnull 0, 0
84 7d6f5677 2005-11-28 devnull };
85 7d6f5677 2005-11-28 devnull
86 7d6f5677 2005-11-28 devnull static struct {
87 7d6f5677 2005-11-28 devnull char *shrt;
88 7d6f5677 2005-11-28 devnull char *actual;
89 7d6f5677 2005-11-28 devnull char *lng;
90 7d6f5677 2005-11-28 devnull } operators[] =
91 7d6f5677 2005-11-28 devnull {
92 7d6f5677 2005-11-28 devnull "aN", "&=", "andeq",
93 7d6f5677 2005-11-28 devnull "aS", "=", "assign",
94 7d6f5677 2005-11-28 devnull "aa", "&&", "andand",
95 7d6f5677 2005-11-28 devnull "ad", "&", "and",
96 7d6f5677 2005-11-28 devnull "an", "&", "and",
97 7d6f5677 2005-11-28 devnull "cl", "()", "construct",
98 7d6f5677 2005-11-28 devnull "cm", ",", "comma",
99 7d6f5677 2005-11-28 devnull "co", "~", "twiddle",
100 7d6f5677 2005-11-28 devnull "dV", "/=", "diveq",
101 7d6f5677 2005-11-28 devnull "da", "delete[]", "deletearray",
102 7d6f5677 2005-11-28 devnull "de", "*", "star",
103 7d6f5677 2005-11-28 devnull "dl", "delete", "delete",
104 7d6f5677 2005-11-28 devnull "dv", "/", "div",
105 7d6f5677 2005-11-28 devnull "eO", "^=", "xoreq",
106 7d6f5677 2005-11-28 devnull "eo", "^", "xor",
107 7d6f5677 2005-11-28 devnull "eq", "==", "eq",
108 7d6f5677 2005-11-28 devnull "ge", ">=", "geq",
109 7d6f5677 2005-11-28 devnull "gt", ">", "gt",
110 7d6f5677 2005-11-28 devnull "ix", "[]", "index",
111 7d6f5677 2005-11-28 devnull "IS", "<<=", "lsheq",
112 7d6f5677 2005-11-28 devnull "le", "<=", "leq",
113 7d6f5677 2005-11-28 devnull "ls", "<<", "lsh",
114 7d6f5677 2005-11-28 devnull "lt", "<", "lt",
115 7d6f5677 2005-11-28 devnull "ml", "-=", "subeq",
116 7d6f5677 2005-11-28 devnull "mL", "*=", "muleq",
117 7d6f5677 2005-11-28 devnull "mi", "-", "sub",
118 7d6f5677 2005-11-28 devnull "mI", "*", "mul",
119 7d6f5677 2005-11-28 devnull "mm", "--", "dec",
120 7d6f5677 2005-11-28 devnull "na", "new[]", "newarray",
121 7d6f5677 2005-11-28 devnull "ne", "!=", "neq",
122 7d6f5677 2005-11-28 devnull "ng", "-", "neg",
123 7d6f5677 2005-11-28 devnull "nt", "!", "not",
124 7d6f5677 2005-11-28 devnull "nw", "new", "new",
125 7d6f5677 2005-11-28 devnull "oR", "|=", "oreq",
126 7d6f5677 2005-11-28 devnull "oo", "||", "oror",
127 7d6f5677 2005-11-28 devnull "or", "|", "or",
128 7d6f5677 2005-11-28 devnull "pL", "+=", "addeq",
129 7d6f5677 2005-11-28 devnull "pl", "+", "add",
130 7d6f5677 2005-11-28 devnull "pm", "->*", "pointstoderef",
131 7d6f5677 2005-11-28 devnull "pp", "++", "inc",
132 7d6f5677 2005-11-28 devnull "ps", "+", "pos",
133 7d6f5677 2005-11-28 devnull "pt", "->", "pointsto",
134 7d6f5677 2005-11-28 devnull "qu", "?", "question",
135 7d6f5677 2005-11-28 devnull "rM", "%=", "modeq",
136 7d6f5677 2005-11-28 devnull "rS", ">>=", "rsheq",
137 7d6f5677 2005-11-28 devnull "rm", "%", "mod",
138 7d6f5677 2005-11-28 devnull "rs", ">>", "rsh",
139 7d6f5677 2005-11-28 devnull "st", "sizeof", "sizeoftype",
140 7d6f5677 2005-11-28 devnull "sz", "sizeof", "sizeofexpr",
141 fa325e9b 2020-01-10 cross
142 7d6f5677 2005-11-28 devnull 0,0,0
143 7d6f5677 2005-11-28 devnull };
144 7d6f5677 2005-11-28 devnull
145 7d6f5677 2005-11-28 devnull /*
146 7d6f5677 2005-11-28 devnull * Pick apart the next mangled name section.
147 7d6f5677 2005-11-28 devnull * Names and types are treated as the same.
148 7d6f5677 2005-11-28 devnull * Let's see how far we can go before that becomes a problem.
149 7d6f5677 2005-11-28 devnull */
150 7d6f5677 2005-11-28 devnull static int
151 7d6f5677 2005-11-28 devnull gccname(char **ps, char **pp, Gccstate *state)
152 7d6f5677 2005-11-28 devnull {
153 7d6f5677 2005-11-28 devnull int i, n;
154 7d6f5677 2005-11-28 devnull char *os, *s, *t, *p;
155 7d6f5677 2005-11-28 devnull Gccstate nstate;
156 fa325e9b 2020-01-10 cross
157 7d6f5677 2005-11-28 devnull s = *ps;
158 7d6f5677 2005-11-28 devnull os = s;
159 7d6f5677 2005-11-28 devnull p = *pp;
160 7d6f5677 2005-11-28 devnull
161 7d6f5677 2005-11-28 devnull /* print("\tgccname: %s\n", s); */
162 7d6f5677 2005-11-28 devnull
163 7d6f5677 2005-11-28 devnull /* overloaded operators */
164 7d6f5677 2005-11-28 devnull for(i=0; operators[i].shrt; i++){
165 7d6f5677 2005-11-28 devnull if(memcmp(operators[i].shrt, s, 2) == 0){
166 7d6f5677 2005-11-28 devnull strcpy(p, "operator$");
167 7d6f5677 2005-11-28 devnull strcat(p, operators[i].lng);
168 7d6f5677 2005-11-28 devnull p += strlen(p);
169 7d6f5677 2005-11-28 devnull s += 2;
170 7d6f5677 2005-11-28 devnull goto suffix;
171 7d6f5677 2005-11-28 devnull }
172 7d6f5677 2005-11-28 devnull }
173 fa325e9b 2020-01-10 cross
174 7d6f5677 2005-11-28 devnull /* basic types */
175 7d6f5677 2005-11-28 devnull if((t = chartabsearch(typetab, *s)) != nil){
176 7d6f5677 2005-11-28 devnull s++;
177 7d6f5677 2005-11-28 devnull strcpy(p, t);
178 7d6f5677 2005-11-28 devnull p += strlen(t);
179 7d6f5677 2005-11-28 devnull goto suffix;
180 7d6f5677 2005-11-28 devnull }
181 fa325e9b 2020-01-10 cross
182 7d6f5677 2005-11-28 devnull switch(*s){
183 7d6f5677 2005-11-28 devnull default:
184 7d6f5677 2005-11-28 devnull bad:
185 7d6f5677 2005-11-28 devnull fprint(2, "bad name: %s\n", s);
186 7d6f5677 2005-11-28 devnull return 0;
187 7d6f5677 2005-11-28 devnull
188 7d6f5677 2005-11-28 devnull case '1': case '2': case '3': case '4': /* name length */
189 7d6f5677 2005-11-28 devnull case '5': case '6': case '7': case '8': case '9':
190 7d6f5677 2005-11-28 devnull n = strtol(s, &s, 10);
191 7d6f5677 2005-11-28 devnull memmove(p, s, n);
192 7d6f5677 2005-11-28 devnull p += n;
193 7d6f5677 2005-11-28 devnull s += n;
194 7d6f5677 2005-11-28 devnull break;
195 7d6f5677 2005-11-28 devnull
196 7d6f5677 2005-11-28 devnull case 'C': /* C1: constructor? */
197 7d6f5677 2005-11-28 devnull strtol(s+1, &s, 10);
198 7d6f5677 2005-11-28 devnull strcpy(p, "constructor");
199 7d6f5677 2005-11-28 devnull p += strlen(p);
200 7d6f5677 2005-11-28 devnull break;
201 7d6f5677 2005-11-28 devnull
202 7d6f5677 2005-11-28 devnull case 'D': /* D1: destructor? */
203 7d6f5677 2005-11-28 devnull strtol(s+1, &s, 10);
204 7d6f5677 2005-11-28 devnull strcpy(p, "destructor");
205 7d6f5677 2005-11-28 devnull p += strlen(p);
206 7d6f5677 2005-11-28 devnull break;
207 7d6f5677 2005-11-28 devnull
208 7d6f5677 2005-11-28 devnull case 'K': /* const */
209 7d6f5677 2005-11-28 devnull s++;
210 7d6f5677 2005-11-28 devnull strcpy(p, "const ");
211 7d6f5677 2005-11-28 devnull p += strlen(p);
212 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state))
213 7d6f5677 2005-11-28 devnull return 0;
214 7d6f5677 2005-11-28 devnull break;
215 7d6f5677 2005-11-28 devnull
216 7d6f5677 2005-11-28 devnull case 'L': /* default value */
217 7d6f5677 2005-11-28 devnull t = s;
218 7d6f5677 2005-11-28 devnull s++;
219 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state))
220 7d6f5677 2005-11-28 devnull return 0;
221 7d6f5677 2005-11-28 devnull if(!isdigit((uchar)*s)){
222 7d6f5677 2005-11-28 devnull fprint(2, "bad value: %s\n", t);
223 7d6f5677 2005-11-28 devnull return 0;
224 7d6f5677 2005-11-28 devnull }
225 7d6f5677 2005-11-28 devnull n = strtol(s, &s, 10);
226 7d6f5677 2005-11-28 devnull if(*s != 'E'){
227 7d6f5677 2005-11-28 devnull fprint(2, "bad value2: %s\n", t);
228 7d6f5677 2005-11-28 devnull return 0;
229 7d6f5677 2005-11-28 devnull }
230 7d6f5677 2005-11-28 devnull sprint(p, "=%d", n);
231 7d6f5677 2005-11-28 devnull p += strlen(p);
232 7d6f5677 2005-11-28 devnull s++;
233 7d6f5677 2005-11-28 devnull break;
234 7d6f5677 2005-11-28 devnull
235 7d6f5677 2005-11-28 devnull case 'N': /* hierarchical name */
236 7d6f5677 2005-11-28 devnull s++;
237 7d6f5677 2005-11-28 devnull while(*s != 'E'){
238 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state)){
239 7d6f5677 2005-11-28 devnull fprint(2, "bad name in hierarchy: %s in %s\n", s, os);
240 7d6f5677 2005-11-28 devnull return 0;
241 7d6f5677 2005-11-28 devnull }
242 7d6f5677 2005-11-28 devnull strcpy(p, "::");
243 7d6f5677 2005-11-28 devnull p += 2;
244 7d6f5677 2005-11-28 devnull }
245 7d6f5677 2005-11-28 devnull p -= 2;
246 7d6f5677 2005-11-28 devnull s++;
247 7d6f5677 2005-11-28 devnull break;
248 fa325e9b 2020-01-10 cross
249 7d6f5677 2005-11-28 devnull case 'P': /* pointer to */
250 7d6f5677 2005-11-28 devnull s++;
251 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state))
252 7d6f5677 2005-11-28 devnull return 0;
253 7d6f5677 2005-11-28 devnull *p++ = '*';
254 7d6f5677 2005-11-28 devnull break;
255 7d6f5677 2005-11-28 devnull
256 7d6f5677 2005-11-28 devnull case 'R': /* reference to */
257 7d6f5677 2005-11-28 devnull s++;
258 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state))
259 7d6f5677 2005-11-28 devnull return 0;
260 7d6f5677 2005-11-28 devnull *p++ = '&';
261 7d6f5677 2005-11-28 devnull break;
262 7d6f5677 2005-11-28 devnull
263 7d6f5677 2005-11-28 devnull case 'S': /* standard or previously-seen name */
264 7d6f5677 2005-11-28 devnull s++;
265 7d6f5677 2005-11-28 devnull if('0' <= *s && *s <= '9'){
266 7d6f5677 2005-11-28 devnull /* previously seen */
267 7d6f5677 2005-11-28 devnull t = s-1;
268 7d6f5677 2005-11-28 devnull n = strtol(s, &s, 10);
269 7d6f5677 2005-11-28 devnull if(*s != '_'){
270 7d6f5677 2005-11-28 devnull fprint(2, "bad S: %s\n", t);
271 7d6f5677 2005-11-28 devnull return 0;
272 7d6f5677 2005-11-28 devnull }
273 7d6f5677 2005-11-28 devnull s++;
274 7d6f5677 2005-11-28 devnull sprint(p, "S%d_", n);
275 7d6f5677 2005-11-28 devnull p += strlen(p);
276 7d6f5677 2005-11-28 devnull break;
277 7d6f5677 2005-11-28 devnull }
278 7d6f5677 2005-11-28 devnull /* SA_ ??? */
279 7d6f5677 2005-11-28 devnull if(*s == 'A' && *(s+1) == '_'){
280 7d6f5677 2005-11-28 devnull strcpy(p, "SA_");
281 7d6f5677 2005-11-28 devnull p += 3;
282 7d6f5677 2005-11-28 devnull s += 2;
283 7d6f5677 2005-11-28 devnull break;
284 7d6f5677 2005-11-28 devnull }
285 fa325e9b 2020-01-10 cross
286 7d6f5677 2005-11-28 devnull /* standard name */
287 7d6f5677 2005-11-28 devnull if(*s == 't'){
288 7d6f5677 2005-11-28 devnull strcpy(p, "std::");
289 7d6f5677 2005-11-28 devnull p += 5;
290 7d6f5677 2005-11-28 devnull s++;
291 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, state))
292 7d6f5677 2005-11-28 devnull return 0;
293 7d6f5677 2005-11-28 devnull }else if((t = chartabsearch(stdnames, *s)) != nil){
294 7d6f5677 2005-11-28 devnull strcpy(p, t);
295 7d6f5677 2005-11-28 devnull p += strlen(p);
296 7d6f5677 2005-11-28 devnull s++;
297 7d6f5677 2005-11-28 devnull }else{
298 7d6f5677 2005-11-28 devnull strcpy(p, "std::");
299 7d6f5677 2005-11-28 devnull p += 5;
300 7d6f5677 2005-11-28 devnull *p++ = *s++;
301 7d6f5677 2005-11-28 devnull }
302 7d6f5677 2005-11-28 devnull break;
303 fa325e9b 2020-01-10 cross
304 7d6f5677 2005-11-28 devnull case 'T': /* previously-seen type??? T0_ also T_*/
305 7d6f5677 2005-11-28 devnull t = s;
306 7d6f5677 2005-11-28 devnull for(; *s != '_'; s++){
307 7d6f5677 2005-11-28 devnull if(*s == 0){
308 7d6f5677 2005-11-28 devnull s = t;
309 7d6f5677 2005-11-28 devnull goto bad;
310 7d6f5677 2005-11-28 devnull }
311 7d6f5677 2005-11-28 devnull }
312 7d6f5677 2005-11-28 devnull s++;
313 7d6f5677 2005-11-28 devnull memmove(p, t, s-t);
314 7d6f5677 2005-11-28 devnull p += s-t;
315 fa325e9b 2020-01-10 cross break;
316 7d6f5677 2005-11-28 devnull }
317 fa325e9b 2020-01-10 cross
318 7d6f5677 2005-11-28 devnull suffix:
319 7d6f5677 2005-11-28 devnull if(*s == 'I'){
320 7d6f5677 2005-11-28 devnull /* template suffix */
321 7d6f5677 2005-11-28 devnull nstate.nname = 0;
322 7d6f5677 2005-11-28 devnull *p++ = '<';
323 7d6f5677 2005-11-28 devnull s++;
324 7d6f5677 2005-11-28 devnull while(*s != 'E'){
325 7d6f5677 2005-11-28 devnull if(!gccname(&s, &p, &nstate)){
326 7d6f5677 2005-11-28 devnull fprint(2, "bad name in template: %s\n", s);
327 7d6f5677 2005-11-28 devnull return 0;
328 7d6f5677 2005-11-28 devnull }
329 7d6f5677 2005-11-28 devnull *p++ = ',';
330 7d6f5677 2005-11-28 devnull }
331 7d6f5677 2005-11-28 devnull *(p-1) = '>';
332 7d6f5677 2005-11-28 devnull s++;
333 7d6f5677 2005-11-28 devnull }
334 7d6f5677 2005-11-28 devnull
335 7d6f5677 2005-11-28 devnull *ps = s;
336 7d6f5677 2005-11-28 devnull *pp = p;
337 7d6f5677 2005-11-28 devnull return 1;
338 7d6f5677 2005-11-28 devnull }