bug-binutils
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]