/[gxemul]/trunk/src/symbol/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

Annotation of /trunk/src/symbol/symbol_demangle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 44 - (hide annotations)
Mon Oct 8 16:22:56 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 7101 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1632 2007/09/11 21:46:35 debug Exp $
20070616	Implementing the MIPS32/64 revision 2 "ror" instruction.
20070617	Adding a struct for each physpage which keeps track of which
		ranges within that page (base offset, length) that are
		continuously translatable. When running with native code
		generation enabled (-b), a range is added after each read-
		ahead loop.
		Experimenting with using the physical program counter sample
		data (implemented 20070608) together with the "translatable
		range" information, to figure out which physical address ranges
		would be worth translating to native code (if the number of
		samples falling within a range is above a certain threshold).
20070618	Adding automagic building of .index comment files for
		src/file/, src/promemul/, src src/useremul/ as well.
		Adding a "has been translated" bit to the ranges, so that only
		not-yet-translated ranges will be sampled.
20070619	Moving src/cpu.c and src/memory_rw.c into src/cpus/,
		src/device.c into src/devices/, and src/machine.c into
		src/machines/.
		Creating a skeleton cc/ld native backend module; beginning on
		the function which will detect cc command line, etc.
20070620	Continuing on the native code generation infrastructure.
20070621	Moving src/x11.c and src/console.c into a new src/console/
		subdir (for everything that is console or framebuffer related).
		Moving src/symbol*.c into a new src/symbol/, which should
		contain anything that is symbol handling related.
20070624	Making the program counter sampling threshold a "settings
		variable" (sampling_threshold), i.e. it can now be changed
		during runtime.
		Switching the RELEASE notes format from plain text to HTML.
		If the TMPDIR environment variable is set, it is used instead
		of "/tmp" for temporary files.
		Continuing on the cc/ld backend: simple .c code is generated,
		the compiler and linker are called, etc.
		Adding detection of host architecture to the configure script
		(again), and adding icache invalidation support (only
		implemented for Alpha hosts so far).
20070625	Simplifying the program counter sampling mechanism.
20070626	Removing the cc/ld native code generation stuff, program
		counter sampling, etc; it would not have worked well in the
		general case.
20070627	Removing everything related to native code generation.
20070629	Removing the (practically unusable) support for multiple
		emulations. (The single emulation allowed now still supports
		multiple simultaneous machines, as before.)
		Beginning on PCCTWO and M88K interrupts.
20070723	Adding a dummy skeleton for emulation of M32R processors.
20070901	Fixing a warning found by "gcc version 4.3.0 20070817
		(experimental)" on amd64.
20070905	Removing some more traces of the old "multiple emulations"
		code.
		Also looking in /usr/local/include and /usr/local/lib for
		X11 libs, when running configure.
20070909	Minor updates to the guest OS install instructions, in
		preparation for the NetBSD 4.0 release.
20070918	More testing of NetBSD 4.0 RC1.

1 dpavlin 44 /*
2     * Copyright (C) 2006-2007 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.1 2007/06/20 14:25:14 debug Exp $
29     *
30     * C++ symbol name demangling.
31     *
32     * For obvious performance reasons, the external c++filt utility cannot be
33     * used. Also, the host's version of this utility might be incompatible with
34     * the 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;
69     size_t result_len = 0, len;
70     int first = 1, type_added = 0, pointercounter, reference;
71    
72     CHECK_ALLOCATION(result = malloc(MAXLEN + 1));
73     result[0] = '\0';
74    
75     while (name[0] && name[0] != 'E' && result_len < MAXLEN) {
76     /* Read length of the next part: */
77     len = 0;
78     if (*name == '0') {
79     name ++;
80     } else {
81     while (isdigit((int)*name)) {
82     len *= 10;
83     len += (*name - '0');
84     name ++;
85     }
86     }
87    
88     /* Add :: */
89     if (!first)
90     add_string(result, &result_len, "::");
91    
92     /* Read the part itself: */
93     while (len-- >= 1 && result_len < MAXLEN)
94     result[result_len ++] = *name++;
95    
96     first = 0;
97     }
98    
99     if (name[0] != 'E')
100     goto fail;
101    
102     name ++;
103    
104     if (*name)
105     add_string(result, &result_len, "{");
106    
107     /* Type: */
108     pointercounter = reference = 0;
109     while (*name) {
110     int argument_done = 0;
111     char t = *name++;
112     switch (t) {
113     case 'c':
114     add_string(result, &result_len, "char");
115     argument_done = 1;
116     break;
117     case 'a':
118     add_string(result, &result_len, "signed char");
119     argument_done = 1;
120     break;
121     case 'h':
122     add_string(result, &result_len, "unsigned char");
123     argument_done = 1;
124     break;
125     case 'i':
126     add_string(result, &result_len, "int");
127     argument_done = 1;
128     break;
129     case 'j':
130     add_string(result, &result_len, "unsigned int");
131     argument_done = 1;
132     break;
133     case 'w':
134     add_string(result, &result_len, "wchar_t");
135     argument_done = 1;
136     break;
137     case 'b':
138     add_string(result, &result_len, "bool");
139     argument_done = 1;
140     break;
141     case 's':
142     add_string(result, &result_len, "short");
143     argument_done = 1;
144     break;
145     case 't':
146     add_string(result, &result_len, "unsigned short");
147     argument_done = 1;
148     break;
149     case 'l':
150     add_string(result, &result_len, "long");
151     argument_done = 1;
152     break;
153     case 'm':
154     add_string(result, &result_len, "unsigned long");
155     argument_done = 1;
156     break;
157     case 'x':
158     add_string(result, &result_len, "long long");
159     argument_done = 1;
160     break;
161     case 'y':
162     add_string(result, &result_len, "unsigned long long");
163     argument_done = 1;
164     break;
165     case 'n':
166     add_string(result, &result_len, "__int128");
167     argument_done = 1;
168     break;
169     case 'o':
170     add_string(result, &result_len, "unsigned __int128");
171     argument_done = 1;
172     break;
173     case 'f':
174     add_string(result, &result_len, "float");
175     argument_done = 1;
176     break;
177     case 'd':
178     add_string(result, &result_len, "double");
179     argument_done = 1;
180     break;
181     case 'e':
182     add_string(result, &result_len, "__float80");
183     argument_done = 1;
184     break;
185     case 'g':
186     add_string(result, &result_len, "__float128");
187     argument_done = 1;
188     break;
189     case 'z':
190     add_string(result, &result_len, "...");
191     argument_done = 1;
192     break;
193     case 'P':
194     pointercounter ++;
195     break;
196     case 'R':
197     reference ++;
198     break;
199     case 'v': /* void */
200     break;
201     default:/* Unknown */
202     goto fail;
203     }
204     if (argument_done) {
205     while (pointercounter-- > 0)
206     add_string(result, &result_len, "*");
207     while (reference-- > 0)
208     add_string(result, &result_len, "&");
209     if (*name)
210     add_string(result, &result_len, ",");
211     }
212     type_added = 1;
213     }
214    
215     if (type_added)
216     add_string(result, &result_len, "}");
217    
218     if (result_len == MAXLEN)
219     goto fail;
220    
221     result[result_len] = '\0';
222    
223     return result;
224    
225     fail:
226     free(result);
227     return NULL;
228     }
229    
230    
231     /*
232     * symbol_demangle_cplusplus():
233     *
234     * Try to demangle name. If name was not a valid/known C++ symbol, then NULL
235     * is returned. Otherwise, a newly allocated string is returned, containing
236     * the demangled name.
237     */
238     char *symbol_demangle_cplusplus(char *name)
239     {
240     /* Only support _Z-style mangled names, for now: */
241     if (strlen(name) < 2 || name[0] != '_' || name[1] != 'Z')
242     return NULL;
243    
244     name += 2;
245    
246     switch (name[0]) {
247     case 'N':
248     return symbol_demangle_cplusplus_nested(name + 1);
249     break;
250     }
251    
252     return NULL;
253     }
254    
255    
256    
257     #ifdef TEST
258    
259     void test(char *mangled, char *result)
260     {
261     char *p = symbol_demangle_cplusplus(mangled);
262     if (p == NULL) {
263     if (result == NULL) {
264     return;
265     } else {
266     printf("FAILURE for %s!\n", mangled);
267     exit(1);
268     }
269     }
270     if (strcmp(p, result) == 0)
271     return;
272     printf("FAILURE for %s! (result = %s)\n", mangled, p);
273     exit(1);
274     }
275    
276     int main(int argc, char *argv[])
277     {
278     test("monkey", NULL);
279     test("_monkey", NULL);
280     test("_zmonkey", NULL);
281     test("_Zmonkey", NULL);
282     test("_ZQ5abcde", NULL);
283     test("_ZN3abc5defghE", "abc::defgh");
284     test("_ZN05defghEv", "::defgh{}");
285     test("_ZN5defghEv", "defgh{}");
286     test("_ZN3abc5defghEv", "abc::defgh{}");
287     test("_ZN3abc5defghEc", "abc::defgh{char}");
288     test("_ZN1a2bcEjij", "a::bc{unsigned int,int,unsigned int}");
289     printf("OK\n");
290     return 0;
291     }
292    
293     #endif
294    

  ViewVC Help
Powered by ViewVC 1.1.26