Die symbols are used for external references. Typically during LTO, early debug emits 'die_symbol+offset' for each possibly referenced DIE in future. Partitions in LTRANS phase then use these references.
Originally die symbols are handled only in root comp_unit and in attributes. This patch allows die symbols to be attached to any DIE. References then choose closest parent with die symbol. gcc/ChangeLog: * dwarf2out.cc (dwarf2out_die_ref_for_decl): Choose closest parent with die_symbol. (output_die): Output asm label. (output_unit_die_symbol_list): New. (output_comp_unit): Output die_symbol list. (reset_dies): Reset all die_symbols. (dwarf2out_finish): Don't reset comp_unit die_symbol. --- gcc/dwarf2out.cc | 80 +++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index e10a5c78fe9..bf1ac45ed73 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -6039,14 +6039,14 @@ dwarf2out_die_ref_for_decl (tree decl, const char **sym, /* Similar to get_ref_die_offset_label, but using the "correct" label. */ - *off = die->die_offset; - while (die->die_parent) + unsigned HOST_WIDE_INT unit_offset = die->die_offset; + while (die->die_parent && (die->comdat_type_p || !die->die_id.die_symbol)) die = die->die_parent; - /* For the containing CU DIE we compute a die_symbol in + /* Root CU DIE always contains die_symbol computed in compute_comp_unit_symbol. */ - if (die->die_tag == DW_TAG_compile_unit) + if (!die->comdat_type_p && die->die_id.die_symbol) { - gcc_assert (die->die_id.die_symbol != NULL); + *off = unit_offset - die->die_offset; *sym = die->die_id.die_symbol; return true; } @@ -10798,6 +10798,10 @@ output_die (dw_die_ref die) unsigned long size; unsigned ix; + if ((flag_generate_lto || flag_generate_offload) + && !die->comdat_type_p && die->die_id.die_symbol) + ASM_OUTPUT_LABEL (asm_out_file, die->die_id.die_symbol); + dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)", (unsigned long)die->die_offset, dwarf_tag_name (die->die_tag)); @@ -11228,14 +11232,41 @@ output_compilation_unit_header (enum dwarf_unit_type ut) dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)"); } +/* Output list of all die symbols in the DIE. */ +static void +output_unit_die_symbol_list (dw_die_ref die) +{ + if (!die->comdat_type_p && die->die_id.die_symbol) + { + const char* sym = die->die_id.die_symbol; + /* ??? No way to get visibility assembled without a decl. */ + tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, + get_identifier (sym), char_type_node); + TREE_PUBLIC (decl) = true; + TREE_STATIC (decl) = true; + DECL_ARTIFICIAL (decl) = true; + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (decl) = true; + targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); +#ifdef ASM_WEAKEN_LABEL + /* We prefer a .weak because that handles duplicates from duplicate + archive members in a graceful way. */ + ASM_WEAKEN_LABEL (asm_out_file, sym); +#else + targetm.asm_out.globalize_label (asm_out_file, sym); +#endif + } + + dw_die_ref c; + FOR_EACH_CHILD (die, c, output_unit_die_symbol_list (c)); +} + /* Output the compilation unit DIE and its children. */ static void output_comp_unit (dw_die_ref die, int output_if_empty, const unsigned char *dwo_id) { - const char *oldsym; - /* Unless we are outputting main CU, we may throw away empty ones. */ if (!output_if_empty && die->die_child == NULL) return; @@ -11267,34 +11298,12 @@ output_comp_unit (dw_die_ref die, int output_if_empty, : DWARF_COMPILE_UNIT_HEADER_SIZE); calc_die_sizes (die); - oldsym = die->die_id.die_symbol; - switch_to_section (debug_info_section); ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label); info_section_emitted = true; - /* For LTO cross unit DIE refs we want a symbol on the start of the - debuginfo section, not on the CU DIE. */ - if ((flag_generate_lto || flag_generate_offload) && oldsym) - { - /* ??? No way to get visibility assembled without a decl. */ - tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, - get_identifier (oldsym), char_type_node); - TREE_PUBLIC (decl) = true; - TREE_STATIC (decl) = true; - DECL_ARTIFICIAL (decl) = true; - DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; - DECL_VISIBILITY_SPECIFIED (decl) = true; - targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); -#ifdef ASM_WEAKEN_LABEL - /* We prefer a .weak because that handles duplicates from duplicate - archive members in a graceful way. */ - ASM_WEAKEN_LABEL (asm_out_file, oldsym); -#else - targetm.asm_out.globalize_label (asm_out_file, oldsym); -#endif - ASM_OUTPUT_LABEL (asm_out_file, oldsym); - } + if (flag_generate_lto || flag_generate_offload) + output_unit_die_symbol_list (die); /* Output debugging information. */ output_compilation_unit_header (dwo_id @@ -11309,7 +11318,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty, /* Leave the marks on the main CU, so we can check them in output_pubnames. */ - if (oldsym) + if (die->die_id.die_symbol) unmark_dies (die); } @@ -32297,6 +32306,10 @@ reset_dies (dw_die_ref die) die->die_abbrev = 0; remove_AT (die, DW_AT_sibling); + /* Reset die symbols so we don't output them twice. */ + if (!die->comdat_type_p) + die->die_id.die_symbol = NULL; + FOR_EACH_CHILD (die, c, reset_dies (c)); } @@ -32388,9 +32401,6 @@ dwarf2out_finish (const char *filename) reset_dies (ctnode->root_die); } - /* Reset die CU symbol so we don't output it twice. */ - comp_unit_die ()->die_id.die_symbol = NULL; - /* Remove DW_AT_macro and DW_AT_stmt_list from the early output. */ remove_AT (comp_unit_die (), DW_AT_stmt_list); if (have_macinfo) -- 2.47.0