public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Demangling long function argument lists
@ 2000-08-02 17:03 Jerry Gamache
  0 siblings, 0 replies; only message in thread
From: Jerry Gamache @ 2000-08-02 17:03 UTC (permalink / raw)
  To: 'binutils@sourceware.cygnus.com'

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 10307 bytes --]

Title: Demangling long function argument lists





I found a bug in libiberty/cplus-dem.c where the repeat count for long function prototypes was not extracted correctly when demangling (still there in binutils snapshot 000801).

When mangling the following name:


class bar { ... };
int foo(int, int, int, int, int, int, int, int, int, int, bar, bar, bar, bar);


I get


foo__FiiiiiiiiiiG3barN310_


which fails when demangling using c++filt (or, most important in my case, when resctricting the export of C++ symbols in a version-script)

The problem lies in the get_count function, which gets called twice in demangle_args. The function will always decode everything up to the underscore, giving a repeat count of 310 of the "unknown" arg. 

When called the first time to get the repeat count, the get_count function must make sure something is left after the underscore for the typevec index. I looked in gcc/cp/method.c and g++ will emit underscores if the repeat count is greater than 10, which means N12_12_ would be the way to signify 12 repeats of the 12th arg.

Probably fixable by adding a boolean parameter to get_count indicating the need for some numbers after the underscore, which means the last test in get_count would look like 

          if (*p == '_' && !(leave_number && !isdigit(*(p+1))))


In fact, here is a patch against snapshot 000801 that worked in my case. Another option would be to create a specialized get_repeat_count function instead.

        Jerry Gamache
        SDE Core & Linux port
        Avid/SoftImage Montreal


=================================================================== 
*** cplus-dem.c Wed Aug  2 19:41:36 2000
--- cplus-dem.c.orig    Wed Aug  2 18:57:46 2000
***************
*** 413,419 ****
  string_append_template_idx PARAMS ((string *, int));
  
  static int
! get_count PARAMS ((const char **, int, int *));
  
  static int
  consume_count PARAMS ((const char **));
--- 413,419 ----
  string_append_template_idx PARAMS ((string *, int));
  
  static int
! get_count PARAMS ((const char **, int *));
  
  static int
  consume_count PARAMS ((const char **));
***************
*** 1499,1505 ****
  
    string_append (tname, "template <");
    /* get size of template parameter list */
!   if (get_count (mangled, 0, &r))
      {
        for (i = 0; i < r; i++)
        {
--- 1499,1505 ----
  
    string_append (tname, "template <");
    /* get size of template parameter list */
!   if (get_count (mangled, &r))
      {
        for (i = 0; i < r; i++)
        {
***************
*** 1921,1927 ****
    if (!is_java_array)
      string_append (tname, "<");
    /* get size of template parameter list */
!   if (!get_count (mangled, 0, &r))
      {
        return (0);
      }
--- 1921,1927 ----
    if (!is_java_array)
      string_append (tname, "<");
    /* get size of template parameter list */
!   if (!get_count (mangled, &r))
      {
        return (0);
      }
***************
*** 3214,3220 ****
  SYNOPSIS
  
        static int
!       get_count (const char **type, int leave_numbers, int *count)
  
  DESCRIPTION
  
--- 3214,3220 ----
  SYNOPSIS
  
        static int
!       get_count (const char **type, int *count)
  
  DESCRIPTION
  
***************
*** 3226,3235 ****
  
        If *type points at a string of digits followed by an
        underscore, set *count to their value as an integer, advance
!       *type to point *after the underscore, but if the leave_number
!       variable is true, then make sure there is a number left to
!       crunch after the underscore.
!       
  
        If *type points at a string of digits not followed by an
        underscore, consume only the first digit.  Set *count to its
--- 3226,3232 ----
  
        If *type points at a string of digits followed by an
        underscore, set *count to their value as an integer, advance
!       *type to point *after the underscore, and return 1.
  
        If *type points at a string of digits not followed by an
        underscore, consume only the first digit.  Set *count to its
***************
*** 3252,3268 ****
          pointer to an integer (`Pi'), and then the next five arguments
          are the same (`N5'), and the first repeat is the function's
          second argument (`1').
- 
-       Also of note, the g++ compiler will emit underscore everytime
-       a number is greater than 10, giving N10_1 for ten repeats of
-       argument 1, N10_10_ for ten repeats of argument 10, and the
-       non-trivial N510_ for five repeats of argument 10.
  */
  
  static int
! get_count (type, leave_number, count)
       const char **type;
-      int leave_number;
       int *count;
  {
    const char *p;
--- 3249,3259 ----
          pointer to an integer (`Pi'), and then the next five arguments
          are the same (`N5'), and the first repeat is the function's
          second argument (`1').
  */
  
  static int
! get_count (type, count)
       const char **type;
       int *count;
  {
    const char *p;
***************
*** 3285,3291 ****
              p++;
            }
          while (isdigit ((unsigned char)*p));
!         if (*p == '_' && !(leave_number && !isdigit(*(p+1))))
            {
              *type = p + 1;
              *count = n;
--- 3276,3282 ----
              p++;
            }
          while (isdigit ((unsigned char)*p));
!         if (*p == '_')
            {
              *type = p + 1;
              *count = n;
***************
*** 3366,3372 ****
        /* A back reference to a previously seen type */
        case 'T':
          (*mangled)++;
!         if (!get_count (mangled, 0, &n) || n >= work -> ntypes)
            {
              success = 0;
            }
--- 3357,3363 ----
        /* A back reference to a previously seen type */
        case 'T':
          (*mangled)++;
!         if (!get_count (mangled, &n) || n >= work -> ntypes)
            {
              success = 0;
            }
***************
*** 3540,3546 ****
      /* A back reference to a previously seen squangled type */
      case 'B':
        (*mangled)++;
!       if (!get_count (mangled, 0, &n) || n >= work -> numb)
        success = 0;
        else
        string_append (result, work->btypevec[n]);
--- 3531,3537 ----
      /* A back reference to a previously seen squangled type */
      case 'B':
        (*mangled)++;
!       if (!get_count (mangled, &n) || n >= work -> numb)
        success = 0;
        else
        string_append (result, work->btypevec[n]);
***************
*** 4247,4253 ****
  
          if (temptype == 'N')
            {
!             if (!get_count (mangled, 1, &r))
                {
                  return (0);
                }
--- 4238,4244 ----
  
          if (temptype == 'N')
            {
!             if (!get_count (mangled, &r))
                {
                  return (0);
                }
***************
*** 4271,4277 ****
              }
            else
            {
!             if (!get_count (mangled, 0, &t))
                {
                  return (0);
                }
--- 4262,4268 ----
              }
            else
            {
!             if (!get_count (mangled, &t))
                {
                  return (0);
                }
=================================================================== 




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2000-08-02 17:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-08-02 17:03 Demangling long function argument lists Jerry Gamache

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).