Demangling long function argument lists
Jerry Gamache
jerryg@softimage.com
Wed Aug 2 17:03:00 GMT 2000
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);
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ }
===================================================================
More information about the Binutils
mailing list