From 89e63ee47a55271506d68f24b25a4a2094ab346f Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Wed, 4 Sep 2013 23:05:32 +0000 Subject: [PATCH] * dwarf2read.c (queue_and_load_all_dwo_tus): New function. (queue_and_load_dwo_tu): New function. (lookup_dwo_signatured_type): Set per_cu.tu_read. (maybe_queue_comp_unit): Rename this_cu argument to dependent_cu. Make dependent_cu optional. (dw2_do_instantiate_symtab): If we just loaded a CU from a DWO, and an older .gdb_index is in use, queue and load all its TUs too. testsuite/ * gdb.base/enumval.c (ZERO): New enum value. (main): Use it * gdb.base/enumval.exp: Test ability to print ZERO. --- gdb/ChangeLog | 10 ++++ gdb/dwarf2read.c | 73 ++++++++++++++++++++++++++++-- gdb/testsuite/ChangeLog | 8 +++- gdb/testsuite/gdb.base/enumval.c | 4 +- gdb/testsuite/gdb.base/enumval.exp | 6 +++ 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bd7a8fb0425..91fced47df9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2013-09-04 Doug Evans + + * dwarf2read.c (queue_and_load_all_dwo_tus): New function. + (queue_and_load_dwo_tu): New function. + (lookup_dwo_signatured_type): Set per_cu.tu_read. + (maybe_queue_comp_unit): Rename this_cu argument to dependent_cu. + Make dependent_cu optional. + (dw2_do_instantiate_symtab): If we just loaded a CU from a DWO, + and an older .gdb_index is in use, queue and load all its TUs too. + 2013-09-04 Jan Kratochvil Code cleanup: Change OPF_DISABLE_REALPATH to OPF_RETURN_REALPATH. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 59b7b01a2fe..4b30e6e310d 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1778,6 +1778,8 @@ static struct dwo_unit *lookup_dwo_comp_unit static struct dwo_unit *lookup_dwo_type_unit (struct signatured_type *, const char *, const char *); +static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *); + static void free_dwo_file_cleanup (void *); static void process_cu_includes (void); @@ -2338,6 +2340,17 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) { queue_comp_unit (per_cu, language_minimal); load_cu (per_cu); + + /* If we just loaded a CU from a DWO, and we're working with an index + that may badly handle TUs, load all the TUs in that DWO as well. + http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */ + if (!per_cu->is_debug_types + && per_cu->cu->dwo_unit != NULL + && dwarf2_per_objfile->index_table != NULL + && dwarf2_per_objfile->index_table->version <= 7 + /* DWP files aren't supported yet. */ + && get_dwp_file () == NULL) + queue_and_load_all_dwo_tus (per_cu); } process_queue (); @@ -4468,6 +4481,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) return NULL; fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry); + sig_entry->per_cu.tu_read = 1; return sig_entry; } @@ -6940,8 +6954,9 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu, dwarf2_queue_tail = item; } -/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation - unit and add it to our queue. +/* If PER_CU is not yet queued, add it to the queue. + If DEPENDENT_CU is non-NULL, it has a reference to PER_CU so add a + dependency. The result is non-zero if PER_CU was queued, otherwise the result is zero meaning either PER_CU is already queued or it is already loaded. @@ -6949,7 +6964,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu, The caller is required to load PER_CU if we return non-zero. */ static int -maybe_queue_comp_unit (struct dwarf2_cu *this_cu, +maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu, struct dwarf2_per_cu_data *per_cu, enum language pretend_language) { @@ -6965,7 +6980,8 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu, /* Mark the dependence relation so that we don't flush PER_CU too early. */ - dwarf2_add_dependence (this_cu, per_cu); + if (dependent_cu != NULL) + dwarf2_add_dependence (dependent_cu, per_cu); /* If it's already on the queue, we have nothing to do. */ if (per_cu->queued) @@ -9828,6 +9844,55 @@ lookup_dwo_type_unit (struct signatured_type *this_tu, return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1); } +/* Traversal function for queue_and_load_all_dwo_tus. */ + +static int +queue_and_load_dwo_tu (void **slot, void *info) +{ + struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot; + struct dwarf2_per_cu_data *per_cu = (struct dwarf2_per_cu_data *) info; + ULONGEST signature = dwo_unit->signature; + struct signatured_type *sig_type = + lookup_dwo_signatured_type (per_cu->cu, signature); + + if (sig_type != NULL) + { + struct dwarf2_per_cu_data *sig_cu = &sig_type->per_cu; + + /* We pass NULL for DEPENDENT_CU because we don't yet know if there's + a real dependency of PER_CU on SIG_TYPE. That is detected later + while processing PER_CU. */ + if (maybe_queue_comp_unit (NULL, sig_cu, per_cu->cu->language)) + load_full_type_unit (sig_cu); + VEC_safe_push (dwarf2_per_cu_ptr, per_cu->imported_symtabs, sig_cu); + } + + return 1; +} + +/* Queue all TUs contained in the DWO of PER_CU to be read in. + The DWO may have the only definition of the type, though it may not be + referenced anywhere in PER_CU. Thus we have to load *all* its TUs. + http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */ + +static void +queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu) +{ + struct dwo_unit *dwo_unit; + struct dwo_file *dwo_file; + + gdb_assert (!per_cu->is_debug_types); + gdb_assert (get_dwp_file () == NULL); + gdb_assert (per_cu->cu != NULL); + + dwo_unit = per_cu->cu->dwo_unit; + gdb_assert (dwo_unit != NULL); + + dwo_file = dwo_unit->dwo_file; + if (dwo_file->tus != NULL) + htab_traverse_noresize (dwo_file->tus, queue_and_load_dwo_tu, per_cu); +} + /* Free all resources associated with DWO_FILE. Close the DWO file and munmap the sections. All memory should be on the objfile obstack. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 62d26d2c610..cfa5590475b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,4 +1,10 @@ -2013-09-13 Muhammad Bilal +2013-09-04 Doug Evans + + * gdb.base/enumval.c (ZERO): New enum value. + (main): Use it + * gdb.base/enumval.exp: Test ability to print ZERO. + +2013-09-03 Muhammad Bilal Pedro Alves * gdb.base/relocate.exp: Check that invalid options are diff --git a/gdb/testsuite/gdb.base/enumval.c b/gdb/testsuite/gdb.base/enumval.c index 13e081abce7..44d4fd0644b 100644 --- a/gdb/testsuite/gdb.base/enumval.c +++ b/gdb/testsuite/gdb.base/enumval.c @@ -17,6 +17,8 @@ enum e { I, J = 0xffffffffU, K = 0xf000000000000000ULL } e = J, f = K; +enum { ZERO }; + void dummy() { @@ -26,5 +28,5 @@ int main(void) { dummy(); - return 0; + return ZERO; /* This is here to ensure it survives into the debug info. */ } diff --git a/gdb/testsuite/gdb.base/enumval.exp b/gdb/testsuite/gdb.base/enumval.exp index e0964fc8895..93e675283d9 100644 --- a/gdb/testsuite/gdb.base/enumval.exp +++ b/gdb/testsuite/gdb.base/enumval.exp @@ -70,3 +70,9 @@ gdb_test_multiple $test $test { } } } + +# gold/15021 +# With -fdebug-types-section, Gold's .gdb_index entry for ZERO refers to the +# CU, but the CU doesn't use the TU (type unit) that defines ZERO. +# Thus gdb has to read in every TU for the CU. +gdb_test "p ZERO" "ZERO" -- 2.30.2