/[gxemul]/upstream/0.4.1/src/symbol_demangle.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.4.1/src/symbol_demangle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29 - (show annotations)
Mon Oct 8 16:20:32 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 7063 byte(s)
0.4.1
1 /*
2 * Copyright (C) 2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: symbol_demangle.c,v 1.5 2006/05/01 09:00:19 debug Exp $
29 *
30 * C++ symbol name demangling.
31 *
32 * For obvious performance reasons, we cannot call the external c++filt
33 * utility. The host's version of this utility might be incompatible with the
34 * binary being emulated.
35 *
36 * TODO: Constructors, destructors, and lots of other stuff. See
37 * http://www.codesourcery.com/cxx-abi/abi.html#mangling for details.
38 */
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <ctype.h>
44
45 #include "symbol.h"
46
47
48 #define MAXLEN 1000
49
50
51 static void add_string(char *p, size_t *curlenp, char *to_add)
52 {
53 size_t curlen = *curlenp;
54 while (curlen < MAXLEN && *to_add)
55 p[curlen++] = *to_add++;
56 *curlenp = curlen;
57 }
58
59
60 /*
61 * symbol_demangle_cplusplus_nested():
62 *
63 * Try to demangle a nested cplusplus name. name points to the first character
64 * after "_ZN".
65 */
66 static char *symbol_demangle_cplusplus_nested(char *name)
67 {
68 char *result = malloc(MAXLEN + 1);
69 size_t result_len = 0, len;
70 int first = 1, type_added = 0, pointercounter, reference;
71
72 result[0] = '\0';
73
74 while (name[0] && name[0] != 'E' && result_len < MAXLEN) {
75 /* Read length of the next part: */
76 len = 0;
77 if (*name == '0') {
78 name ++;
79 } else {
80 while (isdigit((int)*name)) {
81 len *= 10;
82 len += (*name - '0');
83 name ++;
84 }
85 }
86
87 /* Add :: */
88 if (!first)
89 add_string(result, &result_len, "::");
90
91 /* Read the part itself: */
92 while (len-- >= 1 && result_len < MAXLEN)
93 result[result_len ++] = *name++;
94
95 first = 0;
96 }
97
98 if (name[0] != 'E')
99 goto fail;
100
101 name ++;
102
103 if (*name)
104 add_string(result, &result_len, "{");
105
106 /* Type: */
107 pointercounter = reference = 0;
108 while (*name) {
109 int argument_done = 0;
110 char t = *name++;
111 switch (t) {
112 case 'c':
113 add_string(result, &result_len, "char");
114 argument_done = 1;
115 break;
116 case 'a':
117 add_string(result, &result_len, "signed char");
118 argument_done = 1;
119 break;
120 case 'h':
121 add_string(result, &result_len, "unsigned char");
122 argument_done = 1;
123 break;
124 case 'i':
125 add_string(result, &result_len, "int");
126 argument_done = 1;
127 break;
128 case 'j':
129 add_string(result, &result_len, "unsigned int");
130 argument_done = 1;
131 break;
132 case 'w':
133 add_string(result, &result_len, "wchar_t");
134 argument_done = 1;
135 break;
136 case 'b':
137 add_string(result, &result_len, "bool");
138 argument_done = 1;
139 break;
140 case 's':
141 add_string(result, &result_len, "short");
142 argument_done = 1;
143 break;
144 case 't':
145 add_string(result, &result_len, "unsigned short");
146 argument_done = 1;
147 break;
148 case 'l':
149 add_string(result, &result_len, "long");
150 argument_done = 1;
151 break;
152 case 'm':
153 add_string(result, &result_len, "unsigned long");
154 argument_done = 1;
155 break;
156 case 'x':
157 add_string(result, &result_len, "long long");
158 argument_done = 1;
159 break;
160 case 'y':
161 add_string(result, &result_len, "unsigned long long");
162 argument_done = 1;
163 break;
164 case 'n':
165 add_string(result, &result_len, "__int128");
166 argument_done = 1;
167 break;
168 case 'o':
169 add_string(result, &result_len, "unsigned __int128");
170 argument_done = 1;
171 break;
172 case 'f':
173 add_string(result, &result_len, "float");
174 argument_done = 1;
175 break;
176 case 'd':
177 add_string(result, &result_len, "double");
178 argument_done = 1;
179 break;
180 case 'e':
181 add_string(result, &result_len, "__float80");
182 argument_done = 1;
183 break;
184 case 'g':
185 add_string(result, &result_len, "__float128");
186 argument_done = 1;
187 break;
188 case 'z':
189 add_string(result, &result_len, "...");
190 argument_done = 1;
191 break;
192 case 'P':
193 pointercounter ++;
194 break;
195 case 'R':
196 reference ++;
197 break;
198 case 'v': /* void */
199 break;
200 default:/* Unknown */
201 goto fail;
202 }
203 if (argument_done) {
204 while (pointercounter-- > 0)
205 add_string(result, &result_len, "*");
206 while (reference-- > 0)
207 add_string(result, &result_len, "&");
208 if (*name)
209 add_string(result, &result_len, ",");
210 }
211 type_added = 1;
212 }
213
214 if (type_added)
215 add_string(result, &result_len, "}");
216
217 if (result_len == MAXLEN)
218 goto fail;
219
220 result[result_len] = '\0';
221
222 return result;
223
224 fail:
225 free(result);
226 return NULL;
227 }
228
229
230 /*
231 * symbol_demangle_cplusplus():
232 *
233 * Try to demangle name. If name was not a valid/known C++ symbol, then NULL
234 * is returned. Otherwise, a newly allocated string is returned, containing
235 * the demangled name.
236 */
237 char *symbol_demangle_cplusplus(char *name)
238 {
239 /* Only support _Z-style mangled names, for now: */
240 if (strlen(name) < 2 || name[0] != '_' || name[1] != 'Z')
241 return NULL;
242
243 name += 2;
244
245 switch (name[0]) {
246 case 'N':
247 return symbol_demangle_cplusplus_nested(name + 1);
248 break;
249 }
250
251 return NULL;
252 }
253
254
255
256 #ifdef TEST
257
258 void test(char *mangled, char *result)
259 {
260 char *p = symbol_demangle_cplusplus(mangled);
261 if (p == NULL) {
262 if (result == NULL) {
263 return;
264 } else {
265 printf("FAILURE for %s!\n", mangled);
266 exit(1);
267 }
268 }
269 if (strcmp(p, result) == 0)
270 return;
271 printf("FAILURE for %s! (result = %s)\n", mangled, p);
272 exit(1);
273 }
274
275 int main(int argc, char *argv[])
276 {
277 test("monkey", NULL);
278 test("_monkey", NULL);
279 test("_zmonkey", NULL);
280 test("_Zmonkey", NULL);
281 test("_ZQ5abcde", NULL);
282 test("_ZN3abc5defghE", "abc::defgh");
283 test("_ZN05defghEv", "::defgh{}");
284 test("_ZN5defghEv", "defgh{}");
285 test("_ZN3abc5defghEv", "abc::defgh{}");
286 test("_ZN3abc5defghEc", "abc::defgh{char}");
287 test("_ZN1a2bcEjij", "a::bc{unsigned int,int,unsigned int}");
288 printf("OK\n");
289 return 0;
290 }
291
292 #endif
293

  ViewVC Help
Powered by ViewVC 1.1.26