GNU Binutils with patches for OS216
リビジョン | e61b4af73de761ca2b877b09c1ad710f44ba0f54 (tree) |
---|---|
日時 | 2018-02-05 12:21:08 |
作者 | Simon Marchi <simon.marchi@poly...> |
コミッター | Simon Marchi |
Don't trust templates from DW_AT_name
With gcc 8 (and clang?) the non-type template arguments (constants)
don't include the integer suffixes anymore. For example, with
used to generate foo<10u> as the DW_AT_name, now it generates foo<10>.
This is a problem when things look up "foo<10u>" and don't find it. For
example, when trying to print an instance of that class through a base
class pointer, GDB would first demangle the symbol for that class'
vtable, which would give "vtable for foo<10u>". GDB would then take the
"foo<10u>" from that string and try to look up the type. With the new
DW_AT_name, it would fail to look it up, and fail to print the value.
This patch makes it so GDB doesn't trust the templates contained in
DW_AT_name. Instead, it re-builds the name from the DW_AT_template_*
DIES in the format that it expects (with the integer suffixes).
@@ -454,6 +454,21 @@ c_val_print_int (struct type *type, struct type *unresolved_type, | ||
454 | 454 | : options->output_format); |
455 | 455 | val_print_scalar_formatted (type, embedded_offset, |
456 | 456 | original_value, &opts, 0, stream); |
457 | + | |
458 | + if (opts.print_suffix) | |
459 | + { | |
460 | + struct type *t = check_typedef (type); | |
461 | + | |
462 | + if (TYPE_UNSIGNED (t)) | |
463 | + fputc_filtered ('u', stream); | |
464 | + | |
465 | + /* Is there a better way to do this? Just looking at the size doesn't | |
466 | + work. */ | |
467 | + if (strstr (TYPE_NAME (t), "long long") != NULL) | |
468 | + fputs_filtered ("ll", stream); | |
469 | + else if (strstr (TYPE_NAME (t), "long") != NULL) | |
470 | + fputc_filtered ('l', stream); | |
471 | + } | |
457 | 472 | } |
458 | 473 | else |
459 | 474 | { |
@@ -9211,7 +9211,7 @@ partial_die_full_name (struct partial_die_info *pdi, | ||
9211 | 9211 | { |
9212 | 9212 | fixup_partial_die (pdi, cu); |
9213 | 9213 | |
9214 | - if (pdi->name != NULL && strchr (pdi->name, '<') == NULL) | |
9214 | + if (pdi->name != NULL) | |
9215 | 9215 | { |
9216 | 9216 | struct die_info *die; |
9217 | 9217 | struct attribute attr; |
@@ -10875,6 +10875,22 @@ dwarf2_compute_name (const char *name, | ||
10875 | 10875 | if (name == NULL) |
10876 | 10876 | name = dwarf2_name (die, cu); |
10877 | 10877 | |
10878 | + /* If there is a template in the name, strip it and let the code below | |
10879 | + re-compute it. */ | |
10880 | + gdb::unique_xmalloc_ptr<char> holder; | |
10881 | + if (name != NULL) | |
10882 | + { | |
10883 | + const char *opening = strchr (name, '<'); | |
10884 | + if (opening != NULL) | |
10885 | + { | |
10886 | + /* In this case, name will get copied/modified and re-assigned, | |
10887 | + so we can free this copy. */ | |
10888 | + holder.reset (xstrdup (name)); | |
10889 | + holder.get ()[opening - name] = '\0'; | |
10890 | + name = holder.get (); | |
10891 | + } | |
10892 | + } | |
10893 | + | |
10878 | 10894 | /* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present |
10879 | 10895 | but otherwise compute it by typename_concat inside GDB. |
10880 | 10896 | FIXME: Actually this is not really true, or at least not always true. |
@@ -10942,7 +10958,7 @@ dwarf2_compute_name (const char *name, | ||
10942 | 10958 | templates; two instantiated function templates are allowed to |
10943 | 10959 | differ only by their return types, which we do not add here. */ |
10944 | 10960 | |
10945 | - if (cu->language == language_cplus && strchr (name, '<') == NULL) | |
10961 | + if (cu->language == language_cplus) | |
10946 | 10962 | { |
10947 | 10963 | struct attribute *attr; |
10948 | 10964 | struct die_info *child; |
@@ -11026,6 +11042,7 @@ dwarf2_compute_name (const char *name, | ||
11026 | 11042 | the radix. */ |
11027 | 11043 | get_formatted_print_options (&opts, 'd'); |
11028 | 11044 | opts.raw = 1; |
11045 | + opts.print_suffix = true; | |
11029 | 11046 | value_print (v, &buf, &opts); |
11030 | 11047 | release_value (v); |
11031 | 11048 | value_free (v); |
@@ -109,7 +109,8 @@ struct value_print_options user_print_options = | ||
109 | 109 | 1, /* pascal_static_field_print */ |
110 | 110 | 0, /* raw */ |
111 | 111 | 0, /* summary */ |
112 | - 1 /* symbol_print */ | |
112 | + 1, /* symbol_print */ | |
113 | + false, /* print_suffix */ | |
113 | 114 | }; |
114 | 115 | |
115 | 116 | /* Initialize *OPTS to be a copy of the user print options. */ |
@@ -92,6 +92,10 @@ struct value_print_options | ||
92 | 92 | /* If nonzero, when printing a pointer, print the symbol to which it |
93 | 93 | points, if any. */ |
94 | 94 | int symbol_print; |
95 | + | |
96 | + /* If true, print the integer suffixes (u for unsigned, l for long, ll for | |
97 | + long long). */ | |
98 | + bool print_suffix; | |
95 | 99 | }; |
96 | 100 | |
97 | 101 | /* The global print options set by the user. In general this should |