]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Update libiberty demangler
authorMark Wielaard <mark@klomp.org>
Sun, 26 Sep 2021 12:47:17 +0000 (14:47 +0200)
committerMark Wielaard <mark@klomp.org>
Sun, 26 Sep 2021 12:47:17 +0000 (14:47 +0200)
Update the libiberty demangler using the auxprogs/update-demangler
script to gcc git commit b3585c0836e729bed56b9afd4292177673a25ca0.

This update includes:

- prevent null dereferencing on dlang_type
- prevent buffer overflow when decoding user input
- Add support for demangling local D template declarations
- Add support for demangling D function literals as template
  value parameters
- Add support for D `typeof(*null)' types
- Fix -Wundef warnings in ansidecl.h
- Fix endian bug in rust demangler
- Adjust mangling of __alignof__
- Avoid -Wstringop-truncation

auxprogs/update-demangler
coregrind/m_demangle/ansidecl.h
coregrind/m_demangle/cp-demangle.c
coregrind/m_demangle/d-demangle.c
coregrind/m_demangle/demangle.h
coregrind/m_demangle/dyn-string.c
coregrind/m_demangle/rust-demangle.c

index 947fa5e314cb836391aedcc6880b664ba4a6f620..00c0904678d342c6b7ef979126568167f871662e 100755 (executable)
@@ -17,8 +17,8 @@ set -e
 #---------------------------------------------------------------------
 
 # You need to modify these revision numbers for your update.
-old_gcc_revision=7a312bbd41e190379d80b47e308a32c8bc4575c3  # the revision of the previous update
-new_gcc_revision=01d92cfd79872e4cffc78bf233bb9b767336beb8  # the revision for this update
+old_gcc_revision=01d92cfd79872e4cffc78bf233bb9b767336beb8 # the revision of the previous update
+new_gcc_revision=b3585c0836e729bed56b9afd4292177673a25ca0 # the revision for this update
 
 # Unless the organization of demangler related files has changed, no
 # changes below this line should be necessary.
index 8e5de9bf5a89493205626536583a0c83689d560b..2329c8655afa1c1b40cf0084e0bfd6bc6a30b81d 100644 (file)
@@ -79,7 +79,7 @@ So instead we use the macro below and test it against specific values.  */
 /* inline requires special treatment; it's in C99, and GCC >=2.7 supports
    it too, but it's not in C89.  */
 #undef inline
-#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+#if (!defined(__cplusplus) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
 /* it's a keyword */
 #else
 # if GCC_VERSION >= 2007
@@ -356,7 +356,7 @@ So instead we use the macro below and test it against specific values.  */
 #define ENUM_BITFIELD(TYPE) unsigned int
 #endif
 
-#if __cpp_constexpr >= 200704
+#if defined(__cplusplus) && __cpp_constexpr >= 200704
 #define CONSTEXPR constexpr
 #else
 #define CONSTEXPR
@@ -419,7 +419,7 @@ So instead we use the macro below and test it against specific values.  */
 
    so that most attempts at copy are caught at compile-time.  */
 
-#if __cplusplus >= 201103
+#if defined(__cplusplus) && __cplusplus >= 201103
 #define DISABLE_COPY_AND_ASSIGN(TYPE)          \
   TYPE (const TYPE&) = delete;                 \
   void operator= (const TYPE &) = delete
index 11382a23ca9d1a72b4355bf8a570e9b5087bd57d..1f4cd3d28e77abcf23d4d17dde21fb512a404aae 100644 (file)
@@ -832,6 +832,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_LITERAL_NEG:
       printf ("negative literal\n");
       break;
+    case DEMANGLE_COMPONENT_VENDOR_EXPR:
+      printf ("vendor expression\n");
+      break;
     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
       printf ("java resource\n");
       break;
@@ -993,6 +996,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_TRINARY_ARG1:
     case DEMANGLE_COMPONENT_LITERAL:
     case DEMANGLE_COMPONENT_LITERAL_NEG:
+    case DEMANGLE_COMPONENT_VENDOR_EXPR:
     case DEMANGLE_COMPONENT_COMPOUND_NAME:
     case DEMANGLE_COMPONENT_VECTOR_TYPE:
     case DEMANGLE_COMPONENT_CLONE:
@@ -2982,7 +2986,7 @@ d_parmlist (struct d_info *di)
 /* <bare-function-type> ::= [J]<type>+  */
 
 static struct demangle_component *
-d_bare_function_type (struct d_info *di, int has_return_tipe)
+d_bare_function_type (struct d_info *di, int has_return_type)
 {
   struct demangle_component *return_type;
   struct demangle_component *tl;
@@ -2994,10 +2998,10 @@ d_bare_function_type (struct d_info *di, int has_return_tipe)
   if (peek == 'J')
     {
       d_advance (di, 1);
-      has_return_tipe = 1;
+      has_return_type = 1;
     }
 
-  if (has_return_tipe)
+  if (has_return_type)
     {
       return_type = cplus_demangle_type (di);
       if (return_type == NULL)
@@ -3361,6 +3365,7 @@ d_unresolved_name (struct d_info *di)
                ::= cl <expression>+ E
                 ::= st <type>
                 ::= <template-param>
+               ::= u <source-name> <template-arg>* E # vendor extended expression
                ::= <unresolved-name>
                 ::= <expr-primary>
 
@@ -3442,6 +3447,15 @@ d_expression_1 (struct d_info *di)
       return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
                          type, d_exprlist (di, 'E'));
     }
+  else if (peek == 'u')
+    {
+      /* A vendor extended expression.  */
+      struct demangle_component *name, *args;
+      d_advance (di, 1);
+      name = d_source_name (di);
+      args = d_template_args_1 (di);
+      return d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_EXPR, name, args);
+    }
   else
     {
       struct demangle_component *op;
@@ -4246,6 +4260,7 @@ d_count_templates_scopes (struct d_print_info *dpi,
     case DEMANGLE_COMPONENT_TRINARY_ARG2:
     case DEMANGLE_COMPONENT_LITERAL:
     case DEMANGLE_COMPONENT_LITERAL_NEG:
+    case DEMANGLE_COMPONENT_VENDOR_EXPR:
     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
     case DEMANGLE_COMPONENT_COMPOUND_NAME:
     case DEMANGLE_COMPONENT_DECLTYPE:
@@ -5542,18 +5557,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       }
 
     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
-      {
-       struct demangle_component *name = dc->u.s_extended_operator.name;
-       if (name->type == DEMANGLE_COMPONENT_NAME
-           && !strncmp (name->u.s_name.s, "__alignof__", name->u.s_name.len))
-         d_print_comp (dpi, options, dc->u.s_extended_operator.name);
-       else
-         {
-           d_append_string (dpi, "operator ");
-           d_print_comp (dpi, options, dc->u.s_extended_operator.name);
-         }
-       return;
-      }
+      d_append_string (dpi, "operator ");
+      d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+      return;
 
     case DEMANGLE_COMPONENT_CONVERSION:
       d_append_string (dpi, "operator ");
@@ -5618,14 +5624,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
        if (code && !strcmp (code, "gs"))
          /* Avoid parens after '::'.  */
          d_print_comp (dpi, options, operand);
-       else if ((code && !strcmp (code, "st"))
-                || (op->type == DEMANGLE_COMPONENT_EXTENDED_OPERATOR
-                    && (op->u.s_extended_operator.name->type
-                        == DEMANGLE_COMPONENT_NAME)
-                    && !strncmp (op->u.s_extended_operator.name->u.s_name.s,
-                                 "__alignof__",
-                                 op->u.s_extended_operator.name->u.s_name.len)))
-         /* Always print parens for sizeof (type) and __alignof__.  */
+       else if (code && !strcmp (code, "st"))
+         /* Always print parens for sizeof (type).  */
          {
            d_append_char (dpi, '(');
            d_print_comp (dpi, options, operand);
@@ -5838,6 +5838,13 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       }
       return;
 
+    case DEMANGLE_COMPONENT_VENDOR_EXPR:
+      d_print_comp (dpi, options, d_left (dc));
+      d_append_char (dpi, '(');
+      d_print_comp (dpi, options, d_right (dc));
+      d_append_char (dpi, ')');
+      return;
+
     case DEMANGLE_COMPONENT_NUMBER:
       d_append_num (dpi, dc->u.s_number.number);
       return;
index 1f2fbbe43fc7eac303c00fdfccf06ffd3ae56f8c..4525c48d4bad2ec5e231550129240dd34867ee91 100644 (file)
@@ -207,7 +207,8 @@ static const char *dlang_function_args (string *, const char *,
 
 static const char *dlang_type (string *, const char *, struct dlang_info *);
 
-static const char *dlang_value (string *, const char *, const char *, char);
+static const char *dlang_value (string *, const char *, const char *, char,
+                               struct dlang_info *);
 
 static const char *dlang_parse_qualified (string *, const char *,
                                          struct dlang_info *, int);
@@ -396,7 +397,7 @@ dlang_symbol_backref (string *decl, const char *mangled,
 
   /* Must point to a simple identifier.  */
   backref = dlang_number (backref, &len);
-  if (backref == NULL)
+  if (backref == NULL || strlen(backref) < len)
     return NULL;
 
   backref = dlang_lname (decl, backref, len);
@@ -589,9 +590,11 @@ dlang_attributes (string *decl, const char *mangled)
        case 'g':
        case 'h':
        case 'k':
+       case 'n':
          /* inout parameter is represented as 'Ng'.
             vector parameter is represented as 'Nh'.
-            return paramenter is represented as 'Nk'.
+            return parameter is represented as 'Nk'.
+            typeof(*null) parameter is represented as 'Nn'.
             If we see this, then we know we're really in the
             parameter list.  Rewind and break.  */
          mangled--;
@@ -803,6 +806,12 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info)
          string_append (decl, ")");
          return mangled;
        }
+      else if (*mangled == 'n') /* typeof(*null) */
+       {
+         mangled++;
+         string_append (decl, "typeof(*null)");
+         return mangled;
+       }
       else
        return NULL;
     case 'A': /* dynamic array (T[]) */
@@ -882,7 +891,7 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info)
       szmods = string_length (&mods);
 
       /* Back referenced function type.  */
-      if (*mangled == 'Q')
+      if (mangled && *mangled == 'Q')
        mangled = dlang_type_backref (decl, mangled, info, 1);
       else
        mangled = dlang_function_type (decl, mangled, info);
@@ -900,7 +909,7 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info)
     /* Basic types */
     case 'n':
       mangled++;
-      string_append (decl, "none");
+      string_append (decl, "typeof(null)");
       return mangled;
     case 'v':
       mangled++;
@@ -1051,6 +1060,25 @@ dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
       && (mangled[2] == 'T' || mangled[2] == 'U'))
     return dlang_parse_template (decl, mangled, info, len);
 
+  /* There can be multiple different declarations in the same function that have
+     the same mangled name.  To make the mangled names unique, a fake parent in
+     the form `__Sddd' is added to the symbol.  */
+  if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S')
+    {
+      const char *numptr = mangled + 3;
+      while (numptr < (mangled + len) && ISDIGIT (*numptr))
+       numptr++;
+
+      if (mangled + len == numptr)
+       {
+         /* Skip over the fake parent.  */
+         mangled += len;
+         return dlang_identifier (decl, mangled, info);
+       }
+
+      /* else demangle it as a plain identifier.  */
+    }
+
   return dlang_lname (decl, mangled, len);
 }
 
@@ -1394,7 +1422,8 @@ dlang_parse_string (string *decl, const char *mangled)
 /* Extract the static array value from MANGLED and append it to DECL.
    Return the remaining string on success or NULL on failure.  */
 static const char *
-dlang_parse_arrayliteral (string *decl, const char *mangled)
+dlang_parse_arrayliteral (string *decl, const char *mangled,
+                         struct dlang_info *info)
 {
   unsigned long elements;
 
@@ -1405,7 +1434,7 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
   string_append (decl, "[");
   while (elements--)
     {
-      mangled = dlang_value (decl, mangled, NULL, '\0');
+      mangled = dlang_value (decl, mangled, NULL, '\0', info);
       if (mangled == NULL)
        return NULL;
 
@@ -1420,7 +1449,8 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
 /* Extract the associative array value from MANGLED and append it to DECL.
    Return the remaining string on success or NULL on failure.  */
 static const char *
-dlang_parse_assocarray (string *decl, const char *mangled)
+dlang_parse_assocarray (string *decl, const char *mangled,
+                       struct dlang_info *info)
 {
   unsigned long elements;
 
@@ -1431,12 +1461,12 @@ dlang_parse_assocarray (string *decl, const char *mangled)
   string_append (decl, "[");
   while (elements--)
     {
-      mangled = dlang_value (decl, mangled, NULL, '\0');
+      mangled = dlang_value (decl, mangled, NULL, '\0', info);
       if (mangled == NULL)
        return NULL;
 
       string_append (decl, ":");
-      mangled = dlang_value (decl, mangled, NULL, '\0');
+      mangled = dlang_value (decl, mangled, NULL, '\0', info);
       if (mangled == NULL)
        return NULL;
 
@@ -1451,7 +1481,8 @@ dlang_parse_assocarray (string *decl, const char *mangled)
 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
    Return the remaining string on success or NULL on failure.  */
 static const char *
-dlang_parse_structlit (string *decl, const char *mangled, const char *name)
+dlang_parse_structlit (string *decl, const char *mangled, const char *name,
+                      struct dlang_info *info)
 {
   unsigned long args;
 
@@ -1465,7 +1496,7 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
   string_append (decl, "(");
   while (args--)
     {
-      mangled = dlang_value (decl, mangled, NULL, '\0');
+      mangled = dlang_value (decl, mangled, NULL, '\0', info);
       if (mangled == NULL)
        return NULL;
 
@@ -1480,7 +1511,8 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
 /* Extract the value from MANGLED and append it to DECL.
    Return the remaining string on success or NULL on failure.  */
 static const char *
-dlang_value (string *decl, const char *mangled, const char *name, char type)
+dlang_value (string *decl, const char *mangled, const char *name, char type,
+            struct dlang_info *info)
 {
   if (mangled == NULL || *mangled == '\0')
     return NULL;
@@ -1541,15 +1573,24 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
     case 'A':
       mangled++;
       if (type == 'H')
-       mangled = dlang_parse_assocarray (decl, mangled);
+       mangled = dlang_parse_assocarray (decl, mangled, info);
       else
-       mangled = dlang_parse_arrayliteral (decl, mangled);
+       mangled = dlang_parse_arrayliteral (decl, mangled, info);
       break;
 
       /* Struct values.  */
     case 'S':
       mangled++;
-      mangled = dlang_parse_structlit (decl, mangled, name);
+      mangled = dlang_parse_structlit (decl, mangled, name, info);
+      break;
+
+      /* Function literal symbol.  */
+    case 'f':
+      mangled++;
+      if (strncmp (mangled, "_D", 2) != 0
+         || !dlang_symbol_name_p (mangled + 2, info))
+       return NULL;
+      mangled = dlang_parse_mangle (decl, mangled, info);
       break;
 
     default:
@@ -1822,7 +1863,7 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
          string_need (&name, 1);
          *(name.p) = '\0';
 
-         mangled = dlang_value (decl, mangled, name.b, type);
+         mangled = dlang_value (decl, mangled, name.b, type, info);
          string_delete (&name);
          break;
        }
index bcccf45d0c1ac4361b6eee2467eccfb8068bd580..2acb3bd4eea0b6f2eabb904abdcdf8ea92cdec35 100644 (file)
@@ -410,6 +410,9 @@ enum demangle_component_type
      number which involves neither modifying the mangled string nor
      allocating a new copy of the literal in memory.  */
   DEMANGLE_COMPONENT_LITERAL_NEG,
+  /* A vendor's builtin expression.  The left subtree holds the
+     expression's name, and the right subtree is a argument list.  */
+  DEMANGLE_COMPONENT_VENDOR_EXPR,
   /* A libgcj compiled resource.  The left subtree is the name of the
      resource.  */
   DEMANGLE_COMPONENT_JAVA_RESOURCE,
index 8b688a24ad6f07dc39b040add057a19ece683924..66948debff162616c13699ba75e971199ea17693 100644 (file)
@@ -290,7 +290,7 @@ dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src)
   for (i = dest->length; i >= pos; --i)
     dest->s[i + length] = dest->s[i];
   /* Splice in the new stuff.  */
-  strncpy (dest->s + pos, src, length);
+  memcpy (dest->s + pos, src, length);
   /* Compute the new length.  */
   dest->length += length;
   return 1;
index 9ad424e85cd0e6b082cd10cc471e40be6854c62f..0cafa3df9cf0f7904c9c680d746fb0475c43820e 100644 (file)
@@ -1280,9 +1280,12 @@ demangle_const_char (struct rust_demangler *rdm)
   else if (value == '\n')
     PRINT ("\\n");
   else if (value > ' ' && value < '~')
-    /* Rust also considers many non-ASCII codepoints to be printable, but
-       that logic is not easily ported to C. */
-    print_str (rdm, (char *) &value, 1);
+    {
+      /* Rust also considers many non-ASCII codepoints to be printable, but
+        that logic is not easily ported to C. */
+      char c = value;
+      print_str (rdm, &c, 1);
+    }
   else
     {
       PRINT ("\\u{");