From: Jerry Gamache <jerryg@softimage.com>
To: "'binutils@sourceware.cygnus.com'" <binutils@sourceware.cygnus.com>
Subject: Demangling long function argument lists
Date: Wed, 02 Aug 2000 17:03:00 -0000 [thread overview]
Message-ID: <C1DC220FAC8DD211A71500805FEABE2503C772BF@MON-EXC-01> (raw)
[-- 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);
            }
===================================================================
reply other threads:[~2000-08-02 17:03 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=C1DC220FAC8DD211A71500805FEABE2503C772BF@MON-EXC-01 \
--to=jerryg@softimage.com \
--cc=binutils@sourceware.cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).