diff mbox series

Fix -gdwarf-5 -gsplit-dwarf ICEs (PR debug/89498)

Message ID 20190304223550.GS7611@tucnak
State New
Headers show
Series Fix -gdwarf-5 -gsplit-dwarf ICEs (PR debug/89498) | expand

Commit Message

Jakub Jelinek March 4, 2019, 10:35 p.m. UTC
Hi!

output_view_list_offset does:
  if (dwarf_split_debug_info)
    dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label,
                          "%s", dwarf_attr_name (a->dw_attr));
  else
    dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
                           "%s", dwarf_attr_name (a->dw_attr));
while output_loc_list_offset does:
  if (!dwarf_split_debug_info)
    dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
                           "%s", dwarf_attr_name (a->dw_attr));
  else if (dwarf_version >= 5)
    {
      gcc_assert (AT_loc_list (a)->num_assigned);
      dw2_asm_output_data_uleb128 (AT_loc_list (a)->hash, "%s (%s)",
                                   dwarf_attr_name (a->dw_attr),
                                   sym);
    }
  else
    dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label,
                          "%s", dwarf_attr_name (a->dw_attr));
but both size_of_die and value_format handle both the same as loc_list,
so for -gdwarf-5 -gsplit-dwarf we just ICE, as e.g. AT_loc_list is not
valid on a view list.

Assuming output_view_list_offset is correct, the following patch adjusts
size_of_die/value_format accordingly.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-03-04  Jakub Jelinek  <jakub@redhat.com>

	PR debug/89498
	* dwarf2out.c (size_of_die): For dw_val_class_view_list always use
	DWARF_OFFSET_SIZE.
	(value_format): For dw_val_class_view_list never use DW_FORM_loclistx.


	Jakub

Comments

Jason Merrill March 5, 2019, 9:06 p.m. UTC | #1
On 3/4/19 5:35 PM, Jakub Jelinek wrote:
> Hi!
> 
> output_view_list_offset does:
>    if (dwarf_split_debug_info)
>      dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label,
>                            "%s", dwarf_attr_name (a->dw_attr));
>    else
>      dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
>                             "%s", dwarf_attr_name (a->dw_attr));
> while output_loc_list_offset does:
>    if (!dwarf_split_debug_info)
>      dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
>                             "%s", dwarf_attr_name (a->dw_attr));
>    else if (dwarf_version >= 5)
>      {
>        gcc_assert (AT_loc_list (a)->num_assigned);
>        dw2_asm_output_data_uleb128 (AT_loc_list (a)->hash, "%s (%s)",
>                                     dwarf_attr_name (a->dw_attr),
>                                     sym);
>      }
>    else
>      dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label,
>                            "%s", dwarf_attr_name (a->dw_attr));
> but both size_of_die and value_format handle both the same as loc_list,
> so for -gdwarf-5 -gsplit-dwarf we just ICE, as e.g. AT_loc_list is not
> valid on a view list.
> 
> Assuming output_view_list_offset is correct, the following patch adjusts
> size_of_die/value_format accordingly.

I would guess that omitting the handling from output_view_list_offset 
was an oversight in the view work.  Alex, which is right? :)

Jason
Jakub Jelinek March 6, 2019, 10:04 p.m. UTC | #2
On Tue, Mar 05, 2019 at 04:06:59PM -0500, Jason Merrill wrote:
> > Assuming output_view_list_offset is correct, the following patch adjusts
> > size_of_die/value_format accordingly.
> 
> I would guess that omitting the handling from output_view_list_offset was an
> oversight in the view work.  Alex, which is right? :)

I had further look today.  Alex has added multiple modes, with
-gvariable-location-views=incompat5 the location view stuff is emitted
directly into the .debug_loclist section as part of the sequence, like:
        .uleb128 0      # DW_AT_location (*.LLST0)
...
        .section        .debug_loclists.dwo,"e",@progbits
        .long   .Ldebug_loc3-.Ldebug_loc2       # Length of Location Lists
.Ldebug_loc2:
        .value  0x5     # DWARF version number
        .byte   0x8     # Address Size
        .byte   0       # Segment Size
        .long   0x3     # Offset Entry Count
.Ldebug_loc0:
        .long   .LLST0-.Ldebug_loc0
        .long   .LLST1-.Ldebug_loc0
        .long   .LLST2-.Ldebug_loc0
.LLST0:
        .byte   0x9     # DW_LLE_view_pair
        .uleb128 0      # Location view begin
        .uleb128 .LVU6  # Location view end
        .byte   0x3     # DW_LLE_startx_length (*.LLST0)
        .uleb128 0x2    # Location list range start index (*.LVL0)
        .uleb128 .LVL1-.LVL0    # Location list length (*.LLST0)
        .uleb128 0x1    # Location expression size
        .byte   0x61    # DW_OP_reg17
...
        .byte   0       # DW_LLE_end_of_list (*.LLST0)
and in this case we don't ICE, the DW_AT_GNU_locviews attributes aren't
emitted at all.
With just -gvariable-location-views -gdwarf-5 -gsplit-dwarf (and the patch
I've posted so that it doesn't ICE):
        .uleb128 0      # DW_AT_location (*.LLST0)
        .long   .LVUS0-.Ldebug_loc0     # DW_AT_GNU_locviews
...
        .section        .debug_loclists.dwo,"e",@progbits
        .long   .Ldebug_loc3-.Ldebug_loc2       # Length of Location Lists
.Ldebug_loc2:
        .value  0x5     # DWARF version number
        .byte   0x8     # Address Size
        .byte   0       # Segment Size
        .long   0x3     # Offset Entry Count
.Ldebug_loc0:
        .long   .LLST0-.Ldebug_loc0
        .long   .LLST1-.Ldebug_loc0
        .long   .LLST2-.Ldebug_loc0
.LVUS0:
        .uleb128 0      # View list begin (*.LVUS0)
        .uleb128 .LVU6  # View list end (*.LVUS0)
        .uleb128 .LVU6  # View list begin (*.LVUS0)
        .uleb128 0      # View list end (*.LVUS0)
.LLST0:
        .byte   0x3     # DW_LLE_startx_length (*.LLST0)
        .uleb128 0x2    # Location list range start index (*.LVL0)
        .uleb128 .LVL1-.LVL0    # Location list length (*.LLST0)
        .uleb128 0x1    # Location expression size
        .byte   0x61    # DW_OP_reg17
        .byte   0x3     # DW_LLE_startx_length (*.LLST0)
        .uleb128 0      # Location list range start index (*.LVL1)
        .uleb128 .LFE0-.LVL1    # Location list length (*.LLST0)
        .uleb128 0x6    # Location expression size
        .byte   0xa3    # DW_OP_entry_value
        .uleb128 0x3
        .byte   0xa5    # DW_OP_regval_type
        .uleb128 0x11
        .uleb128 0x19
        .byte   0x9f    # DW_OP_stack_value
        .byte   0       # DW_LLE_end_of_list (*.LLST0)
In order to use DW_FORM_loclistx .uleb128 for the DW_AT_GNU_locviews,
we'd need to emit .long	.LVUS0-.Ldebug_loc0 etc. next to the
.LLST0-.Ldebug_loc0 in the section offsets table at .Ldebug_loc0,
but I'd expect debug info consumers to assume that anything listed
in the offset table is actually a valid DW_LLE_* sequence, which is not the
case for the .LVUS* labels.

Note the
        .long   .LVUS0-.Ldebug_loc0     # DW_AT_GNU_locviews
looks weird, at least with the patch it is given DW_FORM_sec_offset, but
because it is a difference between .LVUS0-.Ldebug_loc0, it is actually not a
sec offset.  Shall it use a different form in that case?

Alex?

	Jakub
Alexandre Oliva March 9, 2019, 6:12 a.m. UTC | #3
On Mar  6, 2019, Jakub Jelinek <jakub@redhat.com> wrote:

> On Tue, Mar 05, 2019 at 04:06:59PM -0500, Jason Merrill wrote:
>> > Assuming output_view_list_offset is correct, the following patch adjusts
>> > size_of_die/value_format accordingly.
>> 
>> I would guess that omitting the handling from output_view_list_offset was an
>> oversight in the view work.  Alex, which is right? :)

I guess both are :-)

I don't recall having dealt with this particular combination of flags.
Indeed, I'm pretty sure I wrote the bulk of the locview output support
before DWARFv5 support was there, and AFAICT I failed to pick up the
more compact DWARFv5 representation as I updated the patchset, proposed
the locview extension for DWARFv6 in line with DWARFv5 locviews, and
implemented it as the incompatv5 extension for v5 loclists with locviews
that Jakub noticed.

> In order to use DW_FORM_loclistx .uleb128 for the DW_AT_GNU_locviews,
> we'd need to emit .long	.LVUS0-.Ldebug_loc0 etc. next to the
> .LLST0-.Ldebug_loc0 in the section offsets table at .Ldebug_loc0,
> but I'd expect debug info consumers to assume that anything listed
> in the offset table is actually a valid DW_LLE_* sequence, which is not the
> case for the .LVUS* labels.

*nod*

> Note the
>         .long   .LVUS0-.Ldebug_loc0     # DW_AT_GNU_locviews
> looks weird, at least with the patch it is given DW_FORM_sec_offset, but
> because it is a difference between .LVUS0-.Ldebug_loc0, it is actually not a
> sec offset.  Shall it use a different form in that case?

Ugh.  That's more fallout from the concurrent implementations of v5 and
LVU, ISTM.  My bad for not catching, no doubt, since LVU landed later; I
don't mean to excuse it, just to explain how it came about.


I'm afraid I hadn't thought of it to the point of saying what would be
correct, let alone more desirable.  We're in non-strict dwarf territory,
trying to extend something that was not designed to be extended.
Unfortunately, the extensions designed for v4 do not work for v5, and
the extensions proposed for v6 don't either, so we're in a bit of a
limbo, so I guess anything that makes sense and doesn't break
unsuspecting consumers will do.


I'm thinking the most reasonable way forward in this non-standard
minefield is to document that the section base address used for
DW_AT_GNU_locviews is the same base address used for the corresponding
loclistx table.  That would make it trivially correct for v4-, and
not-so-trivially correct, but mostly sensible IMHO, for v5.

I'd argue there are even backward-compatibility reasons to document it
that way, since it is not hard to figure out that this was (by inaction)
the intent in the, erhm, reference implementation, even though, as you
noticed, it didn't work for split v5.  Of course, since it was broken,
it wouldn't be unreasonable to disregard backward compatibility
altogether and go for something entirely different; I don't know of any
other implementations that might have been based on this accidental
implementation detail, and I'd assume that if anyone even noticed the
problem while collecting data from the reference implementation, we'd
have got a bug report about it shortly thereafter.


Another possibility of encoding that comes to mind would be to output an
offset between the LLST and the LVUS labels as DW_AT_GNU_locviews, but
since it's not a compile-time constant, we won't want to make it
uleb128.  It would still be resolved to a constant and avoid
relocations, as preferred by split-dwarf, but it wouldn't save space or
relocations WRT what we'd get after your corrective patch.

Yet another, more far-out possibilities, are to introduce a list of
locview offsets right after the end of the loclist offsets, or even a
separate section with a separate section header for them, so that we
could use uleb128 compiler-computed indices to reference locview
extensions to loclists.  That would be a significant amount of work for
little to no benefit AFAICT, and only on the short term.  In the long
term, I expect/hope some way to represent locviews to be adopted in
standard DWARF.
Jakub Jelinek March 9, 2019, 7:36 a.m. UTC | #4
On Sat, Mar 09, 2019 at 03:12:28AM -0300, Alexandre Oliva wrote:
> Ugh.  That's more fallout from the concurrent implementations of v5 and
> LVU, ISTM.  My bad for not catching, no doubt, since LVU landed later; I
> don't mean to excuse it, just to explain how it came about.
> 
> 
> I'm afraid I hadn't thought of it to the point of saying what would be
> correct, let alone more desirable.  We're in non-strict dwarf territory,
> trying to extend something that was not designed to be extended.
> Unfortunately, the extensions designed for v4 do not work for v5, and
> the extensions proposed for v6 don't either, so we're in a bit of a
> limbo, so I guess anything that makes sense and doesn't break
> unsuspecting consumers will do.
> 
> 
> I'm thinking the most reasonable way forward in this non-standard
> minefield is to document that the section base address used for
> DW_AT_GNU_locviews is the same base address used for the corresponding
> loclistx table.  That would make it trivially correct for v4-, and
> not-so-trivially correct, but mostly sensible IMHO, for v5.
> 
> I'd argue there are even backward-compatibility reasons to document it
> that way, since it is not hard to figure out that this was (by inaction)
> the intent in the, erhm, reference implementation, even though, as you
> noticed, it didn't work for split v5.  Of course, since it was broken,
> it wouldn't be unreasonable to disregard backward compatibility
> altogether and go for something entirely different; I don't know of any
> other implementations that might have been based on this accidental
> implementation detail, and I'd assume that if anyone even noticed the
> problem while collecting data from the reference implementation, we'd
> have got a bug report about it shortly thereafter.
> 
> 
> Another possibility of encoding that comes to mind would be to output an
> offset between the LLST and the LVUS labels as DW_AT_GNU_locviews, but
> since it's not a compile-time constant, we won't want to make it
> uleb128.  It would still be resolved to a constant and avoid
> relocations, as preferred by split-dwarf, but it wouldn't save space or
> relocations WRT what we'd get after your corrective patch.
> 
> Yet another, more far-out possibilities, are to introduce a list of
> locview offsets right after the end of the loclist offsets, or even a
> separate section with a separate section header for them, so that we
> could use uleb128 compiler-computed indices to reference locview
> extensions to loclists.  That would be a significant amount of work for
> little to no benefit AFAICT, and only on the short term.  In the long
> term, I expect/hope some way to represent locviews to be adopted in
> standard DWARF.

Whatever we choose, IMHO: 1) we can't introduce new DW_FORM_*
2) we must avoid changing anything on how it was represented for the
non-split case, we've already shipped GCC 8.[123] with it
3) the consumer must be able to figure out easily according to clear rules
how to interpret the attribute and find the views.  So, either it needs
to use different form from what is used normally if it needs to be
interpreted differently, or it needs to use a different attribute,
and from that and possibly version number in .debug_info header it needs
to figure out if it should use absolute or relative offset to .debug_loc,
or absolute or relative offset to .debug_loclist, in split or non-split
case etc.  We need to look at what we emit with
-gdwarf-{2,3,4,5} {,-gsplit-dwarf}.

If we added offsets to LVU entries to the table at the start of
.debug_loclists, they shouldn't be counted towards the limit and guess some
locviews unaware consumers could be upset, because the uleb128s would be
above that limit.  If we include them in the limit, then even more consumers
would be upset because they don't find valid DW_LLE_* at those spots when
they just try to dump the .debug_loclists section without accessing
.debug_info.

	Jakub
Alexandre Oliva March 9, 2019, 9:20 a.m. UTC | #5
On Mar  9, 2019, Jakub Jelinek <jakub@redhat.com> wrote:

> Whatever we choose, IMHO: 1) we can't introduce new DW_FORM_*
> 2) we must avoid changing anything on how it was represented for the
> non-split case, we've already shipped GCC 8.[123] with it

None of the thoughts I wrote out involved any of that, so it looks like
we're in agreement.

> 3) the consumer must be able to figure out easily according to clear rules
> how to interpret the attribute and find the views.

I don't immediately see trouble there either.  DW_FORM_sec_offset has
different base addresses depending on the attribute they're used in.

My favorite suggestion is that we just define that the base address for
DW_FOR_sec_offset in split-dwarfv5 is the base address of the entries in
the loclistx index table, given by DW_AT_loclists_base.  Now I realize
this sort of amounts to introducing a new attribute class, but any
extended attribute might sort of do that already.  Anyway, maybe this
requirement makes it not such a great idea, after all.

So maybe in extended split-dwarfv5 mode, we should bite the bullet and
generate an index table for view lists, right after the index table for
loc lists, and use DW_FORM_loclistx.  That would be interpreted just as
in DW_AT_location, except that the index entry would NOT be in the range
implied by the Offset Entry Count in the loclists.dwo section header,
and it would reference a view list rather than a loclist.  Its being out
of range in an extended attribute would likely limit any surprises to
readers unaware of the DW_AT_GNU_locviews extension, especially WRT
split-dwarfv5.

> case etc.  We need to look at what we emit with
> -gdwarf-{2,3,4,5} {,-gsplit-dwarf}.

For v<5, we use DW_FORM_sec_offset for both DW_AT_location and
DW_AT_GNU_locviews, with absolute addresses for -gno-split-dwarf, and
with .Ldebug_loc0-based offsets for -gsplit-dwarf.

We use exactly the same logic for DW_AT_GNU_locviews in v5, even though
the logic for DW_AT_location changes for -gsplit-dwarf.  Given the
precedent for changing the DW_FORM_sec_offset's base address in split
compile units, I hope we can stick to it, but if you see some reason not
to do that, even for an extension, we should probably go with the
index-based indirection and DW_FORM_loclistx.
Jakub Jelinek March 9, 2019, 9:47 a.m. UTC | #6
On Sat, Mar 09, 2019 at 06:20:47AM -0300, Alexandre Oliva wrote:
> > case etc.  We need to look at what we emit with
> > -gdwarf-{2,3,4,5} {,-gsplit-dwarf}.
> 
> For v<5, we use DW_FORM_sec_offset for both DW_AT_location and
> DW_AT_GNU_locviews, with absolute addresses for -gno-split-dwarf, and
> with .Ldebug_loc0-based offsets for -gsplit-dwarf.
> 
> We use exactly the same logic for DW_AT_GNU_locviews in v5, even though
> the logic for DW_AT_location changes for -gsplit-dwarf.  Given the
> precedent for changing the DW_FORM_sec_offset's base address in split
> compile units, I hope we can stick to it, but if you see some reason not
> to do that, even for an extension, we should probably go with the
> index-based indirection and DW_FORM_loclistx.

If so, then all we need is likely my patch + some documentation change,
though not sure where exactly it should be documented, some Wiki we refer
in include/dwarf2.def, or what?

	Jakub
Alexandre Oliva March 9, 2019, 1:30 p.m. UTC | #7
On Mar  9, 2019, Jakub Jelinek <jakub@redhat.com> wrote:

> If so, then all we need is likely my patch + some documentation change,
> though not sure where exactly it should be documented, some Wiki we refer
> in include/dwarf2.def, or what?

Hmm, I was thinking of placing it next to dwarf6-sfn-lvu.txt in
https://people.redhat.com/aoliva/papers/sfn/ but there seem to be
several extensions documented in the GCC wiki, so I guess I could do
that instead, or as well.  I'll take care of it, and post back when I'm
done.
Alexandre Oliva March 12, 2019, 7:32 a.m. UTC | #8
On Mar  9, 2019, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar  9, 2019, Jakub Jelinek <jakub@redhat.com> wrote:
>> If so, then all we need is likely my patch + some documentation change,
>> though not sure where exactly it should be documented, some Wiki we refer
>> in include/dwarf2.def, or what?

> Hmm, I was thinking of placing it next to dwarf6-sfn-lvu.txt in
> https://people.redhat.com/aoliva/papers/sfn/ but there seem to be
> several extensions documented in the GCC wiki, so I guess I could do
> that instead, or as well.  I'll take care of it, and post back when I'm
> done.

Here's a draft description of the representation of locviews in DWARF up
to 5, and, while at that, of DW_AT_GNU_entry_view, to be appended to
dwarf6-sfn-lvu.txt (and possibly massaged into the wiki).

Please let me know if it's sufficiently descriptive and clear, or if you
find anything missing, wrong, unclear or otherwise improvable.  Thanks
in advance,


=============================
Extensions for DWARF v2 to v5
=============================

This section documents how location views are implemented as
extensions to earlier versions of DWARF.

View number assignment takes place in the line number table, just as
proposed above.

Attributes and Forms
--------------------

Location lists are not extensible in DWARF up to v5 in a backward
compatible way.  Thus, augmenting them with view lists relies on a
separate optional attribute:

  DW_AT_GNU_locviews | 0x2137

This attribute should only be present in a DIE that has a
DW_AT_location attribute that references a location list, rather than
a single location.  If this attribute is omitted, the view numbers
associated with any implied or explicit location ranges in the
location are to be taken as zero.

Locviews lists, referenced by DW_AT_GNU_locviews attributes, are to be
placed in the same section as the location lists.

When location lists are referenced in DW_AT_location attributes by an
absolute address in DW_FORM_sec_offset, the corresponding
DW_AT_GNU_locviews attribute can be a DW_FORM_sec_offset with an
absolute address as well.

When generating split (extension to) DWARF up to v4, DW_AT_location is
represented with an offset from the base address in the beginning of
the .debug_loc.dwo section, in DW_FORM_sec_offset.  DW_AT_GNU_locviews
should then be an offset from the same base address, also in
DW_FORM_sec_offset.

When generating split DWARF v5, DW_AT_location is given in
DW_FORM_loclistx, an offset, from the base address after the
.debug_loclists section header, that in turn holds the offset, from
the same base address, of the beginning of the actual location list.
DW_AT_GNU_locviews attributes that augment such location lists shall
use a DW_FORM_sec_offset value, to be interpreted as an offset from
the same base address, rather than from the beginning of the
.debug_loclists section.

For split DWARF v5, it is not recommended for DW_AT_GNU_locviews to
use DW_FORM_loclistx.  Having entries in the loclists index table
referencing locviews rather than loclists might surprise some
consumers, and using out-of-range indirect addresses instead of index
table entries might also surprise them for out-of-range indexing of
the table and for not ultimately referencing a location list.



Separate Locviews lists
-----------------------

The locviews list is represented as a sequence of pairs of uleb128
numbers, each pair corresponding to an address range in the location
list, i.e. not including the terminator, in DWARF up to v4, and only
bounded location descriptions in DWARF v5.  The view numbers are
assigned to address ranges in the order they appear.

Where a proposed DWARFv6 combined location+view list could be
represented as:

  DW_LLE_base_address base-address
  DW_LLE_view_pair V1, V2
  DW_LLE_start_end A1, A2, location-expression
  DW_LLE_start_end A3, A4, location-epxression
  DW_LLE_view_pair V5, V6
  DW_LLE_start_length A5, L6, location-expression
  DW_LLE_default location-expression
  DW_LLE_end_of_list

... the locview list output separately for DWARF up to v5 would be:

  V1, V2, 0, 0, V5, V6

for a DWARFv5 location list like the v6 one above, minus the
DW_LLE_view_pair entries.  The view pair for A3 and A4, that could be
omitted in the combined v6 list, has to be explicitly put in up to v5,
because for each bounded location description, there must be a pair of
corresponding view numbers to be matched to the pair of addresses
given by it.

Up to DWARFv4, the location list matching the locview list above would
look as follows:

  -1, base-address
  A1, A2 location-expression
  A3, A4 location-expression
  A5, A5+L6 location-expression
  (the default expression cannot be represented)
  0, 0


========================
Inlined Entry Point View
========================

Optimizing subprograms into which a subroutine was inlined, the entry
point of an inlined subroutine may be at an address associated with
other views, in the enclosing subprogram, in the inlined subroutine,
or even in other inlined subroutines.

It may thus be useful to indicate which of the views associated with
the entry point address logically corresponds to the view in which
execution of the inlined subprogram begins, so that, when a
breakpoint is set at the entry point, a debugger knows to advance to
the entry point view: locations for the parameters are not expected to
be bound in earlier views.

The view number for the entry of the inlined subroutine can be named
in the DW_TAG_inlined_subroutine DIE, along with the DW_AT_entry_point
attribute or other means that specify the entry point.

  DW_AT_GNU_entry_view | 0x2138

The view number shall be represented as an unsigned constant, using
such forms as DW_FORM_data<n>, DW_FORM_udata, or even
DW_FORM_implicit_const.

If this attribute is omitted, the entry point view number should be
taken as zero.
Jakub Jelinek March 12, 2019, 11:50 a.m. UTC | #9
On Tue, Mar 12, 2019 at 04:32:35AM -0300, Alexandre Oliva wrote:
> When location lists are referenced in DW_AT_location attributes by an
> absolute address in DW_FORM_sec_offset, the corresponding
> DW_AT_GNU_locviews attribute can be a DW_FORM_sec_offset with an
> absolute address as well.

Note, for DWARF before v4, there is no DW_FORM_sec_offset and
DW_FORM_data4 or DW_FORM_data8 depending on whether it is 32-bit or 64-bit
DWARF is used instead.
> 
> When generating split (extension to) DWARF up to v4, DW_AT_location is
> represented with an offset from the base address in the beginning of
> the .debug_loc.dwo section, in DW_FORM_sec_offset.  DW_AT_GNU_locviews
> should then be an offset from the same base address, also in
> DW_FORM_sec_offset.

Likewise here.

Otherwise LGTM.

	Jakub
Jakub Jelinek March 12, 2019, 11:51 a.m. UTC | #10
On Mon, Mar 04, 2019 at 11:35:50PM +0100, Jakub Jelinek wrote:
> 2019-03-04  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/89498
> 	* dwarf2out.c (size_of_die): For dw_val_class_view_list always use
> 	DWARF_OFFSET_SIZE.
> 	(value_format): For dw_val_class_view_list never use DW_FORM_loclistx.

Given the clarifications Alex has just posted, I believe this patch does
what is documented in there.  Ok for trunk?

	Jakub
Jason Merrill March 13, 2019, 7:55 p.m. UTC | #11
On 3/12/19 7:51 AM, Jakub Jelinek wrote:
> On Mon, Mar 04, 2019 at 11:35:50PM +0100, Jakub Jelinek wrote:
>> 2019-03-04  Jakub Jelinek  <jakub@redhat.com>
>>
>> 	PR debug/89498
>> 	* dwarf2out.c (size_of_die): For dw_val_class_view_list always use
>> 	DWARF_OFFSET_SIZE.
>> 	(value_format): For dw_val_class_view_list never use DW_FORM_loclistx.
> 
> Given the clarifications Alex has just posted, I believe this patch does
> what is documented in there.  Ok for trunk?

OK.

Jason
Alexandre Oliva March 14, 2019, 9:08 p.m. UTC | #12
On Mar 12, 2019, Jakub Jelinek <jakub@redhat.com> wrote:

> Note, for DWARF before v4, there is no DW_FORM_sec_offset and
> DW_FORM_data4 or DW_FORM_data8 depending on whether it is 32-bit or 64-bit
> DWARF is used instead.

Ah, yes, thanks.  I made these fixes, changed some dashes to underlines
in "identifiers", and uploaded it for now to the end of
https://people.redhat.com/aoliva/papers/sfn/dwarf6-sfn-lvu.txt


=============================
Extensions for DWARF v2 to v5
=============================

This section documents how location views are implemented as
extensions to earlier versions of DWARF.  Being backports of the
proposed extensions above, these were NOT submitted to the DWARF
committee.

View number assignment takes place in the line number table, just as
proposed above.

Attributes and Forms
--------------------

Location lists are not extensible in DWARF up to v5 in a backward
compatible way.  Thus, augmenting them with view lists relies on a
separate optional attribute:

  DW_AT_GNU_locviews | 0x2137

This attribute should only be present in a DIE that has a
DW_AT_location attribute that references a location list, rather than
a single location.  If this attribute is omitted, the view numbers
associated with any implied or explicit location ranges in the
location are to be taken as zero.

Locviews lists, referenced by DW_AT_GNU_locviews attributes, are to be
placed in the same section as the location lists.

When location lists are referenced in DW_AT_location attributes by an
absolute address in DW_FORM_sec_offset (DWARF v4) or DW_FORM_data<n>
(DWARF up to v3), the corresponding DW_AT_GNU_locviews attribute can
be of the same form, with an absolute address as well.

When generating split (extension to) DWARF up to v4, DW_AT_location is
represented with an offset from the base address in the beginning of
the .debug_loc.dwo section, in DW_FORM_sec_offset (DWARF v4) or
DW_FORM_data<n> (DWARF up to v3).  DW_AT_GNU_locviews should then be
an offset from the same base address, also of the same form.

When generating split DWARF v5, DW_AT_location is given in
DW_FORM_loclistx, an offset, from the base address after the
.debug_loclists section header, that in turn holds the offset, from
the same base address, of the beginning of the actual location list.
DW_AT_GNU_locviews attributes that augment such location lists shall
use a DW_FORM_sec_offset value, to be interpreted as an offset from
the same base address, rather than from the beginning of the
.debug_loclists section.

For split DWARF v5, it is not recommended for DW_AT_GNU_locviews to
use DW_FORM_loclistx.  Having entries in the loclists index table
referencing locviews rather than loclists might surprise some
consumers, and using out-of-range indirect addresses instead of index
table entries might also surprise them for out-of-range indexing of
the table and for not ultimately referencing a location list.



Separate Locviews lists
-----------------------

The locviews list is represented as a sequence of pairs of uleb128
numbers, each pair corresponding to an address range in the location
list, i.e. not including the terminator, in DWARF up to v4, and
covering only bounded location descriptions in DWARF v5.  The view
numbers pairs are matched to address ranges in the order they appear.

Where a proposed DWARFv6 combined location+view list could be
represented as:

  DW_LLE_base_address base_address
  DW_LLE_view_pair    V1, V2
  DW_LLE_start_end    A1, A2, location_expression
  DW_LLE_start_end    A3, A4, location_expression
  DW_LLE_view_pair    V5, V6
  DW_LLE_start_length A5, L6, location_expression
  DW_LLE_default      location_expression
  DW_LLE_end_of_list

... the locview list output separately for DWARF up to v5 would be:

  V1, V2, 0, 0, V5, V6

for a DWARFv5 location list like the v6 one above, minus the
DW_LLE_view_pair entries.  The view pair for A3 and A4, that could be
omitted in the combined v6 list, has to be explicitly put in up to v5,
because for each bounded location description, there must be a pair of
corresponding view numbers to be matched to the pair of addresses
given by it.

Up to DWARFv4, the location list matching the locview list above would
look as follows:

  -1, base_address
  A1, A2    location_expression
  A3, A4    location_expression
  A5, A5+L6 location_expression
  (a default expression cannot be represented)
  0, 0


========================
Inlined Entry Point View
========================

This extension proposal is yet to be submitted to the DWARF committee.

Optimizing subprograms into which a subroutine was inlined, the entry
point of an inlined subroutine may be at an address associated with
other views, in the enclosing subprogram, in the inlined subroutine,
or even in other inlined subroutines.

It may thus be useful to indicate which of the views associated with
the entry point address logically corresponds to the view in which
execution of the inlined subprogram begins, so that, when a
breakpoint is set at the entry point, a debugger knows to advance to
the entry point view: locations for the parameters are not expected to
be bound in earlier views.

The view number for the entry of the inlined subroutine can be named
in the DW_TAG_inlined_subroutine DIE, along with the DW_AT_entry_point
attribute or other means that specify the entry point.

  DW_AT_GNU_entry_view | 0x2138

The view number shall be represented as an unsigned constant, using
such forms as DW_FORM_data<n>, DW_FORM_udata, or even
DW_FORM_implicit_const.

If this attribute is omitted, the entry point view number should be
taken as zero.
diff mbox series

Patch

--- gcc/dwarf2out.c.jj	2019-03-01 09:04:15.440751912 +0100
+++ gcc/dwarf2out.c	2019-03-04 17:58:59.501542373 +0100
@@ -9351,7 +9351,6 @@  size_of_die (dw_die_ref die)
 	  }
 	  break;
 	case dw_val_class_loc_list:
-	case dw_val_class_view_list:
 	  if (dwarf_split_debug_info && dwarf_version >= 5)
 	    {
 	      gcc_assert (AT_loc_list (a)->num_assigned);
@@ -9360,6 +9359,9 @@  size_of_die (dw_die_ref die)
           else
             size += DWARF_OFFSET_SIZE;
 	  break;
+	case dw_val_class_view_list:
+	  size += DWARF_OFFSET_SIZE;
+	  break;
 	case dw_val_class_range_list:
 	  if (value_format (a) == DW_FORM_rnglistx)
 	    {
@@ -9733,12 +9735,12 @@  value_format (dw_attr_node *a)
 	  gcc_unreachable ();
 	}
     case dw_val_class_loc_list:
-    case dw_val_class_view_list:
       if (dwarf_split_debug_info
 	  && dwarf_version >= 5
 	  && AT_loc_list (a)->num_assigned)
 	return DW_FORM_loclistx;
       /* FALLTHRU */
+    case dw_val_class_view_list:
     case dw_val_class_range_list:
       /* For range lists in DWARF 5, use DW_FORM_rnglistx from .debug_info.dwo
 	 but in .debug_info use DW_FORM_sec_offset, which is shorter if we