https://sourceware.org/bugzilla/show_bug.cgi?id=34366

            Bug ID: 34366
           Summary: readelf: spurious "Hole and overlap detection" warning
                    for DW_LLE_startx_endx/startx_length loclists with
                    DW_AT_GNU_locviews
           Product: binutils
           Version: 2.46
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: kamil.bucki at nokia dot com
  Target Milestone: ---

Created attachment 16823
  --> https://sourceware.org/bugzilla/attachment.cgi?id=16823&action=edit
gas-only reproducer (locview-startx.s + build/reproduce scripts)

SUMMARY
=======
When readelf/objdump dumps a DWARF 5 .debug_loclists location list that uses
an indexed bounded entry -- DW_LLE_startx_endx (0x02) or DW_LLE_startx_length
(0x03) -- and the variable also has a GNU location-view list
(DW_AT_GNU_locviews), a spurious warning is printed:
    readelf: Warning: Hole and overlap detection requires adjacent view lists
and loclists.
The DWARF is well-formed; this is a false positive. The range is printed
WITHOUT its "views at ... for:" annotation (unlike offset_pair / start_end /
start_length entries), and the preceding view pair is left unread, so the
adjacency heuristic at the end of the per-list loop reports a view/loclist
mismatch.


ROOT CAUSE
==========
In display_loclists_list (binutils/dwarf.c, ~line 8177), the block that reads
and attaches the location-view pair is guarded by a whitelist of entry kinds
that only lists DW_LLE_offset_pair, DW_LLE_start_end and DW_LLE_start_length --
even though the switch in the same function already decodes DW_LLE_startx_endx
and DW_LLE_startx_length as bounded ranges (since PR 28981):
    /* binutils/dwarf.c, display_loclists_list() */
    if (vstart && (llet == DW_LLE_offset_pair
                   || llet == DW_LLE_start_end
                   || llet == DW_LLE_start_length))
      {
        off = offset + (vstart - *start_ptr);
        ...
      }
Because DW_LLE_startx_endx / DW_LLE_startx_length are not in this guard, their
view pair is never consumed nor printed, and the adjacency heuristic at the end
of the per-list loop then reports a view/loclist mismatch.
Adding the two indexed bounded forms to that guard fixes it:
    if (vstart && (llet == DW_LLE_offset_pair
                   || llet == DW_LLE_start_end
                   || llet == DW_LLE_start_length
                   || llet == DW_LLE_startx_endx
                   || llet == DW_LLE_startx_length))
This is not target specific: it reproduces on any DWARF 5 object whose producer
emits startx_* loclist entries together with location views.


REPRODUCTION
============
Minimal hand-crafted DWARF 5 reproducer assembled with gas only (no GCC,
no BOLT). One DW_LLE_startx_endx entry plus a DW_AT_GNU_locviews view list.
    as -o locview-startx.o locview-startx.s
    readelf --debug-dump=loc locview-startx.o


OBSERVED (before fix, readelf 2.46)
===================================
A standalone view pair at 0x0c, followed by a startx_endx range at 0x0e with
NO "views at" annotation, then the warning:
    Contents of the .debug_loclists section:
    Table at Offset 0
      Length:          0x10
      DWARF version:   5
      Address size:    4
      Segment size:    0
      Offset entries:  0
        Offset   Begin            End              Expression
        0000000c v0000000 v0000000 location view pair
        0000000e 00000000 00000000 (DW_OP_reg1 (rdx)) (start == end)
        00000013 <End of list>
    readelf: Warning: Hole and overlap detection requires adjacent view lists
and loclists.


EXPECTED (after the attached patch)
===================================
The view pair is attached and no warning is printed:
    0000000c v0000000 v0000000 location view pair
    0000000e v0000000 v0000000 views at 0000000c for:
             00000000 00000000 (DW_OP_reg1 (rdx))
    00000013 <End of list>


PATCH
=====
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -8177,7 +8177,9 @@ display_loclists_list (struct dwarf_section *  section,

       if (vstart && (llet == DW_LLE_offset_pair
                     || llet == DW_LLE_start_end
-                    || llet == DW_LLE_start_length))
+                    || llet == DW_LLE_start_length
+                    || llet == DW_LLE_startx_endx
+                    || llet == DW_LLE_startx_length))
        {
          off = offset + (vstart - *start_ptr);


VERSIONS AFFECTED
=================
- Released readelf 2.46 prints the warning on the attached reproducer.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to