Fix an (almost) infinite loop in the tekhex parser.
[deliverable/binutils-gdb.git] / binutils / cxxfilt.c
CommitLineData
bb279dc0 1/* Demangler for GNU C++ - main program
4b95cf5c 2 Copyright (C) 1989-2014 Free Software Foundation, Inc.
bb279dc0
ZW
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
6
32866df7 7 This file is part of GNU Binutils.
bb279dc0 8
32866df7
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at
12 your option) any later version.
bb279dc0 13
32866df7
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
bb279dc0 18
cbf1f5df
NC
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
bb279dc0 23
3db64b00 24#include "sysdep.h"
bb279dc0 25#include "bfd.h"
bb279dc0
ZW
26#include "libiberty.h"
27#include "demangle.h"
28#include "getopt.h"
29#include "safe-ctype.h"
3db64b00 30#include "bucomm.h"
bb279dc0 31
ec948987 32static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
cbf1f5df 33static int strip_underscore = TARGET_PREPENDS_UNDERSCORE;
bb279dc0 34
cbf1f5df
NC
35static const struct option long_options[] =
36{
37 {"strip-underscore", no_argument, NULL, '_'},
38 {"format", required_argument, NULL, 's'},
39 {"help", no_argument, NULL, 'h'},
40 {"no-params", no_argument, NULL, 'p'},
41 {"no-strip-underscores", no_argument, NULL, 'n'},
cbf1f5df 42 {"no-verbose", no_argument, NULL, 'i'},
ec948987 43 {"types", no_argument, NULL, 't'},
cbf1f5df
NC
44 {"version", no_argument, NULL, 'v'},
45 {NULL, no_argument, NULL, 0}
46};
bb279dc0
ZW
47
48static void
2da42df6 49demangle_it (char *mangled_name)
bb279dc0
ZW
50{
51 char *result;
cbf1f5df
NC
52 unsigned int skip_first = 0;
53
ec948987
NC
54 /* _ and $ are sometimes found at the start of function names
55 in assembler sources in order to distinguish them from other
56 names (eg register names). So skip them here. */
cbf1f5df
NC
57 if (mangled_name[0] == '.' || mangled_name[0] == '$')
58 ++skip_first;
59 if (strip_underscore && mangled_name[skip_first] == '_')
60 ++skip_first;
61
62 result = cplus_demangle (mangled_name + skip_first, flags);
bb279dc0 63
bb279dc0 64 if (result == NULL)
1afcb04c 65 printf ("%s", mangled_name);
bb279dc0
ZW
66 else
67 {
cbf1f5df
NC
68 if (mangled_name[0] == '.')
69 putchar ('.');
1afcb04c 70 printf ("%s", result);
bb279dc0
ZW
71 free (result);
72 }
73}
74
2da42df6
AJ
75static void
76print_demangler_list (FILE *stream)
bb279dc0 77{
2da42df6 78 const struct demangler_engine *demangler;
bb279dc0
ZW
79
80 fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
2da42df6 81
bb279dc0
ZW
82 for (demangler = libiberty_demanglers + 1;
83 demangler->demangling_style != unknown_demangling;
84 ++demangler)
85 fprintf (stream, ",%s", demangler->demangling_style_name);
86
87 fprintf (stream, "}");
88}
89
90static void
2da42df6 91usage (FILE *stream, int status)
bb279dc0
ZW
92{
93 fprintf (stream, "\
cbf1f5df 94Usage: %s [options] [mangled names]\n", program_name);
bb279dc0 95 fprintf (stream, "\
cbf1f5df
NC
96Options are:\n\
97 [-_|--strip-underscore] Ignore first leading underscore%s\n",
98 TARGET_PREPENDS_UNDERSCORE ? " (default)" : "");
99 fprintf (stream, "\
100 [-n|--no-strip-underscore] Do not ignore a leading underscore%s\n",
101 TARGET_PREPENDS_UNDERSCORE ? "" : " (default)");
bb279dc0 102 fprintf (stream, "\
cbf1f5df 103 [-p|--no-params] Do not display function arguments\n\
cbf1f5df 104 [-i|--no-verbose] Do not show implementation details (if any)\n\
ec948987 105 [-t|--types] Also attempt to demangle type encodings\n\
cbf1f5df 106 [-s|--format ");
bb279dc0
ZW
107 print_demangler_list (stream);
108 fprintf (stream, "]\n");
109
110 fprintf (stream, "\
cbf1f5df
NC
111 [@<file>] Read extra options from <file>\n\
112 [-h|--help] Display this information\n\
113 [-v|--version] Show the version information\n\
114Demangled names are displayed to stdout.\n\
115If a name cannot be demangled it is just echoed to stdout.\n\
116If no names are provided on the command line, stdin is read.\n");
92f01d61
JM
117 if (REPORT_BUGS_TO[0] && status == 0)
118 fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
bb279dc0
ZW
119 exit (status);
120}
121
2da42df6 122/* Return the string of non-alnum characters that may occur
bb279dc0
ZW
123 as a valid symbol component, in the standard assembler symbol
124 syntax. */
125
126static const char *
2da42df6 127standard_symbol_characters (void)
bb279dc0
ZW
128{
129 return "_$.";
130}
131
bb279dc0
ZW
132/* Return the string of non-alnum characters that may occur
133 as a valid symbol name component in an HP object file.
134
135 Note that, since HP's compiler generates object code straight from
136 C++ source, without going through an assembler, its mangled
137 identifiers can use all sorts of characters that no assembler would
138 tolerate, so the alphabet this function creates is a little odd.
139 Here are some sample mangled identifiers offered by HP:
140
141 typeid*__XT24AddressIndExpClassMember_
142 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
143 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
144
145 This still seems really weird to me, since nowhere else in this
146 file is there anything to recognize curly brackets, parens, etc.
147 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
148 this is right, but I still strongly suspect that there's a
149 misunderstanding here.
150
151 If we decide it's better for c++filt to use HP's assembler syntax
152 to scrape identifiers out of its input, here's the definition of
153 the symbol name syntax from the HP assembler manual:
154
155 Symbols are composed of uppercase and lowercase letters, decimal
156 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
157 underscore (_). A symbol can begin with a letter, digit underscore or
158 dollar sign. If a symbol begins with a digit, it must contain a
159 non-digit character.
160
161 So have fun. */
162static const char *
2da42df6 163hp_symbol_characters (void)
bb279dc0
ZW
164{
165 return "_$.<>#,*&[]:(){}";
166}
167
2da42df6 168extern int main (int, char **);
bb279dc0
ZW
169
170int
2da42df6 171main (int argc, char **argv)
bb279dc0 172{
bb279dc0
ZW
173 int c;
174 const char *valid_symbols;
175 enum demangling_styles style = auto_demangling;
176
177 program_name = argv[0];
178 xmalloc_set_program_name (program_name);
179
869b9d07
MM
180 expandargv (&argc, &argv);
181
cbf1f5df 182 while ((c = getopt_long (argc, argv, "_hinps:tv", long_options, (int *) 0)) != EOF)
bb279dc0
ZW
183 {
184 switch (c)
185 {
186 case '?':
187 usage (stderr, 1);
188 break;
189 case 'h':
190 usage (stdout, 0);
191 case 'n':
192 strip_underscore = 0;
193 break;
4e48c9dd
ILT
194 case 'p':
195 flags &= ~ DMGL_PARAMS;
196 break;
cbf1f5df 197 case 't':
ec948987 198 flags |= DMGL_TYPES;
cbf1f5df
NC
199 break;
200 case 'i':
201 flags &= ~ DMGL_VERBOSE;
202 break;
bb279dc0
ZW
203 case 'v':
204 print_version ("c++filt");
cbf1f5df 205 return 0;
bb279dc0
ZW
206 case '_':
207 strip_underscore = 1;
208 break;
209 case 's':
cbf1f5df
NC
210 style = cplus_demangle_name_to_style (optarg);
211 if (style == unknown_demangling)
212 {
213 fprintf (stderr, "%s: unknown demangling style `%s'\n",
214 program_name, optarg);
215 return 1;
216 }
217 cplus_demangle_set_style (style);
bb279dc0
ZW
218 break;
219 }
220 }
221
222 if (optind < argc)
223 {
224 for ( ; optind < argc; optind++)
ec948987
NC
225 {
226 demangle_it (argv[optind]);
227 putchar ('\n');
228 }
cbf1f5df
NC
229
230 return 0;
bb279dc0 231 }
cbf1f5df
NC
232
233 switch (current_demangling_style)
bb279dc0 234 {
cbf1f5df
NC
235 case gnu_demangling:
236 case lucid_demangling:
237 case arm_demangling:
238 case java_demangling:
239 case edg_demangling:
240 case gnat_demangling:
241 case gnu_v3_demangling:
242 case auto_demangling:
243 valid_symbols = standard_symbol_characters ();
244 break;
245 case hp_demangling:
246 valid_symbols = hp_symbol_characters ();
247 break;
248 default:
249 /* Folks should explicitly indicate the appropriate alphabet for
250 each demangling. Providing a default would allow the
251 question to go unconsidered. */
252 fatal ("Internal error: no symbol alphabet for current style");
253 }
254
255 for (;;)
256 {
257 static char mbuffer[32767];
258 unsigned i = 0;
259
260 c = getchar ();
261 /* Try to read a mangled name. */
262 while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
bb279dc0 263 {
cbf1f5df
NC
264 if (i >= sizeof (mbuffer) - 1)
265 break;
266 mbuffer[i++] = c;
267 c = getchar ();
bb279dc0
ZW
268 }
269
cbf1f5df 270 if (i > 0)
bb279dc0 271 {
cbf1f5df
NC
272 mbuffer[i] = 0;
273 demangle_it (mbuffer);
bb279dc0 274 }
ec948987 275
cbf1f5df
NC
276 if (c == EOF)
277 break;
ec948987
NC
278
279 /* Echo the whitespace characters so that the output looks
280 like the input, only with the mangled names demangled. */
281 putchar (c);
02aec879
AH
282 if (c == '\n')
283 fflush (stdout);
bb279dc0
ZW
284 }
285
ec948987 286 fflush (stdout);
cbf1f5df 287 return 0;
bb279dc0 288}
This page took 0.64206 seconds and 4 git commands to generate.