aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2018-12-07 11:32:55 +0000
committerNick Clifton <nickc@redhat.com>2018-12-07 11:32:55 +0000
commitaf03af8f55f2536b6e20928e6b1fa0324a5f3d6e (patch)
treefa6b5ef700e811c0d6bfaec08d2ebb8291dae17f /binutils
parent67bb16f345cb72740ab523018709c183ff3f8c8d (diff)
downloadgdb-af03af8f55f2536b6e20928e6b1fa0324a5f3d6e.zip
gdb-af03af8f55f2536b6e20928e6b1fa0324a5f3d6e.tar.gz
gdb-af03af8f55f2536b6e20928e6b1fa0324a5f3d6e.tar.bz2
Synchronize libiberty with gcc and add --no-recruse-limit option to tools that support name demangling.
This patch addresses the multitude of bug reports about resource exhaustion in libiberty's name demangling code. It adds a limit to the amount of recursion that is allowed, before an error is triggered. It also adds a new demangling option to disable this limit. (The limit is enabled by default). PR 87681 PR 87675 PR 87636 PR 87335 libiberty * cp-demangle.h (struct d_info): Add recursion_limit field. * cp-demangle.c (d_function_type): If the recursion limit is enabled and reached, return with a failure result. (d_demangle_callback): If the recursion limit is enabled, check for a mangled string that is so long that there is not enough stack space for the local arrays. * cplus-dem.c (struct work): Add recursion_level field. (demangle_nested_args): If the recursion limit is enabled and reached, return with a failure result. include * demangle.h (DMGL_RECURSE_LIMIT): Define. (DEMANGLE_RECURSION_LIMIT): Prototype. binutuils * addr2line.c (demangle_flags): New static variable. (long_options): Add --recurse-limit and --no-recurse-limit. (translate_address): Pass demangle_flags to bfd_demangle. (main): Handle --recurse-limit and --no-recurse-limit options. * cxxfilt.c (flags): Add DMGL_RECURSE_LIMIT. (long_options): Add --recurse-limit and --no-recurse-limit. (main): Handle new options. * dlltool.c (gen_def_file): Include DMGL_RECURSE_LIMIT in flags passed to cplus_demangle. * nm.c (demangle_flags): New static variable. (long_options): Add --recurse-limit and --no-recurse-limit. (main): Handle new options. * objdump.c (demangle_flags): New static variable. (usage): Add --recurse-limit and --no-recurse-limit. (long_options): Likewise. (objdump_print_symname): Pass demangle_flags to bfd_demangle. (disassemble_section): Likewise. (dump_dymbols): Likewise. (main): Handle new options. * prdbg.c (demangle_flags): New static variable. (tg_variable): Pass demangle_flags to demangler. (tg_start_function): Likewise. * stabs.c (demangle_flags): New static variable. (stab_demangle_template): Pass demangle_flags to demangler. (stab_demangle_v3_argtypes): Likewise. (stab_demangle_v3_arg): Likewise. * doc/binutuls.texi: Document new command line options. * NEWS: Mention the new feature. * testsuite/config/default.exp (CXXFILT): Define if not already defined. (CXXFILTFLAGS): Likewise. * testsuite/binutils-all/cxxfilt.exp: New file. Runs a few simple tests of the cxxfilt program.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog34
-rw-r--r--binutils/NEWS11
-rw-r--r--binutils/addr2line.c19
-rw-r--r--binutils/cxxfilt.c14
-rw-r--r--binutils/doc/binutils.texi89
-rw-r--r--binutils/nm.c27
-rw-r--r--binutils/objdump.c22
-rw-r--r--binutils/prdbg.c6
-rw-r--r--binutils/stabs.c10
-rw-r--r--binutils/testsuite/binutils-all/cxxfilt.exp44
-rw-r--r--binutils/testsuite/config/default.exp6
11 files changed, 265 insertions, 17 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index b61ea26..d865bf6 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,37 @@
+2018-12-07 Nick Clifton <nickc@redhat.com>
+
+ * addr2line.c (demangle_flags): New static variable.
+ (long_options): Add --recurse-limit and --no-recurse-limit.
+ (translate_address): Pass demangle_flags to bfd_demangle.
+ (main): Handle --recurse-limit and --no-recurse-limit options.
+ * cxxfilt.c: (long_options): Add --recurse-limit and
+ --no-recurse-limit.
+ (main): Handle new options.
+ * nm.c (demangle_flags): New static variable.
+ (long_options): Add --recurse-limit and --no-recurse-limit.
+ (main): Handle new options.
+ * objdump.c (demangle_flags): New static variable.
+ (usage): Add --recurse-limit and --no-recurse-limit.
+ (long_options): Likewise.
+ (objdump_print_symname): Pass demangle_flags to bfd_demangle.
+ (disassemble_section): Likewise.
+ (dump_dymbols): Likewise.
+ (main): Handle new options.
+ * prdbg.c (demangle_flags): New static variable.
+ (tg_variable): Pass demangle_flags to demangler.
+ (tg_start_function): Likewise.
+ * stabs.c (demangle_flags): New static variable.
+ (stab_demangle_template): Pass demangle_flags to demangler.
+ (stab_demangle_v3_argtypes): Likewise.
+ (stab_demangle_v3_arg): Likewise.
+ * doc/binutuls.texi: Document new command line options.
+ * NEWS: Mention the new feature.
+ * testsuite/config/default.exp (CXXFILT): Define if not already
+ defined.
+ (CXXFILTFLAGS): Likewise.
+ * testsuite/binutils-all/cxxfilt.exp: New file. Runs a few
+ simple tests of the cxxfilt program.
+
2018-12-03 Nick Clifton <nickc@redhat.com>
PR 23941
diff --git a/binutils/NEWS b/binutils/NEWS
index a3ee86e..ce92534 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,16 @@
-*- text -*-
+* The addr2line, c++filt, nm and objdump tools now have a limit on the
+ maximum amount of recursion that is allowed whilst demangling strings.
+ The value for this limit is defined by the DEMANGLE_RECRUSE_LIMIT
+ constant declared in the include/demangle.h header file. At the time
+ of writing this constant has the value of 1024.
+
+ The --no-recurse-limit option can be used to remove the limit, restoring
+ the behaviour of earlier versions of these tools. This may be needed in
+ order to dmangle truly complicated names, but it also leaves the tools
+ vulnerable to stack exhaustion from maliciously constructed mangled names.
+
* Objdump's --disassemble option can now take a parameter, specifying the
starting symbol for disassembly. Disassembly will continue from this
symbol up to the next symbol.
diff --git a/binutils/addr2line.c b/binutils/addr2line.c
index 008e620..817b125 100644
--- a/binutils/addr2line.c
+++ b/binutils/addr2line.c
@@ -45,6 +45,9 @@ static bfd_boolean do_demangle; /* -C, demangle names. */
static bfd_boolean pretty_print; /* -p, print on one line. */
static bfd_boolean base_names; /* -s, strip directory names. */
+/* Flags passed to the name demangler. */
+static int demangle_flags = DMGL_PARAMS | DMGL_ANSI;
+
static int naddr; /* Number of addresses to process. */
static char **addr; /* Hex addresses to process. */
@@ -59,6 +62,10 @@ static struct option long_options[] =
{"functions", no_argument, NULL, 'f'},
{"inlines", no_argument, NULL, 'i'},
{"pretty-print", no_argument, NULL, 'p'},
+ {"recurse-limit", no_argument, NULL, 'R'},
+ {"recursion-limit", no_argument, NULL, 'R'},
+ {"no-recurse-limit", no_argument, NULL, 'r'},
+ {"no-recursion-limit", no_argument, NULL, 'r'},
{"section", required_argument, NULL, 'j'},
{"target", required_argument, NULL, 'b'},
{"help", no_argument, NULL, 'H'},
@@ -91,6 +98,8 @@ usage (FILE *stream, int status)
-s --basenames Strip directory names\n\
-f --functions Show function names\n\
-C --demangle[=style] Demangle function names\n\
+ -R --recurse-limit Enable a limit on recursion whilst demangling. [Default]\n\
+ -r --no-recurse-limit Disable a limit on recursion whilst demangling\n\
-h --help Display this information\n\
-v --version Display the program's version\n\
\n"));
@@ -289,7 +298,7 @@ translate_addresses (bfd *abfd, asection *section)
name = "??";
else if (do_demangle)
{
- alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ alloc = bfd_demangle (abfd, name, demangle_flags);
if (alloc != NULL)
name = alloc;
}
@@ -442,7 +451,7 @@ main (int argc, char **argv)
file_name = NULL;
section_name = NULL;
target = NULL;
- while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:pVv", long_options, (int *) 0))
+ while ((c = getopt_long (argc, argv, "ab:Ce:rRsfHhij:pVv", long_options, (int *) 0))
!= EOF)
{
switch (c)
@@ -469,6 +478,12 @@ main (int argc, char **argv)
cplus_demangle_set_style (style);
}
break;
+ case 'r':
+ demangle_flags |= DMGL_NO_RECURSE_LIMIT;
+ break;
+ case 'R':
+ demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
+ break;
case 'e':
file_name = optarg;
break;
diff --git a/binutils/cxxfilt.c b/binutils/cxxfilt.c
index e727244..21d69d5 100644
--- a/binutils/cxxfilt.c
+++ b/binutils/cxxfilt.c
@@ -42,6 +42,10 @@ static const struct option long_options[] =
{"no-verbose", no_argument, NULL, 'i'},
{"types", no_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
+ {"recurse-limit", no_argument, NULL, 'R'},
+ {"recursion-limit", no_argument, NULL, 'R'},
+ {"no-recurse-limit", no_argument, NULL, 'r'},
+ {"no-recursion-limit", no_argument, NULL, 'r'},
{NULL, no_argument, NULL, 0}
};
@@ -102,6 +106,8 @@ Options are:\n\
fprintf (stream, "\
[-p|--no-params] Do not display function arguments\n\
[-i|--no-verbose] Do not show implementation details (if any)\n\
+ [-R|--recurse-limit] Enable a limit on recursion whilst demangling. [Default]\n\
+ ]-r|--no-recurse-limit] Disable a limit on recursion whilst demangling\n\
[-t|--types] Also attempt to demangle type encodings\n\
[-s|--format ");
print_demangler_list (stream);
@@ -180,7 +186,7 @@ main (int argc, char **argv)
expandargv (&argc, &argv);
- while ((c = getopt_long (argc, argv, "_hinps:tv", long_options, (int *) 0)) != EOF)
+ while ((c = getopt_long (argc, argv, "_hinprRs:tv", long_options, (int *) 0)) != EOF)
{
switch (c)
{
@@ -195,6 +201,12 @@ main (int argc, char **argv)
case 'p':
flags &= ~ DMGL_PARAMS;
break;
+ case 'r':
+ flags |= DMGL_NO_RECURSE_LIMIT;
+ break;
+ case 'R':
+ flags &= ~ DMGL_NO_RECURSE_LIMIT;
+ break;
case 't':
flags |= DMGL_TYPES;
break;
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 9954adf..7efda86 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -769,7 +769,9 @@ nm [@option{-A}|@option{-o}|@option{--print-file-name}] [@option{-a}|@option{--d
[@option{-s}|@option{--print-armap}] [@option{-t} @var{radix}|@option{--radix=}@var{radix}]
[@option{-u}|@option{--undefined-only}] [@option{-V}|@option{--version}]
[@option{-X 32_64}] [@option{--defined-only}] [@option{--no-demangle}]
- [@option{--plugin} @var{name}] [@option{--size-sort}] [@option{--special-syms}]
+ [@option{--plugin} @var{name}]
+ [@option{--no-recurse-limit}|@option{--recurse-limit}]]
+ [@option{--size-sort}] [@option{--special-syms}]
[@option{--synthetic}] [@option{--with-symbol-versions}] [@option{--target=}@var{bfdname}]
[@var{objfile}@dots{}]
@c man end
@@ -939,6 +941,22 @@ for more information on demangling.
@item --no-demangle
Do not demangle low-level symbol names. This is the default.
+@item --recurse-limit
+@itemx --no-recurse-limit
+@itemx --recursion-limit
+@itemx --no-recursion-limit
+Enables or disables a limit on the amount of recursion performed
+whilst demangling strings. Since the name mangling formats allow for
+an inifinite level of recursion it is possible to create strings whose
+decoding will exhaust the amount of stack space available on the host
+machine, triggering a memory fault. The limit tries to prevent this
+from happening by restricting recursion to 1024 levels of nesting.
+
+The default is for this limit to be enabled, but disabling it may be
+necessary in order to demangle truly complicated names. Note however
+that if the recursion limit is disabled then stack exhaustion is
+possible and any bug reports about such an event will be rejected.
+
@item -D
@itemx --dynamic
@cindex dynamic symbols
@@ -2098,6 +2116,7 @@ objdump [@option{-a}|@option{--archive-headers}]
[@option{--adjust-vma=}@var{offset}]
[@option{--dwarf-depth=@var{n}}]
[@option{--dwarf-start=@var{n}}]
+ [@option{--no-recurse-limit}|@option{--recurse-limit}]
[@option{--special-syms}]
[@option{--prefix=}@var{prefix}]
[@option{--prefix-strip=}@var{level}]
@@ -2174,6 +2193,22 @@ mangling styles. The optional demangling style argument can be used to
choose an appropriate demangling style for your compiler. @xref{c++filt},
for more information on demangling.
+@item --recurse-limit
+@itemx --no-recurse-limit
+@itemx --recursion-limit
+@itemx --no-recursion-limit
+Enables or disables a limit on the amount of recursion performed
+whilst demangling strings. Since the name mangling formats allow for
+an inifinite level of recursion it is possible to create strings whose
+decoding will exhaust the amount of stack space available on the host
+machine, triggering a memory fault. The limit tries to prevent this
+from happening by restricting recursion to 1024 levels of nesting.
+
+The default is for this limit to be enabled, but disabling it may be
+necessary in order to demangle truly complicated names. Note however
+that if the recursion limit is disabled then stack exhaustion is
+possible and any bug reports about such an event will be rejected.
+
@item -g
@itemx --debugging
Display debugging information. This attempts to parse STABS
@@ -3403,6 +3438,8 @@ c++filt [@option{-_}|@option{--strip-underscore}]
[@option{-p}|@option{--no-params}]
[@option{-t}|@option{--types}]
[@option{-i}|@option{--no-verbose}]
+ [@option{-r}|@option{--no-recurse-limit}]
+ [@option{-R}|@option{--recurse-limit}]
[@option{-s} @var{format}|@option{--format=}@var{format}]
[@option{--help}] [@option{--version}] [@var{symbol}@dots{}]
@c man end
@@ -3507,6 +3544,28 @@ demangled to ``signed char''.
Do not include implementation details (if any) in the demangled
output.
+@item -r
+@itemx -R
+@itemx --recurse-limit
+@itemx --no-recurse-limit
+@itemx --recursion-limit
+@itemx --no-recursion-limit
+Enables or disables a limit on the amount of recursion performed
+whilst demangling strings. Since the name mangling formats allow for
+an inifinite level of recursion it is possible to create strings whose
+decoding will exhaust the amount of stack space available on the host
+machine, triggering a memory fault. The limit tries to prevent this
+from happening by restricting recursion to 1024 levels of nesting.
+
+The default is for this limit to be enabled, but disabling it may be
+necessary in order to demangle truly complicated names. Note however
+that if the recursion limit is disabled then stack exhaustion is
+possible and any bug reports about such an event will be rejected.
+
+The @option{-r} option is a synonym for the
+@option{--no-recurse-limit} option. The @option{-R} option is a
+synonym for the @option{--recurse-limit} option.
+
@item -s @var{format}
@itemx --format=@var{format}
@command{c++filt} can decode various methods of mangling, used by
@@ -3580,6 +3639,8 @@ c++filt @var{option} @var{symbol}
addr2line [@option{-a}|@option{--addresses}]
[@option{-b} @var{bfdname}|@option{--target=}@var{bfdname}]
[@option{-C}|@option{--demangle}[=@var{style}]]
+ [@option{-r}|@option{--no-recurse-limit}]
+ [@option{-R}|@option{--recurse-limit}]
[@option{-e} @var{filename}|@option{--exe=}@var{filename}]
[@option{-f}|@option{--functions}] [@option{-s}|@option{--basename}]
[@option{-i}|@option{--inlines}]
@@ -3705,6 +3766,32 @@ Read offsets relative to the specified section instead of absolute addresses.
Make the output more human friendly: each location are printed on one line.
If option @option{-i} is specified, lines for all enclosing scopes are
prefixed with @samp{(inlined by)}.
+
+@item -r
+@itemx -R
+@itemx --recurse-limit
+@itemx --no-recurse-limit
+@itemx --recursion-limit
+@itemx --no-recursion-limit
+Enables or disables a limit on the amount of recursion performed
+whilst demangling strings. Since the name mangling formats allow for
+an inifinite level of recursion it is possible to create strings whose
+decoding will exhaust the amount of stack space available on the host
+machine, triggering a memory fault. The limit tries to prevent this
+from happening by restricting recursion to 1024 levels of nesting.
+
+The default is for this limit to be enabled, but disabling it may be
+necessary in order to demangle truly complicated names. Note however
+that if the recursion limit is disabled then stack exhaustion is
+possible and any bug reports about such an event will be rejected.
+
+The @option{-r} option is a synonym for the
+@option{--no-recurse-limit} option. The @option{-R} option is a
+synonym for the @option{--recurse-limit} option.
+
+Note this option is only effective if the @option{-C} or
+@option{--demangle} option has been enabled.
+
@end table
@c man end
diff --git a/binutils/nm.c b/binutils/nm.c
index bc4fccb..8807832 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -162,6 +162,8 @@ static int line_numbers = 0; /* Print line numbers for symbols. */
static int allow_special_symbols = 0; /* Allow special symbols. */
static int with_symbol_versions = 0; /* Include symbol version information in the output. */
+static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
+
/* When to print the names of files. Not mutually exclusive in SYSV format. */
static int filename_per_file = 0; /* Once per file, on its own line. */
static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
@@ -194,9 +196,14 @@ static const char *plugin_target = NULL;
static bfd *lineno_cache_bfd;
static bfd *lineno_cache_rel_bfd;
-#define OPTION_TARGET 200
-#define OPTION_PLUGIN (OPTION_TARGET + 1)
-#define OPTION_SIZE_SORT (OPTION_PLUGIN + 1)
+enum long_option_values
+{
+ OPTION_TARGET = 200,
+ OPTION_PLUGIN,
+ OPTION_SIZE_SORT,
+ OPTION_RECURSE_LIMIT,
+ OPTION_NO_RECURSE_LIMIT
+};
static struct option long_options[] =
{
@@ -209,6 +216,8 @@ static struct option long_options[] =
{"line-numbers", no_argument, 0, 'l'},
{"no-cplus", no_argument, &do_demangle, 0}, /* Linux compatibility. */
{"no-demangle", no_argument, &do_demangle, 0},
+ {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
+ {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
{"no-sort", no_argument, 0, 'p'},
{"numeric-sort", no_argument, 0, 'n'},
{"plugin", required_argument, 0, OPTION_PLUGIN},
@@ -217,6 +226,8 @@ static struct option long_options[] =
{"print-file-name", no_argument, 0, 'o'},
{"print-size", no_argument, 0, 'S'},
{"radix", required_argument, 0, 't'},
+ {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
+ {"recursion-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
{"reverse-sort", no_argument, &reverse_sort, 1},
{"size-sort", no_argument, 0, OPTION_SIZE_SORT},
{"special-syms", no_argument, &allow_special_symbols, 1},
@@ -245,6 +256,8 @@ usage (FILE *stream, int status)
`gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
or `gnat'\n\
--no-demangle Do not demangle low-level symbol names\n\
+ --recurse-limit Enable a demangling recursion limit. This is the default.\n\
+ --no-recurse-limit Disable a demangling recursion limit.\n\
-D, --dynamic Display dynamic symbols instead of normal symbols\n\
--defined-only Display only defined symbols\n\
-e (ignored)\n\
@@ -407,7 +420,7 @@ print_symname (const char *form, const char *name, bfd *abfd)
{
if (do_demangle && *name)
{
- char *res = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ char *res = bfd_demangle (abfd, name, demangle_flags);
if (res != NULL)
{
@@ -1687,6 +1700,12 @@ main (int argc, char **argv)
cplus_demangle_set_style (style);
}
break;
+ case OPTION_RECURSE_LIMIT:
+ demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
+ break;
+ case OPTION_NO_RECURSE_LIMIT:
+ demangle_flags |= DMGL_NO_RECURSE_LIMIT;
+ break;
case 'D':
dynamic = 1;
break;
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 21f1284..86c2fcb 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -120,6 +120,8 @@ static size_t prefix_length;
static bfd_boolean unwind_inlines; /* --inlines. */
static const char * disasm_sym; /* Disassembly start symbol. */
+static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
+
/* A structure to record the sections mentioned in -j switches. */
struct only
{
@@ -252,6 +254,8 @@ usage (FILE *stream, int status)
The STYLE, if specified, can be `auto', `gnu',\n\
`lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
or `gnat'\n\
+ --recurse-limit Enable a limit on recursion whilst demangling. [Default]\n\
+ --no-recurse-limit Disable a limit on recursion whilst demangling\n\
-w, --wide Format output for more than 80 columns\n\
-z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\
--start-address=ADDR Only process data whose address is >= ADDR\n\
@@ -302,6 +306,8 @@ enum option_values
OPTION_DWARF_DEPTH,
OPTION_DWARF_CHECK,
OPTION_DWARF_START,
+ OPTION_RECURSE_LIMIT,
+ OPTION_NO_RECURSE_LIMIT,
OPTION_INLINES
};
@@ -333,6 +339,10 @@ static struct option long_options[]=
{"line-numbers", no_argument, NULL, 'l'},
{"no-show-raw-insn", no_argument, &show_raw_insn, -1},
{"prefix-addresses", no_argument, &prefix_addresses, 1},
+ {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
+ {"recursion-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
+ {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
+ {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
{"reloc", no_argument, NULL, 'r'},
{"section", required_argument, NULL, 'j'},
{"section-headers", no_argument, NULL, 'h'},
@@ -884,7 +894,7 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
if (do_demangle && name[0] != '\0')
{
/* Demangle the name. */
- alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ alloc = bfd_demangle (abfd, name, demangle_flags);
if (alloc != NULL)
name = alloc;
}
@@ -2290,7 +2300,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
if (do_demangle && name[0] != '\0')
{
/* Demangle the name. */
- alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ alloc = bfd_demangle (abfd, name, demangle_flags);
if (alloc != NULL)
name = alloc;
}
@@ -3268,7 +3278,7 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
/* If we want to demangle the name, we demangle it
here, and temporarily clobber it while calling
bfd_print_symbol. FIXME: This is a gross hack. */
- alloc = bfd_demangle (cur_bfd, name, DMGL_ANSI | DMGL_PARAMS);
+ alloc = bfd_demangle (cur_bfd, name, demangle_flags);
if (alloc != NULL)
(*current)->name = alloc;
bfd_print_symbol (cur_bfd, stdout, *current,
@@ -3927,6 +3937,12 @@ main (int argc, char **argv)
cplus_demangle_set_style (style);
}
break;
+ case OPTION_RECURSE_LIMIT:
+ demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
+ break;
+ case OPTION_NO_RECURSE_LIMIT:
+ demangle_flags |= DMGL_NO_RECURSE_LIMIT;
+ break;
case 'w':
do_wide = wide_output = TRUE;
break;
diff --git a/binutils/prdbg.c b/binutils/prdbg.c
index 4b9fa06..5f14d32 100644
--- a/binutils/prdbg.c
+++ b/binutils/prdbg.c
@@ -286,6 +286,8 @@ static const struct debug_write_fns tg_fns =
pr_end_function, /* Same, does nothing. */
tg_lineno
};
+
+static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
/* Print out the generic debugging information recorded in dhandle. */
@@ -2600,7 +2602,7 @@ tg_variable (void *p, const char *name, enum debug_var_kind kind,
dname = NULL;
if (info->demangler)
- dname = info->demangler (info->abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ dname = info->demangler (info->abfd, name, demangle_flags);
from_class = NULL;
if (dname != NULL)
@@ -2661,7 +2663,7 @@ tg_start_function (void *p, const char *name, bfd_boolean global)
dname = NULL;
if (info->demangler)
- dname = info->demangler (info->abfd, name, DMGL_ANSI | DMGL_PARAMS);
+ dname = info->demangler (info->abfd, name, demangle_flags);
if (! substitute_type (info, dname ? dname : name))
return FALSE;
diff --git a/binutils/stabs.c b/binutils/stabs.c
index bf53607..fc459c4 100644
--- a/binutils/stabs.c
+++ b/binutils/stabs.c
@@ -215,6 +215,8 @@ static debug_type stab_demangle_v3_arg
(void *, struct stab_handle *, struct demangle_component *, debug_type,
bfd_boolean *);
+static int demangle_flags = DMGL_ANSI;
+
/* Save a string in memory. */
static char *
@@ -4517,7 +4519,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
free (s1);
- s3 = cplus_demangle (s2, DMGL_ANSI);
+ s3 = cplus_demangle (s2, demangle_flags);
free (s2);
@@ -5243,7 +5245,7 @@ stab_demangle_v3_argtypes (void *dhandle, struct stab_handle *info,
void *mem;
debug_type *pargs;
- dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | DMGL_ANSI, &mem);
+ dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | demangle_flags, &mem);
if (dc == NULL)
{
stab_bad_demangle (physname);
@@ -5418,7 +5420,7 @@ stab_demangle_v3_arg (void *dhandle, struct stab_handle *info,
/* We print this component to get a class name which we can
use. FIXME: This probably won't work if the template uses
template parameters which refer to an outer template. */
- p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
+ p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
if (p == NULL)
{
fprintf (stderr, _("Failed to print demangled template\n"));
@@ -5498,7 +5500,7 @@ stab_demangle_v3_arg (void *dhandle, struct stab_handle *info,
/* We print this component in order to find out the type name.
FIXME: Should we instead expose the
demangle_builtin_type_info structure? */
- p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
+ p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
if (p == NULL)
{
fprintf (stderr, _("Couldn't get demangled builtin type\n"));
diff --git a/binutils/testsuite/binutils-all/cxxfilt.exp b/binutils/testsuite/binutils-all/cxxfilt.exp
new file mode 100644
index 0000000..526815c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/cxxfilt.exp
@@ -0,0 +1,44 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+proc test_cxxfilt {options mangled_string demangled_string} {
+ global CXXFILT
+ global CXXFILTFLAGS
+
+ set testname "cxxfilt: demangling $mangled_string"
+ set got [binutils_run $CXXFILT "$options $CXXFILTFLAGS $mangled_string"]
+
+ if ![regexp $demangled_string $got] then {
+ fail "$testname"
+ verbose 0 "expected: $demangled_string"
+ return
+ }
+
+ pass $testname
+}
+
+# Mangled and demangled strings stolen from libiberty/testsuite/demangle-expected.
+test_cxxfilt {} \
+ "AddAlignment__9ivTSolverUiP12ivInteractorP7ivTGlue" \
+ "ivTSolver::AddAlignment(unsigned int, ivInteractor ., ivTGlue .)*"
+
+test_cxxfilt {--format=lucid} \
+ "__ct__12strstreambufFPFl_PvPFPv_v" \
+ "strstreambuf..(strstreambuf|_ct)(void .(.)(long), void (.)(void .))*"
+
+test_cxxfilt {--no-recurse-limit} \
+ "Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_" \
+ "foo(int, int., int.., int..., int...., int....., int......, int......., int........, int........., int.........., int..........., int............, int............., int.............., int...............)*"
diff --git a/binutils/testsuite/config/default.exp b/binutils/testsuite/config/default.exp
index b34e45c..9ecfcf3 100644
--- a/binutils/testsuite/config/default.exp
+++ b/binutils/testsuite/config/default.exp
@@ -93,6 +93,12 @@ if ![info exists WINDRES] then {
if ![info exists DLLTOOL] then {
set DLLTOOL [findfile $base_dir/dlltool]
}
+if ![info exists CXXFILT] then {
+ set CXXFILT [findfile $base_dir/cxxfilt]
+}
+if ![info exists CXXFILTFLAGS] then {
+ set CXXFILTFLAGS ""
+}
if ![file isdirectory tmpdir] {catch "exec mkdir tmpdir" status}