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)

Reply via email to