2 7d6f5677 2005-11-28 devnull * gcc3 name demangler.
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>
9 7d6f5677 2005-11-28 devnull typedef struct Chartab Chartab;
10 7d6f5677 2005-11-28 devnull struct Chartab
16 7d6f5677 2005-11-28 devnull static char*
17 7d6f5677 2005-11-28 devnull chartabsearch(Chartab *ct, int c)
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;
25 7d6f5677 2005-11-28 devnull typedef struct Gccstate Gccstate;
26 7d6f5677 2005-11-28 devnull struct Gccstate
28 7d6f5677 2005-11-28 devnull char *name[128];
29 7d6f5677 2005-11-28 devnull int nname;
31 7d6f5677 2005-11-28 devnull static int gccname(char**, char**, Gccstate*);
33 7d6f5677 2005-11-28 devnull demanglegcc3(char *s, char *buf)
35 7d6f5677 2005-11-28 devnull char *p, *os;
36 7d6f5677 2005-11-28 devnull Gccstate state;
38 7d6f5677 2005-11-28 devnull state.nname = 0;
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;
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;
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) == ',')
58 7d6f5677 2005-11-28 devnull *p++ = ')';
61 7d6f5677 2005-11-28 devnull return buf;
64 7d6f5677 2005-11-28 devnull static Chartab stdnames[] =
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",
75 7d6f5677 2005-11-28 devnull static Chartab typetab[] =
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",
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[] =
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",
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.
150 7d6f5677 2005-11-28 devnull static int
151 7d6f5677 2005-11-28 devnull gccname(char **ps, char **pp, Gccstate *state)
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;
157 7d6f5677 2005-11-28 devnull s = *ps;
159 7d6f5677 2005-11-28 devnull p = *pp;
161 7d6f5677 2005-11-28 devnull /* print("\tgccname: %s\n", s); */
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);
170 7d6f5677 2005-11-28 devnull goto suffix;
174 7d6f5677 2005-11-28 devnull /* basic types */
175 7d6f5677 2005-11-28 devnull if((t = chartabsearch(typetab, *s)) != nil){
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;
182 7d6f5677 2005-11-28 devnull switch(*s){
183 7d6f5677 2005-11-28 devnull default:
185 7d6f5677 2005-11-28 devnull fprint(2, "bad name: %s\n", s);
186 7d6f5677 2005-11-28 devnull return 0;
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);
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);
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);
208 7d6f5677 2005-11-28 devnull case 'K': /* const */
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;
216 7d6f5677 2005-11-28 devnull case 'L': /* default value */
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;
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;
230 7d6f5677 2005-11-28 devnull sprint(p, "=%d", n);
231 7d6f5677 2005-11-28 devnull p += strlen(p);
235 7d6f5677 2005-11-28 devnull case 'N': /* hierarchical name */
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;
242 7d6f5677 2005-11-28 devnull strcpy(p, "::");
249 7d6f5677 2005-11-28 devnull case 'P': /* pointer to */
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++ = '*';
256 7d6f5677 2005-11-28 devnull case 'R': /* reference to */
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++ = '&';
263 7d6f5677 2005-11-28 devnull case 'S': /* standard or previously-seen name */
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;
274 7d6f5677 2005-11-28 devnull sprint(p, "S%d_", n);
275 7d6f5677 2005-11-28 devnull p += strlen(p);
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_");
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::");
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);
298 7d6f5677 2005-11-28 devnull strcpy(p, "std::");
300 7d6f5677 2005-11-28 devnull *p++ = *s++;
304 7d6f5677 2005-11-28 devnull case 'T': /* previously-seen type??? T0_ also T_*/
306 7d6f5677 2005-11-28 devnull for(; *s != '_'; s++){
307 7d6f5677 2005-11-28 devnull if(*s == 0){
309 7d6f5677 2005-11-28 devnull goto bad;
313 7d6f5677 2005-11-28 devnull memmove(p, t, s-t);
314 7d6f5677 2005-11-28 devnull p += s-t;
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++ = '<';
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;
329 7d6f5677 2005-11-28 devnull *p++ = ',';
331 7d6f5677 2005-11-28 devnull *(p-1) = '>';
335 7d6f5677 2005-11-28 devnull *ps = s;
336 7d6f5677 2005-11-28 devnull *pp = p;
337 7d6f5677 2005-11-28 devnull return 1;