diff options
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index eb5d924..81b20c7 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -404,6 +404,13 @@ struct dwarf2_cu DIEs for namespaces, we don't need to try to infer them from mangled names. */ unsigned int has_namespace_info : 1; + + /* This CU references .debug_loc. See the symtab->locations_valid field. + This test is imperfect as there may exist optimized debug code not using + any location list and still facing inlining issues if handled as + unoptimized code. For a future better test see GCC PR other/32998. */ + + unsigned int has_loclist : 1; }; /* Persistent data held for a compilation unit, even when not @@ -4610,6 +4617,44 @@ compute_delayed_physnames (struct dwarf2_cu *cu) } } +/* Check for GCC >= 4.0. */ + +static int +producer_is_gcc_ge_4_0 (struct dwarf2_cu *cu) +{ + const char *cs; + int major, minor; + + if (cu->producer == NULL) + { + /* For unknown compilers expect their behavior is not compliant. For GCC + this case can also happen for -gdwarf-4 type units supported since + gcc-4.5. */ + + return 0; + } + + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ + + if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) + { + /* For non-GCC compilers expect their behavior is not compliant. */ + + return 0; + } + cs = &cu->producer[strlen ("GNU ")]; + while (*cs && !isdigit (*cs)) + cs++; + if (sscanf (cs, "%d.%d", &major, &minor) != 2) + { + /* Not recognized as GCC. */ + + return 0; + } + + return major >= 4; +} + /* Generate full symbol information for PST and CU, whose DIEs have already been loaded into memory. */ @@ -4649,13 +4694,26 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); - /* Set symtab language to language from DW_AT_language. - If the compilation is from a C file generated by language preprocessors, - do not set the language if it was already deduced by start_subfile. */ - if (symtab != NULL - && !(cu->language == language_c && symtab->language != language_c)) + if (symtab != NULL) { - symtab->language = cu->language; + /* Set symtab language to language from DW_AT_language. If the + compilation is from a C file generated by language preprocessors, do + not set the language if it was already deduced by start_subfile. */ + if (!(cu->language == language_c && symtab->language != language_c)) + symtab->language = cu->language; + + /* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can + produce DW_AT_location with location lists but it can be possibly + invalid without -fvar-tracking. + + For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not + needed, it would be wrong due to missing DW_AT_producer there. + + Still one can confuse GDB by using non-standard GCC compilation + options - this waits on GCC PR other/32998 (-frecord-gcc-switches). + */ + if (cu->has_loclist && producer_is_gcc_ge_4_0 (cu)) + symtab->locations_valid = 1; } if (dwarf2_per_objfile->using_index) @@ -10968,6 +11026,9 @@ var_decode_location (struct attribute *attr, struct symbol *sym, dwarf2_symbol_mark_computed (attr, sym, cu); SYMBOL_CLASS (sym) = LOC_COMPUTED; + + if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs) + cu->has_loclist = 1; } /* Given a pointer to a DWARF information entry, figure out if we need |