Make ada_decode not use a static buffer

This makes it safer to use in general, and also allows using it on a
background thread in the future.

Inspired by tromey's patch at:
1226cbdfa4
(however, implemented in a different way)

gdb/ChangeLog:

2019-09-23  Christian Biesinger  <cbiesinger@google.com>

	* ada-exp.y (write_object_remaining): Update.
	* ada-lang.c (ada_decode): Return a std::string instead of a char*
	and eliminate the static buffer.
	(ada_decode_symbol): Update.
	(ada_la_decode): Update.
	(ada_sniff_from_mangled_name): Update.
	(is_valid_name_for_wild_match): Update.
	(ada_lookup_name_info::matches): Update and simplify.
	(name_matches_regex): Update.
	(ada_add_global_exceptions): Update.
	* ada-lang.h (ada_decode): Update signature.
	* ada-varobj.c (ada_varobj_describe_simple_array_child): Update.
	* dwarf-index-write.c (debug_names::insert): Update.
This commit is contained in:
Christian Biesinger 2019-08-28 15:40:31 -05:00
parent 4a41f3face
commit f945dedfd3
6 changed files with 52 additions and 46 deletions

View file

@ -1,3 +1,19 @@
2019-09-23 Christian Biesinger <cbiesinger@google.com>
* ada-exp.y (write_object_remaining): Update.
* ada-lang.c (ada_decode): Return a std::string instead of a char*
and eliminate the static buffer.
(ada_decode_symbol): Update.
(ada_la_decode): Update.
(ada_sniff_from_mangled_name): Update.
(is_valid_name_for_wild_match): Update.
(ada_lookup_name_info::matches): Update and simplify.
(name_matches_regex): Update.
(ada_add_global_exceptions): Update.
* ada-lang.h (ada_decode): Update signature.
* ada-varobj.c (ada_varobj_describe_simple_array_child): Update.
* dwarf-index-write.c (debug_names::insert): Update.
2019-09-21 Simon Marchi <simon.marchi@polymtl.ca> 2019-09-21 Simon Marchi <simon.marchi@polymtl.ca>
* solib-svr4.c (svr4_iterate_over_objfiles_in_search_order): Fix * solib-svr4.c (svr4_iterate_over_objfiles_in_search_order): Fix

View file

@ -816,7 +816,7 @@ write_object_renaming (struct parser_state *par_state,
renamed_entity_len); renamed_entity_len);
ada_lookup_encoded_symbol (name, orig_left_context, VAR_DOMAIN, &sym_info); ada_lookup_encoded_symbol (name, orig_left_context, VAR_DOMAIN, &sym_info);
if (sym_info.symbol == NULL) if (sym_info.symbol == NULL)
error (_("Could not find renamed variable: %s"), ada_decode (name)); error (_("Could not find renamed variable: %s"), ada_decode (name).c_str ());
else if (SYMBOL_CLASS (sym_info.symbol) == LOC_TYPEDEF) else if (SYMBOL_CLASS (sym_info.symbol) == LOC_TYPEDEF)
/* We have a renaming of an old-style renaming symbol. Don't /* We have a renaming of an old-style renaming symbol. Don't
trust the block information. */ trust the block information. */

View file

@ -1105,22 +1105,16 @@ ada_remove_po_subprogram_suffix (const char *encoded, int *len)
/* If ENCODED follows the GNAT entity encoding conventions, then return /* If ENCODED follows the GNAT entity encoding conventions, then return
the decoded form of ENCODED. Otherwise, return "<%s>" where "%s" is the decoded form of ENCODED. Otherwise, return "<%s>" where "%s" is
replaced by ENCODED. replaced by ENCODED. */
The resulting string is valid until the next call of ada_decode. std::string
If the string is unchanged by decoding, the original string pointer
is returned. */
const char *
ada_decode (const char *encoded) ada_decode (const char *encoded)
{ {
int i, j; int i, j;
int len0; int len0;
const char *p; const char *p;
char *decoded;
int at_start_name; int at_start_name;
static char *decoding_buffer = NULL; std::string decoded;
static size_t decoding_buffer_size = 0;
/* With function descriptors on PPC64, the value of a symbol named /* With function descriptors on PPC64, the value of a symbol named
".FN", if it exists, is the entry point of the function "FN". */ ".FN", if it exists, is the entry point of the function "FN". */
@ -1179,8 +1173,7 @@ ada_decode (const char *encoded)
/* Make decoded big enough for possible expansion by operator name. */ /* Make decoded big enough for possible expansion by operator name. */
GROW_VECT (decoding_buffer, decoding_buffer_size, 2 * len0 + 1); decoded.resize (2 * len0 + 1, 'X');
decoded = decoding_buffer;
/* Remove trailing __{digit}+ or trailing ${digit}+. */ /* Remove trailing __{digit}+ or trailing ${digit}+. */
@ -1217,7 +1210,7 @@ ada_decode (const char *encoded)
op_len - 1) == 0) op_len - 1) == 0)
&& !isalnum (encoded[i + op_len])) && !isalnum (encoded[i + op_len]))
{ {
strcpy (decoded + j, ada_opname_table[k].decoded); strcpy (&decoded.front() + j, ada_opname_table[k].decoded);
at_start_name = 0; at_start_name = 0;
i += op_len; i += op_len;
j += strlen (ada_opname_table[k].decoded); j += strlen (ada_opname_table[k].decoded);
@ -1338,27 +1331,22 @@ ada_decode (const char *encoded)
j += 1; j += 1;
} }
} }
decoded[j] = '\000'; decoded.resize (j);
/* Decoded names should never contain any uppercase character. /* Decoded names should never contain any uppercase character.
Double-check this, and abort the decoding if we find one. */ Double-check this, and abort the decoding if we find one. */
for (i = 0; decoded[i] != '\0'; i += 1) for (i = 0; i < decoded.length(); ++i)
if (isupper (decoded[i]) || decoded[i] == ' ') if (isupper (decoded[i]) || decoded[i] == ' ')
goto Suppress; goto Suppress;
if (strcmp (decoded, encoded) == 0) return decoded;
return encoded;
else
return decoded;
Suppress: Suppress:
GROW_VECT (decoding_buffer, decoding_buffer_size, strlen (encoded) + 3);
decoded = decoding_buffer;
if (encoded[0] == '<') if (encoded[0] == '<')
strcpy (decoded, encoded); decoded = encoded;
else else
xsnprintf (decoded, decoding_buffer_size, "<%s>", encoded); decoded = '<' + std::string(encoded) + '>';
return decoded; return decoded;
} }
@ -1389,13 +1377,13 @@ ada_decode_symbol (const struct general_symbol_info *arg)
if (!gsymbol->ada_mangled) if (!gsymbol->ada_mangled)
{ {
const char *decoded = ada_decode (gsymbol->name); std::string decoded = ada_decode (gsymbol->name);
struct obstack *obstack = gsymbol->language_specific.obstack; struct obstack *obstack = gsymbol->language_specific.obstack;
gsymbol->ada_mangled = 1; gsymbol->ada_mangled = 1;
if (obstack != NULL) if (obstack != NULL)
*resultp = obstack_strdup (obstack, decoded); *resultp = obstack_strdup (obstack, decoded.c_str ());
else else
{ {
/* Sometimes, we can't find a corresponding objfile, in /* Sometimes, we can't find a corresponding objfile, in
@ -1404,10 +1392,10 @@ ada_decode_symbol (const struct general_symbol_info *arg)
significant memory leak (FIXME). */ significant memory leak (FIXME). */
char **slot = (char **) htab_find_slot (decoded_names_store, char **slot = (char **) htab_find_slot (decoded_names_store,
decoded, INSERT); decoded.c_str (), INSERT);
if (*slot == NULL) if (*slot == NULL)
*slot = xstrdup (decoded); *slot = xstrdup (decoded.c_str ());
*resultp = *slot; *resultp = *slot;
} }
} }
@ -1418,7 +1406,7 @@ ada_decode_symbol (const struct general_symbol_info *arg)
static char * static char *
ada_la_decode (const char *encoded, int options) ada_la_decode (const char *encoded, int options)
{ {
return xstrdup (ada_decode (encoded)); return xstrdup (ada_decode (encoded).c_str ());
} }
/* Implement la_sniff_from_mangled_name for Ada. */ /* Implement la_sniff_from_mangled_name for Ada. */
@ -1426,11 +1414,11 @@ ada_la_decode (const char *encoded, int options)
static int static int
ada_sniff_from_mangled_name (const char *mangled, char **out) ada_sniff_from_mangled_name (const char *mangled, char **out)
{ {
const char *demangled = ada_decode (mangled); std::string demangled = ada_decode (mangled);
*out = NULL; *out = NULL;
if (demangled != mangled && demangled != NULL && demangled[0] != '<') if (demangled != mangled && demangled[0] != '<')
{ {
/* Set the gsymbol language to Ada, but still return 0. /* Set the gsymbol language to Ada, but still return 0.
Two reasons for that: Two reasons for that:
@ -5993,7 +5981,7 @@ is_name_suffix (const char *str)
static int static int
is_valid_name_for_wild_match (const char *name0) is_valid_name_for_wild_match (const char *name0)
{ {
const char *decoded_name = ada_decode (name0); std::string decoded_name = ada_decode (name0);
int i; int i;
/* If the decoded name starts with an angle bracket, it means that /* If the decoded name starts with an angle bracket, it means that
@ -6233,19 +6221,16 @@ ada_lookup_name_info::matches
if (strncmp (sym_name, text, text_len) == 0) if (strncmp (sym_name, text, text_len) == 0)
match = true; match = true;
std::string decoded_name = ada_decode (sym_name);
if (match && !m_encoded_p) if (match && !m_encoded_p)
{ {
/* One needed check before declaring a positive match is to verify /* One needed check before declaring a positive match is to verify
that iff we are doing a verbatim match, the decoded version that iff we are doing a verbatim match, the decoded version
of the symbol name starts with '<'. Otherwise, this symbol name of the symbol name starts with '<'. Otherwise, this symbol name
is not a suitable completion. */ is not a suitable completion. */
const char *sym_name_copy = sym_name;
bool has_angle_bracket;
sym_name = ada_decode (sym_name); bool has_angle_bracket = (decoded_name[0] == '<');
has_angle_bracket = (sym_name[0] == '<');
match = (has_angle_bracket == m_verbatim_p); match = (has_angle_bracket == m_verbatim_p);
sym_name = sym_name_copy;
} }
if (match && !m_verbatim_p) if (match && !m_verbatim_p)
@ -6269,7 +6254,7 @@ ada_lookup_name_info::matches
/* Since we are doing wild matching, this means that TEXT /* Since we are doing wild matching, this means that TEXT
may represent an unqualified symbol name. We therefore must may represent an unqualified symbol name. We therefore must
also compare TEXT against the unqualified name of the symbol. */ also compare TEXT against the unqualified name of the symbol. */
sym_name = ada_unqualified_name (ada_decode (sym_name)); sym_name = ada_unqualified_name (decoded_name.c_str ());
if (strncmp (sym_name, text, text_len) == 0) if (strncmp (sym_name, text, text_len) == 0)
match = true; match = true;
@ -13494,7 +13479,7 @@ static bool
name_matches_regex (const char *name, compiled_regex *preg) name_matches_regex (const char *name, compiled_regex *preg)
{ {
return (preg == NULL return (preg == NULL
|| preg->exec (ada_decode (name), 0, NULL, 0) == 0); || preg->exec (ada_decode (name).c_str (), 0, NULL, 0) == 0);
} }
/* Add all exceptions defined globally whose name name match /* Add all exceptions defined globally whose name name match
@ -13527,8 +13512,8 @@ ada_add_global_exceptions (compiled_regex *preg,
lookup_name_info::match_any (), lookup_name_info::match_any (),
[&] (const char *search_name) [&] (const char *search_name)
{ {
const char *decoded = ada_decode (search_name); std::string decoded = ada_decode (search_name);
return name_matches_regex (decoded, preg); return name_matches_regex (decoded.c_str (), preg);
}, },
NULL, NULL,
VARIABLES_DOMAIN); VARIABLES_DOMAIN);

View file

@ -227,7 +227,7 @@ extern struct type *ada_get_decoded_type (struct type *type);
extern const char *ada_decode_symbol (const struct general_symbol_info *); extern const char *ada_decode_symbol (const struct general_symbol_info *);
extern const char *ada_decode (const char*); extern std::string ada_decode (const char*);
extern enum language ada_update_initial_language (enum language); extern enum language ada_update_initial_language (enum language);

View file

@ -624,6 +624,7 @@ ada_varobj_describe_simple_array_child (struct value *parent_value,
of the array index type when such type qualification is of the array index type when such type qualification is
needed. */ needed. */
const char *index_type_name = NULL; const char *index_type_name = NULL;
std::string decoded;
/* If the index type is a range type, find the base type. */ /* If the index type is a range type, find the base type. */
while (TYPE_CODE (index_type) == TYPE_CODE_RANGE) while (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
@ -634,7 +635,10 @@ ada_varobj_describe_simple_array_child (struct value *parent_value,
{ {
index_type_name = ada_type_name (index_type); index_type_name = ada_type_name (index_type);
if (index_type_name) if (index_type_name)
index_type_name = ada_decode (index_type_name); {
decoded = ada_decode (index_type_name);
index_type_name = decoded.c_str ();
}
} }
if (index_type_name != NULL) if (index_type_name != NULL)

View file

@ -714,13 +714,14 @@ public:
name (of the form "<MumBle>") must be entered without the name (of the form "<MumBle>") must be entered without the
angle brackets. Note that the current index is unusual, angle brackets. Note that the current index is unusual,
see PR symtab/24820 for details. */ see PR symtab/24820 for details. */
const char *decoded = ada_decode (name); std::string decoded = ada_decode (name);
if (decoded[0] == '<') if (decoded[0] == '<')
name = (char *) obstack_copy0 (&m_string_obstack, name = (char *) obstack_copy0 (&m_string_obstack,
decoded + 1, decoded.c_str () + 1,
strlen (decoded + 1) - 1); decoded.length () - 2);
else else
name = obstack_strdup (&m_string_obstack, ada_encode (decoded)); name = obstack_strdup (&m_string_obstack,
ada_encode (decoded.c_str ()));
} }
const auto insertpair const auto insertpair