mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 07:53:51 +08:00
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.
This commit is contained in:
@ -146,6 +146,7 @@ struct work_stuff
|
||||
int *proctypevec; /* Indices of currently processed remembered typevecs. */
|
||||
int proctypevec_size;
|
||||
int nproctypes;
|
||||
unsigned int recursion_level;
|
||||
};
|
||||
|
||||
#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
|
||||
@ -1292,12 +1293,14 @@ squangle_mop_up (struct work_stuff *work)
|
||||
free ((char *) work -> btypevec);
|
||||
work->btypevec = NULL;
|
||||
work->bsize = 0;
|
||||
work->numb = 0;
|
||||
}
|
||||
if (work -> ktypevec != NULL)
|
||||
{
|
||||
free ((char *) work -> ktypevec);
|
||||
work->ktypevec = NULL;
|
||||
work->ksize = 0;
|
||||
work->numk = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1331,8 +1334,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
|
||||
|
||||
for (i = 0; i < from->numk; i++)
|
||||
{
|
||||
int len = strlen (from->ktypevec[i]) + 1;
|
||||
int len;
|
||||
|
||||
if (from->ktypevec[i] == NULL)
|
||||
{
|
||||
to->ktypevec[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = strlen (from->ktypevec[i]) + 1;
|
||||
to->ktypevec[i] = XNEWVEC (char, len);
|
||||
memcpy (to->ktypevec[i], from->ktypevec[i], len);
|
||||
}
|
||||
@ -1342,8 +1352,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
|
||||
|
||||
for (i = 0; i < from->numb; i++)
|
||||
{
|
||||
int len = strlen (from->btypevec[i]) + 1;
|
||||
int len;
|
||||
|
||||
if (from->btypevec[i] == NULL)
|
||||
{
|
||||
to->btypevec[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = strlen (from->btypevec[i]) + 1;
|
||||
to->btypevec[i] = XNEWVEC (char , len);
|
||||
memcpy (to->btypevec[i], from->btypevec[i], len);
|
||||
}
|
||||
@ -1401,6 +1418,7 @@ delete_non_B_K_work_stuff (struct work_stuff *work)
|
||||
|
||||
free ((char*) work->tmpl_argvec);
|
||||
work->tmpl_argvec = NULL;
|
||||
work->ntmpl_args = 0;
|
||||
}
|
||||
if (work->previous_argument)
|
||||
{
|
||||
@ -4471,12 +4489,14 @@ remember_Btype (struct work_stuff *work, const char *start,
|
||||
char *tem;
|
||||
|
||||
tem = XNEWVEC (char, len + 1);
|
||||
memcpy (tem, start, len);
|
||||
if (len > 0)
|
||||
memcpy (tem, start, len);
|
||||
tem[len] = '\0';
|
||||
work -> btypevec[index] = tem;
|
||||
}
|
||||
|
||||
/* Lose all the info related to B and K type codes. */
|
||||
|
||||
static void
|
||||
forget_B_and_K_types (struct work_stuff *work)
|
||||
{
|
||||
@ -4502,6 +4522,7 @@ forget_B_and_K_types (struct work_stuff *work)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Forget the remembered types, but not the type vector itself. */
|
||||
|
||||
static void
|
||||
@ -4696,6 +4717,16 @@ demangle_nested_args (struct work_stuff *work, const char **mangled,
|
||||
int result;
|
||||
int saved_nrepeats;
|
||||
|
||||
if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0)
|
||||
{
|
||||
if (work->recursion_level > DEMANGLE_RECURSION_LIMIT)
|
||||
/* FIXME: There ought to be a way to report
|
||||
that the recursion limit has been reached. */
|
||||
return 0;
|
||||
|
||||
work->recursion_level ++;
|
||||
}
|
||||
|
||||
/* The G++ name-mangling algorithm does not remember types on nested
|
||||
argument lists, unless -fsquangling is used, and in that case the
|
||||
type vector updated by remember_type is not used. So, we turn
|
||||
@ -4722,6 +4753,9 @@ demangle_nested_args (struct work_stuff *work, const char **mangled,
|
||||
--work->forgetting_types;
|
||||
work->nrepeats = saved_nrepeats;
|
||||
|
||||
if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0)
|
||||
--work->recursion_level;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user