summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortheraven <theraven@FreeBSD.org>2013-09-23 13:16:21 +0000
committertheraven <theraven@FreeBSD.org>2013-09-23 13:16:21 +0000
commit674fdc66685eb6f5b619be29f1ed5af5c0713c53 (patch)
tree49f6d96a3a7240328177ad82e69c6f0b74166fc0
parent9c38c532fffb7380cebafcee5521c5ceffd56ff0 (diff)
downloadFreeBSD-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
-rw-r--r--contrib/libcxxrt/libelftc_dem_gnu3.c76
-rw-r--r--contrib/libcxxrt/typeinfo.cc13
-rw-r--r--contrib/libcxxrt/unwind-itanium.h2
3 files changed, 74 insertions, 17 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);
}
diff --git a/contrib/libcxxrt/typeinfo.cc b/contrib/libcxxrt/typeinfo.cc
index f941abd..fda5196 100644
--- a/contrib/libcxxrt/typeinfo.cc
+++ b/contrib/libcxxrt/typeinfo.cc
@@ -86,7 +86,18 @@ extern "C" char* __cxa_demangle(const char* mangled_name,
if (NULL != demangled)
{
size_t len = strlen(demangled);
- buf = (char*)realloc(buf, len+1);
+ if (buf == NULL)
+ {
+ if (n)
+ {
+ *n = len;
+ }
+ return demangled;
+ }
+ if (*n < len+1)
+ {
+ buf = (char*)realloc(buf, len+1);
+ }
if (0 != buf)
{
memcpy(buf, demangled, len);
diff --git a/contrib/libcxxrt/unwind-itanium.h b/contrib/libcxxrt/unwind-itanium.h
index a5c0e755..0ca9488 100644
--- a/contrib/libcxxrt/unwind-itanium.h
+++ b/contrib/libcxxrt/unwind-itanium.h
@@ -80,7 +80,7 @@ struct _Unwind_Exception
_Unwind_Exception_Cleanup_Fn exception_cleanup;
unsigned long private_1;
unsigned long private_2;
- };
+ } ;
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
OpenPOWER on IntegriCloud