Commit 42bf58bb by Eduard-Mihai Burtescu Committed by Jeff Law

rust-demangle.c (unescape): Remove.

	* rust-demangle.c (unescape): Remove.
	(parse_lower_hex_nibble): New function.
	(parse_legacy_escape): New function.
	(is_prefixed_hash): Use parse_lower_hex_nibble.
	(looks_like_rust): Use parse_legacy_escape.
	(rust_demangle_sym): Use parse_legacy_escape.
	* testsuite/rust-demangle-expected: Add 'llv$u6d$' test.

From-SVN: r275353
parent 5f76ab15
2019-09-03 Eduard-Mihai Burtescu <eddyb@lyken.rs>
* rust-demangle.c (unescape): Remove.
(parse_lower_hex_nibble): New function.
(parse_legacy_escape): New function.
(is_prefixed_hash): Use parse_lower_hex_nibble.
(looks_like_rust): Use parse_legacy_escape.
(rust_demangle_sym): Use parse_legacy_escape.
* testsuite/rust-demangle-expected: Add 'llv$u6d$' test.
2019-08-27 Martin Liska <mliska@suse.cz> 2019-08-27 Martin Liska <mliska@suse.cz>
PR lto/91478 PR lto/91478
......
...@@ -50,7 +50,7 @@ extern void *memset(void *s, int c, size_t n); ...@@ -50,7 +50,7 @@ extern void *memset(void *s, int c, size_t n);
#include "rust-demangle.h" #include "rust-demangle.h"
/* Mangled Rust symbols look like this: /* Mangled (legacy) Rust symbols look like this:
_$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
The original symbol is: The original symbol is:
...@@ -74,16 +74,7 @@ extern void *memset(void *s, int c, size_t n); ...@@ -74,16 +74,7 @@ extern void *memset(void *s, int c, size_t n);
">" => $GT$ ">" => $GT$
"(" => $LP$ "(" => $LP$
")" => $RP$ ")" => $RP$
" " => $u20$ "\u{XY}" => $uXY$
"\"" => $u22$
"'" => $u27$
"+" => $u2b$
";" => $u3b$
"[" => $u5b$
"]" => $u5d$
"{" => $u7b$
"}" => $u7d$
"~" => $u7e$
A double ".." means "::" and a single "." means "-". A double ".." means "::" and a single "." means "-".
...@@ -95,7 +86,8 @@ static const size_t hash_len = 16; ...@@ -95,7 +86,8 @@ static const size_t hash_len = 16;
static int is_prefixed_hash (const char *start); static int is_prefixed_hash (const char *start);
static int looks_like_rust (const char *sym, size_t len); static int looks_like_rust (const char *sym, size_t len);
static int unescape (const char **in, char **out, const char *seq, char value); static int parse_lower_hex_nibble (char nibble);
static char parse_legacy_escape (const char **in);
/* INPUT: sym: symbol that has been through C++ (gnu v3) demangling /* INPUT: sym: symbol that has been through C++ (gnu v3) demangling
...@@ -149,7 +141,7 @@ is_prefixed_hash (const char *str) ...@@ -149,7 +141,7 @@ is_prefixed_hash (const char *str)
const char *end; const char *end;
char seen[16]; char seen[16];
size_t i; size_t i;
int count; int count, nibble;
if (strncmp (str, hash_prefix, hash_prefix_len)) if (strncmp (str, hash_prefix, hash_prefix_len))
return 0; return 0;
...@@ -157,12 +149,12 @@ is_prefixed_hash (const char *str) ...@@ -157,12 +149,12 @@ is_prefixed_hash (const char *str)
memset (seen, 0, sizeof(seen)); memset (seen, 0, sizeof(seen));
for (end = str + hash_len; str < end; str++) for (end = str + hash_len; str < end; str++)
if (*str >= '0' && *str <= '9') {
seen[*str - '0'] = 1; nibble = parse_lower_hex_nibble (*str);
else if (*str >= 'a' && *str <= 'f') if (nibble < 0)
seen[*str - 'a' + 10] = 1;
else
return 0; return 0;
seen[nibble] = 1;
}
/* Count how many distinct digits seen */ /* Count how many distinct digits seen */
count = 0; count = 0;
...@@ -179,55 +171,15 @@ looks_like_rust (const char *str, size_t len) ...@@ -179,55 +171,15 @@ looks_like_rust (const char *str, size_t len)
const char *end = str + len; const char *end = str + len;
while (str < end) while (str < end)
switch (*str)
{ {
case '$': if (*str == '$')
if (!strncmp (str, "$C$", 3)) {
str += 3; if (!parse_legacy_escape (&str))
else if (!strncmp (str, "$SP$", 4)
|| !strncmp (str, "$BP$", 4)
|| !strncmp (str, "$RF$", 4)
|| !strncmp (str, "$LT$", 4)
|| !strncmp (str, "$GT$", 4)
|| !strncmp (str, "$LP$", 4)
|| !strncmp (str, "$RP$", 4))
str += 4;
else if (!strncmp (str, "$u20$", 5)
|| !strncmp (str, "$u22$", 5)
|| !strncmp (str, "$u27$", 5)
|| !strncmp (str, "$u2b$", 5)
|| !strncmp (str, "$u3b$", 5)
|| !strncmp (str, "$u5b$", 5)
|| !strncmp (str, "$u5d$", 5)
|| !strncmp (str, "$u7b$", 5)
|| !strncmp (str, "$u7d$", 5)
|| !strncmp (str, "$u7e$", 5))
str += 5;
else
return 0;
break;
case '.':
/* Do not allow three or more consecutive dots */
if (!strncmp (str, "...", 3))
return 0; return 0;
/* Fall through */ }
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': else if (*str == '.' || *str == '_' || *str == ':' || ISALNUM (*str))
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case '_':
case ':':
str++; str++;
break; else
default:
return 0; return 0;
} }
...@@ -246,6 +198,7 @@ rust_demangle_sym (char *sym) ...@@ -246,6 +198,7 @@ rust_demangle_sym (char *sym)
const char *in; const char *in;
char *out; char *out;
const char *end; const char *end;
char unescaped;
if (!sym) if (!sym)
return; return;
...@@ -255,32 +208,18 @@ rust_demangle_sym (char *sym) ...@@ -255,32 +208,18 @@ rust_demangle_sym (char *sym)
end = sym + strlen (sym) - (hash_prefix_len + hash_len); end = sym + strlen (sym) - (hash_prefix_len + hash_len);
while (in < end) while (in < end)
switch (*in)
{ {
case '$': if (*in == '$')
if (!(unescape (&in, &out, "$C$", ',') {
|| unescape (&in, &out, "$SP$", '@') unescaped = parse_legacy_escape (&in);
|| unescape (&in, &out, "$BP$", '*') if (unescaped)
|| unescape (&in, &out, "$RF$", '&') *out++ = unescaped;
|| unescape (&in, &out, "$LT$", '<') else
|| unescape (&in, &out, "$GT$", '>')
|| unescape (&in, &out, "$LP$", '(')
|| unescape (&in, &out, "$RP$", ')')
|| unescape (&in, &out, "$u20$", ' ')
|| unescape (&in, &out, "$u22$", '\"')
|| unescape (&in, &out, "$u27$", '\'')
|| unescape (&in, &out, "$u2b$", '+')
|| unescape (&in, &out, "$u3b$", ';')
|| unescape (&in, &out, "$u5b$", '[')
|| unescape (&in, &out, "$u5d$", ']')
|| unescape (&in, &out, "$u7b$", '{')
|| unescape (&in, &out, "$u7d$", '}')
|| unescape (&in, &out, "$u7e$", '~'))) {
/* unexpected escape sequence, not looks_like_rust. */ /* unexpected escape sequence, not looks_like_rust. */
goto fail; goto fail;
} }
break; else if (*in == '_')
case '_': {
/* If this is the start of a path component and the next /* If this is the start of a path component and the next
character is an escape sequence, ignore the underscore. The character is an escape sequence, ignore the underscore. The
mangler inserts an underscore to make sure the path mangler inserts an underscore to make sure the path
...@@ -289,8 +228,9 @@ rust_demangle_sym (char *sym) ...@@ -289,8 +228,9 @@ rust_demangle_sym (char *sym)
in++; in++;
else else
*out++ = *in++; *out++ = *in++;
break; }
case '.': else if (*in == '.')
{
if (in[1] == '.') if (in[1] == '.')
{ {
/* ".." becomes "::" */ /* ".." becomes "::" */
...@@ -304,23 +244,10 @@ rust_demangle_sym (char *sym) ...@@ -304,23 +244,10 @@ rust_demangle_sym (char *sym)
*out++ = '-'; *out++ = '-';
in++; in++;
} }
break; }
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': else if (*in == ':' || ISALNUM (*in))
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case ':':
*out++ = *in++; *out++ = *in++;
break; else
default:
/* unexpected character in symbol, not looks_like_rust. */ /* unexpected character in symbol, not looks_like_rust. */
goto fail; goto fail;
} }
...@@ -332,18 +259,78 @@ done: ...@@ -332,18 +259,78 @@ done:
*out = '\0'; *out = '\0';
} }
/* Return a 0x0-0xf value if the char is 0-9a-f, and -1 otherwise. */
static int static int
unescape (const char **in, char **out, const char *seq, char value) parse_lower_hex_nibble (char nibble)
{
if ('0' <= nibble && nibble <= '9')
return nibble - '0';
if ('a' <= nibble && nibble <= 'f')
return 0xa + (nibble - 'a');
return -1;
}
/* Return the unescaped character for a "$...$" escape, or 0 if invalid. */
static char
parse_legacy_escape (const char **in)
{ {
size_t len = strlen (seq); char c = 0;
const char *e;
size_t escape_len = 0;
int lo_nibble = -1, hi_nibble = -1;
if (strncmp (*in, seq, len)) if ((*in)[0] != '$')
return 0; return 0;
**out = value; e = *in + 1;
*in += len; if (e[0] == 'C')
*out += 1; {
escape_len = 1;
return 1; c = ',';
}
else
{
escape_len = 2;
if (e[0] == 'S' && e[1] == 'P')
c = '@';
else if (e[0] == 'B' && e[1] == 'P')
c = '*';
else if (e[0] == 'R' && e[1] == 'F')
c = '&';
else if (e[0] == 'L' && e[1] == 'T')
c = '<';
else if (e[0] == 'G' && e[1] == 'T')
c = '>';
else if (e[0] == 'L' && e[1] == 'P')
c = '(';
else if (e[0] == 'R' && e[1] == 'P')
c = ')';
else if (e[0] == 'u')
{
escape_len = 3;
hi_nibble = parse_lower_hex_nibble (e[1]);
if (hi_nibble < 0)
return 0;
lo_nibble = parse_lower_hex_nibble (e[2]);
if (lo_nibble < 0)
return 0;
/* Only allow non-control ASCII characters. */
if (hi_nibble > 7)
return 0;
c = (hi_nibble << 4) | lo_nibble;
if (c < 0x20)
return 0;
}
}
if (!c || e[escape_len] != '$')
return 0;
*in += 2 + escape_len;
return c;
} }
...@@ -159,3 +159,7 @@ _ZN68_$LT$core..nonzero..NonZero$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref1 ...@@ -159,3 +159,7 @@ _ZN68_$LT$core..nonzero..NonZero$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref1
--format=rust --format=rust
_ZN63_$LT$core..ptr..Unique$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17h19f2ad4920655e85E _ZN63_$LT$core..ptr..Unique$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17h19f2ad4920655e85E
<core::ptr::Unique<T> as core::ops::Deref>::deref <core::ptr::Unique<T> as core::ops::Deref>::deref
#
--format=rust
_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h059a991a004536adE
issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment