diff options
author | theraven <theraven@FreeBSD.org> | 2013-09-23 13:16:21 +0000 |
---|---|---|
committer | theraven <theraven@FreeBSD.org> | 2013-09-23 13:16:21 +0000 |
commit | 674fdc66685eb6f5b619be29f1ed5af5c0713c53 (patch) | |
tree | 49f6d96a3a7240328177ad82e69c6f0b74166fc0 /contrib/libcxxrt/libelftc_dem_gnu3.c | |
parent | 9c38c532fffb7380cebafcee5521c5ceffd56ff0 (diff) | |
download | FreeBSD-src-674fdc66685eb6f5b619be29f1ed5af5c0713c53.zip FreeBSD-src-674fdc66685eb6f5b619be29f1ed5af5c0713c53.tar.gz |
Import a new libcxxrt. This fixes some potential crashing in the demangler.
Approved by: re (gjb)
MFC after: 1 week
Diffstat (limited to 'contrib/libcxxrt/libelftc_dem_gnu3.c')
-rw-r--r-- | contrib/libcxxrt/libelftc_dem_gnu3.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/contrib/libcxxrt/libelftc_dem_gnu3.c b/contrib/libcxxrt/libelftc_dem_gnu3.c index b0428c9..11c2ca2 100644 --- a/contrib/libcxxrt/libelftc_dem_gnu3.c +++ b/contrib/libcxxrt/libelftc_dem_gnu3.c @@ -405,6 +405,7 @@ static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, const char *, size_t, const char *, size_t); static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, struct vector_type_qualifier *); +static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); static int cpp_demangle_read_local_name(struct cpp_demangle_data *); static int cpp_demangle_read_name(struct cpp_demangle_data *); static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); @@ -453,13 +454,22 @@ __cxa_demangle_gnu3(const char *org) struct cpp_demangle_data ddata; ssize_t org_len; unsigned int limit; - char *rtn; + char *rtn = NULL; if (org == NULL) return (NULL); + org_len = strlen(org); + if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { + if ((rtn = malloc(org_len + 19)) == NULL) + return (NULL); + snprintf(rtn, org_len + 19, + "global constructors keyed to %s", org + 11); + return (rtn); + } + // Try demangling as a type for short encodings - if (((org_len = strlen(org)) < 2) || (org[0] != '_' || org[1] != 'Z' )) { + if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) { if (!cpp_demangle_data_init(&ddata, org)) return (NULL); if (!cpp_demangle_read_type(&ddata, 0)) @@ -467,13 +477,6 @@ __cxa_demangle_gnu3(const char *org) rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); goto clean; } - if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { - if ((rtn = malloc(org_len + 19)) == NULL) - return (NULL); - snprintf(rtn, org_len + 19, - "global constructors keyed to %s", org + 11); - return (rtn); - } if (!cpp_demangle_data_init(&ddata, org + 2)) @@ -604,13 +607,12 @@ cpp_demangle_push_fp(struct cpp_demangle_data *ddata, return (0); rtn = 0; - if ((len = strlen(f)) > 0 && - cpp_demangle_push_str(ddata, f, len)) - rtn = 1; + if ((len = strlen(f)) > 0) + rtn = cpp_demangle_push_str(ddata, f, len); free(f); - return (0); + return (rtn); } static int @@ -655,6 +657,7 @@ cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) return (0); rtn = cpp_demangle_push_subst(ddata, str, str_len); + free(str); return (rtn); @@ -1868,9 +1871,18 @@ static int cpp_demangle_read_sname(struct cpp_demangle_data *ddata) { long len; + int err; if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || - len <= 0 || cpp_demangle_push_str(ddata, ddata->cur, len) == 0) + len <= 0) + return (0); + + if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) + err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21); + else + err = cpp_demangle_push_str(ddata, ddata->cur, len); + + if (err == 0) return (0); assert(ddata->output.size > 0); @@ -2054,7 +2066,7 @@ clean: free(subst_str); vector_str_dest(&v); - return (1); + return (rtn); } static int @@ -2996,6 +3008,40 @@ cpp_demangle_read_uqname(struct cpp_demangle_data *ddata) if (ELFTC_ISDIGIT(*ddata->cur) != 0) return (cpp_demangle_read_sname(ddata)); + + /* local source name */ + if (*ddata->cur == 'L') + return (cpp_demangle_local_source_name(ddata)); + + return (1); +} + +/* + * Read local source name. + * + * References: + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 + * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 + */ +static int +cpp_demangle_local_source_name(struct cpp_demangle_data *ddata) +{ + /* L */ + if (ddata == NULL || *ddata->cur != 'L') + return (0); + ++ddata->cur; + + /* source name */ + if (!cpp_demangle_read_sname(ddata)) + return (0); + + /* discriminator */ + if (*ddata->cur == '_') { + ++ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + } + return (1); } |