On Wed, 20 Jan 2021, Jakub Jelinek wrote: > Hi! > > As mentioned in the PR, with -gdwarf-5 (or -g now) -flto -ffat-lto-objects, > users can't strip the LTO sections with > strip -p -R .gnu.lto_* -R .gnu.debuglto_* -N __gnu_lto_v1 > anymore when GCC is configured against recent binutils. > > The problem is that in that case .gnu.debuglto_.debug_line_str section is > then used, which is fine for references to strings in .gnu.debuglto_.* > sections, but not when those references are in .debug_info section too; > those should really reference separate strings in .debug_line_str section. > > For .gnu.debuglto_.debug_str vs. .debug_str we handle it right, we > reset_indirect_string the strings and thus force creation of new labels for > the second time. > But for DW_FORM_line_strp as the patch shows, there were multiple problems. > First one was that reset_indirect_string, even when called through traverse > on debug_line_str_hash, didn't do anything at all (fixed by first hunk). > The second bug was that the DW_FORM_line_strp strings, which were supposed > to be only visible through debug_line_str_hash, leaked into debug_str_hash > (second hunk). > And the third thing is that when we reset debug_line_str_hash, we should > still make those strings DW_FORM_line_strp if they are accessed. > One could do it by reinstantiating DW_FORM_line_strp right away in > reset_indirect_string and not clear debug_line_str_hash, but that has the > disadvantage that we then force emitting .debug_line_str strings that aren't > really needed - we need those from the CU DIEs' DW_AT_name and > DW_AT_comp_dir attributes, but when emitting .debug_line section through > assembler, we don't need to emit the strings we only needed for > .gnu.debuglto_.debug_line which is always emitted by the compiler. > > Ok for trunk if this passes bootstrap/regtest?
OK. Thanks, Richard. > 2021-01-20 Jakub Jelinek <ja...@redhat.com> > > PR debug/98765 > * dwarf2out.c (reset_indirect_string): Also reset indirect strings > with DW_FORM_line_strp form. > (prune_unused_types_update_strings): Don't add into debug_str_hash > indirect strings with DW_FORM_line_strp form. > (adjust_name_comp_dir): New function. > (dwarf2out_finish): Call it on CU DIEs after resetting > debug_line_str_hash. > > --- gcc/dwarf2out.c.jj 2021-01-20 08:32:09.612958930 +0100 > +++ gcc/dwarf2out.c 2021-01-20 15:41:30.343417095 +0100 > @@ -4733,7 +4733,9 @@ int > reset_indirect_string (indirect_string_node **h, void *) > { > struct indirect_string_node *node = *h; > - if (node->form == DW_FORM_strp || node->form == dwarf_FORM (DW_FORM_strx)) > + if (node->form == DW_FORM_strp > + || node->form == DW_FORM_line_strp > + || node->form == dwarf_FORM (DW_FORM_strx)) > { > free (node->label); > node->label = NULL; > @@ -29477,8 +29479,9 @@ prune_unused_types_update_strings (dw_di > s->refcount++; > /* Avoid unnecessarily putting strings that are used less than > twice in the hash table. */ > - if (s->refcount > - == ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2)) > + if (s->form != DW_FORM_line_strp > + && (s->refcount > + == ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2))) > { > indirect_string_node **slot > = debug_str_hash->find_slot_with_hash (s->str, > @@ -31325,6 +31328,33 @@ reset_dies (dw_die_ref die) > FOR_EACH_CHILD (die, c, reset_dies (c)); > } > > +/* reset_indirect_string removed the references coming from DW_AT_name > + and DW_AT_comp_dir attributes on compilation unit DIEs. Readd them as > + .debug_line_str strings again. */ > + > +static void > +adjust_name_comp_dir (dw_die_ref die) > +{ > + for (int i = 0; i < 2; i++) > + { > + dwarf_attribute attr_kind = i ? DW_AT_comp_dir : DW_AT_name; > + dw_attr_node *a = get_AT (die, attr_kind); > + if (a == NULL || a->dw_attr_val.val_class != dw_val_class_str) > + 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 (a->dw_attr_val.v.val_str->str, > + debug_line_str_hash); > + set_indirect_string (node); > + node->form = DW_FORM_line_strp; > + a->dw_attr_val.v.val_str = node; > + } > +} > + > /* Output stuff that dwarf requires at the end of every file, > and generate the DWARF-2 debugging info. */ > > @@ -31398,6 +31428,12 @@ dwarf2out_finish (const char *filename) > { > debug_line_str_hash->traverse<void *, reset_indirect_string> (NULL); > debug_line_str_hash = NULL; > + if (asm_outputs_debug_line_str ()) > + { > + adjust_name_comp_dir (comp_unit_die ()); > + for (limbo_die_node *node = cu_die_list; node; node = node->next) > + adjust_name_comp_dir (node->die); > + } > } > } > > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)