[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug binutils/1437] c++filt no longer works with stdin
From: |
nickc at redhat dot com |
Subject: |
[Bug binutils/1437] c++filt no longer works with stdin |
Date: |
11 Oct 2005 12:34:01 -0000 |
------- Additional Comments From nickc at redhat dot com 2005-10-11 12:34
-------
Subject: Re: New: c++filt no longer works with stdin
Hi HJ,
> address@hidden testsuite]$ cat foo.s
> .type _Z1fv, @function
> address@hidden testsuite]$
> /export/build/gnu/binutils-import/build-i686-linux/binutils/cxxfilt < foo.s
> .type
> f()
> function
> address@hidden testsuite]$ /usr/bin/c++filt < foo.s
> .type f(), @function
>
However, decoding these definitions on the command line using the old
c++filt does not work properly either:
% cxxfilt .type _Z1fv, @function
.type
_Z1fv,
@function
> Those special handling for `.', `$' and `_' used to be for stdin only.
> I think it makes some sense since they are added to assembly code.
But users can easily look in assembly code, find a mangled name and then
try to pass it to c++filt on the command line, expecting to see the
demangled name. This is why I feel that c++filt should have the same
behaviour regardless of where it obtains the mangled names.
I agree that when it is reading from stdin c++filt should preserve the
whitespace of its input, so that definitely does need fixing.
> The reason for
>
> /* For command line args, also try to demangle type encodings. */
> result = cplus_demangle (mangled_name, flags | DMGL_TYPES);
>
> is that the assembly code may have
>
> .section .eh_frame,"a",@progbits
> .ident "GCC: (GNU) 4.1.0 20051007 (experimental)"
Ok - I also agree that demangling types by default is a bad idea. But I
still believe that it ought to be possible to demangle them, even when
the input comes from stdin.
So please could you consider the attached patch. It does three things:
* Makes type demangling no be enabled by default (for either stdin or
the command line).
* Copies the whitespace read from stdin to stdout, preserving the
formating of the input whilst demangling its contents.
* Updates the documentation to describe why there is a difference
between the demangling of names read on the command line and names read
from the standard input.
Cheers
Nick
binutils/ChangeLog
2005-10-11 Nick Clifton <address@hidden>
PR binutils/1437
* cxxfilt.c (flags): Remove DMGL_TYPES;
(long_options): Rename --no-types to --types.
(usage): Likewise.
(demangle_it): Add a comment describing why _ and $ prefixes are
skipped. Use printf rather than puts to emit the demangled output
in order to avoid emitting a new line character.
(main): Have the -t flag enable type demangling.
Emit a newline after every demangled command line argument.
Copy whitespace from stdin to stdout.
* doc/binutils.texi (c++filt): Document the change to the -t
switch.
Document why demangling names on the command line is slightly
different to demangling names read from the standard input.
Index: binutils/cxxfilt.c
===================================================================
RCS file: /cvs/src/src/binutils/cxxfilt.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 cxxfilt.c
*** binutils/cxxfilt.c 4 Oct 2005 11:03:38 -0000 1.9
--- binutils/cxxfilt.c 11 Oct 2005 12:25:45 -0000
***************
*** 30,36 ****
#include "getopt.h"
#include "safe-ctype.h"
! static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE | DMGL_TYPES;
static int strip_underscore = TARGET_PREPENDS_UNDERSCORE;
static const struct option long_options[] =
--- 30,36 ----
#include "getopt.h"
#include "safe-ctype.h"
! static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
static int strip_underscore = TARGET_PREPENDS_UNDERSCORE;
static const struct option long_options[] =
*************** static const struct option long_options[
*** 40,47 ****
{"help", no_argument, NULL, 'h'},
{"no-params", no_argument, NULL, 'p'},
{"no-strip-underscores", no_argument, NULL, 'n'},
- {"no-types", no_argument, NULL, 't'},
{"no-verbose", no_argument, NULL, 'i'},
{"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0}
};
--- 40,47 ----
{"help", no_argument, NULL, 'h'},
{"no-params", no_argument, NULL, 'p'},
{"no-strip-underscores", no_argument, NULL, 'n'},
{"no-verbose", no_argument, NULL, 'i'},
+ {"types", no_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0}
};
*************** demangle_it (char *mangled_name)
*** 52,57 ****
--- 52,60 ----
char *result;
unsigned int skip_first = 0;
+ /* _ and $ are sometimes found at the start of function names
+ in assembler sources in order to distinguish them from other
+ names (eg register names). So skip them here. */
if (mangled_name[0] == '.' || mangled_name[0] == '$')
++skip_first;
if (strip_underscore && mangled_name[skip_first] == '_')
*************** demangle_it (char *mangled_name)
*** 60,71 ****
result = cplus_demangle (mangled_name + skip_first, flags);
if (result == NULL)
! puts (mangled_name);
else
{
if (mangled_name[0] == '.')
putchar ('.');
! puts (result);
free (result);
}
}
--- 63,74 ----
result = cplus_demangle (mangled_name + skip_first, flags);
if (result == NULL)
! printf (mangled_name);
else
{
if (mangled_name[0] == '.')
putchar ('.');
! printf (result);
free (result);
}
}
*************** Options are:\n\
*** 99,106 ****
TARGET_PREPENDS_UNDERSCORE ? "" : " (default)");
fprintf (stream, "\
[-p|--no-params] Do not display function arguments\n\
- [-t|--no-types] Do not try to demangle type encodings\n\
[-i|--no-verbose] Do not show implementation details (if any)\n\
[-s|--format ");
print_demangler_list (stream);
fprintf (stream, "]\n");
--- 102,109 ----
TARGET_PREPENDS_UNDERSCORE ? "" : " (default)");
fprintf (stream, "\
[-p|--no-params] Do not display function arguments\n\
[-i|--no-verbose] Do not show implementation details (if any)\n\
+ [-t|--types] Also attempt to demangle type encodings\n\
[-s|--format ");
print_demangler_list (stream);
fprintf (stream, "]\n");
*************** main (int argc, char **argv)
*** 191,197 ****
flags &= ~ DMGL_PARAMS;
break;
case 't':
! flags &= ~ DMGL_TYPES;
break;
case 'i':
flags &= ~ DMGL_VERBOSE;
--- 194,200 ----
flags &= ~ DMGL_PARAMS;
break;
case 't':
! flags |= DMGL_TYPES;
break;
case 'i':
flags &= ~ DMGL_VERBOSE;
*************** main (int argc, char **argv)
*** 218,224 ****
if (optind < argc)
{
for ( ; optind < argc; optind++)
! demangle_it (argv[optind]);
return 0;
}
--- 221,230 ----
if (optind < argc)
{
for ( ; optind < argc; optind++)
! {
! demangle_it (argv[optind]);
! putchar ('\n');
! }
return 0;
}
*************** main (int argc, char **argv)
*** 264,274 ****
{
mbuffer[i] = 0;
demangle_it (mbuffer);
- fflush (stdout);
}
if (c == EOF)
break;
}
return 0;
}
--- 270,285 ----
{
mbuffer[i] = 0;
demangle_it (mbuffer);
}
+
if (c == EOF)
break;
+
+ /* Echo the whitespace characters so that the output looks
+ like the input, only with the mangled names demangled. */
+ putchar (c);
}
+ fflush (stdout);
return 0;
}
Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.82
diff -c -3 -p -r1.82 binutils.texi
*** binutils/doc/binutils.texi 11 Oct 2005 04:49:16 -0000 1.82
--- binutils/doc/binutils.texi 11 Oct 2005 12:25:46 -0000
*************** the Info entries for @file{binutils}.
*** 2399,2405 ****
c++filt address@hidden|@option{--strip-underscores}]
address@hidden|@option{--no-strip-underscores}]
address@hidden|@option{--no-params}]
! address@hidden|@option{--no-types}]
address@hidden|@option{--no-verbose}]
address@hidden @var{format}|@address@hidden
address@hidden address@hidden address@hidden@dots{}]
--- 2399,2405 ----
c++filt address@hidden|@option{--strip-underscores}]
address@hidden|@option{--no-strip-underscores}]
address@hidden|@option{--no-params}]
! address@hidden|@option{--types}]
address@hidden|@option{--no-verbose}]
address@hidden @var{format}|@address@hidden
address@hidden address@hidden address@hidden@dots{}]
*************** c++filt address@hidden|@option{--strip-und
*** 2409,2439 ****
@c man begin DESCRIPTION cxxfilt
@kindex cxxfilt
! The C++ and Java languages provides function overloading, which means
! that you can write many functions with the same name (providing each
! takes parameters of different types). All C++ and Java function names
! are encoded into a low-level assembly label (this process is known as
! @dfn{mangling}). The @command{c++filt}
! @footnote{MS-DOS does not allow @kbd{+} characters in file names, so on
MS-DOS this program is named @command{CXXFILT}.}
program does the inverse mapping: it decodes (@dfn{demangles}) low-level
! names into user-level names so that the linker can keep these overloaded
! functions from clashing.
Every alphanumeric word (consisting of letters, digits, underscores,
dollars, or periods) seen in the input is a potential mangled name.
If the name decodes into a C++ name, the C++ name replaces the
! low-level name in the output.
! You can use @command{c++filt} to decipher individual symbols:
@example
c++filt @var{symbol}
@end example
If no @var{symbol} arguments are given, @command{c++filt} reads symbol
! names from the standard input and writes the demangled names to the
! standard output. All results are printed on the standard output.
@c man end
--- 2409,2475 ----
@c man begin DESCRIPTION cxxfilt
@kindex cxxfilt
! The C++ and Java languages provide function overloading, which means
! that you can write many functions with the same name, providing that
! each function takes parameters of different types. In order to be
! able to distinguish these similarly named functions C++ and Java
! encode them into a low-level assembler name which uniquely identifies
! each different version. This process is known as @dfn{mangling}. The
! @command{c++filt}
! @footnote{MS-DOS does not allow @kbd{+} characters in file names, so on
MS-DOS this program is named @command{CXXFILT}.}
program does the inverse mapping: it decodes (@dfn{demangles}) low-level
! names into user-level names so that they can be read.
Every alphanumeric word (consisting of letters, digits, underscores,
dollars, or periods) seen in the input is a potential mangled name.
If the name decodes into a C++ name, the C++ name replaces the
! low-level name in the output, otherwise the original word is output.
! In this way you can pass an entire assembler source file, containing
! mangled names, through @command{c++filt} and see the same source file
! containing demangled names.
! You can also use @command{c++filt} to decipher individual symbols by
! passing them on the command line:
@example
c++filt @var{symbol}
@end example
If no @var{symbol} arguments are given, @command{c++filt} reads symbol
! names from the standard input instead. All the results are printed on
! the standard output. The difference between reading names from the
! command line versus reading names from the standard input is that
! command line arguments are expected to be just mangled names and no
! checking is performed to seperate them from surrounding text. Thus
! for example:
!
! @smallexample
! c++filt -n _Z1fv
! @end smallexample
!
! will work and demangle the name to ``f()'' whereas:
!
! @smallexample
! c++filt -n _Z1fv,
! @end smallexample
!
! will not work. (Note the extra comma at the end of the mangled
! name which makes it invalid). This command however will work:
!
! @smallexample
! echo _Z1fv, | c++filt -n
! @end smallexample
!
! and will display ``f(),'' ie the demangled name followed by a
! trailing comma. This behaviour is because when the names are read
! from the standard input it is expected that they might be part of an
! assembler source file where there might be extra, extraneous
! characters trailing after a mangled name. eg:
!
! @smallexample
! .type _Z1fv, @@function
! @end smallexample
@c man end
*************** When demangling the name of a function,
*** 2462,2470 ****
the function's parameters.
@item -t
! @itemx --no-types
! Do not attempt to demangle types. This is enabled by default, but it
! may not be desired if you are interested in mangled function names.
@item -i
@itemx --no-verbose
--- 2498,2509 ----
the function's parameters.
@item -t
! @itemx --types
! Attempt to demangle types as well as function names. This is disabled
! by default since mangled types are normally only used internally in
! the compiler, and they can be confused with non-mangled names. eg
! a function called ``a'' treated as a mangled type name would be
! demangled to ``signed char''.
@item -i
@itemx --no-verbose
--
http://sourceware.org/bugzilla/show_bug.cgi?id=1437
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
- [Bug binutils/1437] New: c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/07
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/10
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/10
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/10
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/10
- [Bug binutils/1437] c++filt no longer works with stdin,
nickc at redhat dot com <=
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/11
- [Bug binutils/1437] c++filt no longer works with stdin, nickc at redhat dot com, 2005/10/11
- [Bug binutils/1437] c++filt no longer works with stdin, hjl at lucon dot org, 2005/10/13