Hi, On Tue, 2020-09-15 at 20:40 +0200, Jakub Jelinek wrote: > Ok, here it is in patch form. > I've briefly tested it, with the older binutils I have around (no --gdwarf-N > support), with latest gas (--gdwarf-N that can be passed to as even when > compiling C/C++ etc. code and emitting .debug_line) and latest gas with > Mark's fix > reverted (--gdwarf-N support, but can only pass it to as when assembling > user .s/.S files, not when compiling C/C++ etc.). > Will bootstrap/regtest (with the older binutils) later tonight. > > 2020-09-15 Jakub Jelinek <ja...@redhat.com> > > * configure.ac (HAVE_AS_GDWARF_5_DEBUG_FLAG, > HAVE_AS_WORKING_DWARF_4_FLAG): New tests. > * gcc.c (ASM_DEBUG_DWARF_OPTION): Define. > (ASM_DEBUG_SPEC): Use ASM_DEBUG_DWARF_OPTION instead of > "--gdwarf2". Use %{cond:opt1;:opt2} style. > (ASM_DEBUG_OPTION_DWARF_OPT): Define. > (ASM_DEBUG_OPTION_SPEC): Define. > (asm_debug_option): New variable. > (asm_options): Add "%(asm_debug_option)". > (static_specs): Add asm_debug_option entry. > (static_spec_functions): Add dwarf-version-gt. > (debug_level_greater_than_spec_func): New function. > * config/darwin.h (ASM_DEBUG_OPTION_SPEC): Define. > * config/darwin9.h (ASM_DEBUG_OPTION_SPEC): Redefine. > * config.in: Regenerated. > * configure: Regenerated.
Once this is in we can more generally emit DW_FORM_line_str for filepaths in CU DIEs for the name and comp_dir attribute. There currently is a bit of a hack to do this in dwarf2out_early_finish, but that only works when the assembler doesn't emit a DWARF5 .debug_line, but gcc does it itself. What do you think of the attached patch?
From c31667db57de62c3107a0b2a5e30fbd57a4708a3 Mon Sep 17 00:00:00 2001 From: Mark Wielaard <m...@klomp.org> Date: Fri, 18 Sep 2020 17:07:03 +0200 Subject: [PATCH] Output filepath strings in .debug_line_str for DWARF5 DWARF5 has a new string table specially for file paths. .debug_line file and dir tables reference strings in .debug_line_str. If a .debug_line_str section is emitted then also place CU DIE file names and comp dirs there. gcc/ChangeLog: * dwarf2out.c (add_filepath_AT_string): New function. (asm_outputs_debug_line_str): Likewise. (add_filename_attribute): Likewise. (add_comp_dir_attribute): Call add_filepath_AT_string. (gen_compile_unit_die): Call add_filename_attribute for name. (init_sections_and_labels): Init debug_line_str_section when asm_outputs_debug_line_str return true. (dwarf2out_early_finish): Remove DW_AT_name and DW_AT_comp_dir hack and call add_filename_attribute for the remap_debug_filename. --- gcc/dwarf2out.c | 96 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4096c0c0d69f..a43082864a75 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3347,6 +3347,8 @@ output_asm_line_debug_info (void) || !debug_variable_location_views)); } +static bool asm_outputs_debug_line_str (void); + /* Minimum line offset in a special line info. opcode. This value was chosen to give a reasonable range of values. */ #define DWARF_LINE_BASE -10 @@ -4731,6 +4733,33 @@ reset_indirect_string (indirect_string_node **h, void *) return 1; } +static inline void +add_filepath_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, + const char *str) +{ + if (! asm_outputs_debug_line_str ()) + add_AT_string (die, attr_kind, str); + else + { + dw_attr_node attr; + struct indirect_string_node *node; + + if (!debug_line_str_hash) + debug_line_str_hash + = hash_table<indirect_string_hasher>::create_ggc (10); + + node = find_AT_string_in_table (str, debug_line_str_hash); + set_indirect_string (node); + node->form = DW_FORM_line_strp; + + attr.dw_attr = attr_kind; + attr.dw_attr_val.val_class = dw_val_class_str; + attr.dw_attr_val.val_entry = NULL; + attr.dw_attr_val.v.val_str = node; + add_dwarf_attr (die, &attr); + } +} + /* Find out whether a string should be output inline in DIE or out-of-line in .debug_str section. */ @@ -11839,6 +11868,29 @@ output_ranges (void) for -gsplit-dwarf we should use DW_FORM_strx instead. */ \ && !dwarf_split_debug_info) + +/* Returns TRUE if we are outputting DWARF5 and the assembler supports + DWARF5 .debug_line tables using .debug_line_str or we generate + it ourselves, except for split-dwarf which doesn't have a + .debug_line_str. */ +static bool +asm_outputs_debug_line_str (void) +{ + if (dwarf_version >= 5 + && ! output_asm_line_debug_info () + && DWARF5_USE_DEBUG_LINE_STR) + return true; + else + { +#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_4_FLAG) + return !dwarf_split_debug_info && dwarf_version >= 5; +#else + return false; +#endif + } +} + + /* Assign .debug_rnglists indexes. */ static void @@ -20514,6 +20566,13 @@ add_name_attribute (dw_die_ref die, const char *name_string) } } +static void +add_filename_attribute (dw_die_ref die, const char *name_string) +{ + if (name_string != NULL && *name_string != 0) + add_filepath_AT_string (die, DW_AT_name, name_string); +} + /* Generate a DW_AT_description attribute given some string value to be included as the value of the attribute. */ @@ -20640,7 +20699,7 @@ add_comp_dir_attribute (dw_die_ref die) { const char * wd = comp_dir_string (); if (wd != NULL) - add_AT_string (die, DW_AT_comp_dir, wd); + add_filepath_AT_string (die, DW_AT_comp_dir, wd); } /* Given a tree node VALUE describing a scalar attribute ATTR (i.e. a bound, a @@ -24482,7 +24541,7 @@ gen_compile_unit_die (const char *filename) if (filename) { - add_name_attribute (die, filename); + add_filename_attribute (die, filename); /* Don't add cwd for <built-in>. */ if (filename[0] != '<') add_comp_dir_attribute (die); @@ -28733,7 +28792,8 @@ init_sections_and_labels (bool early_lto_debug) SECTION_DEBUG, NULL); debug_str_section = get_section (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS, NULL); - if (!dwarf_split_debug_info && !output_asm_line_debug_info ()) + if ((!dwarf_split_debug_info && !output_asm_line_debug_info ()) + || asm_outputs_debug_line_str ()) debug_line_str_section = get_section (DEBUG_LINE_STR_SECTION, DEBUG_STR_SECTION_FLAGS, NULL); @@ -32020,37 +32080,9 @@ dwarf2out_early_finish (const char *filename) /* Add the name for the main input file now. We delayed this from dwarf2out_init to avoid complications with PCH. */ - add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); + add_filename_attribute (comp_unit_die (), remap_debug_filename (filename)); add_comp_dir_attribute (comp_unit_die ()); - /* When emitting DWARF5 .debug_line_str, move DW_AT_name and - DW_AT_comp_dir into .debug_line_str section. */ - if (!output_asm_line_debug_info () - && dwarf_version >= 5 - && DWARF5_USE_DEBUG_LINE_STR) - { - for (int i = 0; i < 2; i++) - { - dw_attr_node *a = get_AT (comp_unit_die (), - i ? DW_AT_comp_dir : DW_AT_name); - if (a == NULL - || AT_class (a) != dw_val_class_str - || strlen (AT_string (a)) + 1 <= DWARF_OFFSET_SIZE) - continue; - - if (! debug_line_str_hash) - debug_line_str_hash - = hash_table<indirect_string_hasher>::create_ggc (10); - - struct indirect_string_node *node - = find_AT_string_in_table (AT_string (a), debug_line_str_hash); - set_indirect_string (node); - node->form = DW_FORM_line_strp; - a->dw_attr_val.v.val_str->refcount--; - a->dw_attr_val.v.val_str = node; - } - } - /* With LTO early dwarf was really finished at compile-time, so make sure to adjust the phase after annotating the LTRANS CU DIE. */ if (in_lto_p) -- 2.18.4