[03/14] libdw: Handle DW_AT_ranges in split DWARF 5 skeleton in dwarf_ranges

Message ID cece7abd3ff74d40c47faf924c99c36762e146af.1695837512.git.osandov@fb.com
State Committed
Headers
Series elfutils: DWARF package (.dwp) file support |

Commit Message

Omar Sandoval Sept. 27, 2023, 6:20 p.m. UTC
  From: Omar Sandoval <osandov@fb.com>

When commit 879f3a4f99df ("libdw: Handle .debug_rnglists in
dwarf_ranges.") added support for split DWARF 5 in 2018, GCC put all
range lists for split DWARF in the .debug_rnglists section of the
skeleton file (similarly to GNU DebugFission, which puts all range lists
in .debug_ranges in the skeleton file).

In 2021, after a discussion on the dwarf-discuss mailing list [1], GCC
changed this to match Clang's behavior.  Now, ranges are in
.debug_rnglists.dwo in the split file, _except_ for one: the skeleton
unit DIE has a DW_AT_ranges attribute, and its ranges are in
.debug_rnglists in the skeleton file.  See GCC commit 4b33c5aaab9e
("dwarf2out: Fix up ranges for -gdwarf-5 -gsplit-dwarf [PR99490]") and
the Issue 210310.1 clarifying the DWARF standard [2].

Unfortunately, this confuses dwarf_ranges, which always uses
.debug_rnglists.dwo if it exists.  Fix it by special casing the unit
DIE: its range lists should be in .debug_rnglists if that exists, and
.debug_rnglists.dwo otherwise.

1: https://lists.dwarfstd.org/pipermail/dwarf-discuss/2021-March/002009.html
2: https://dwarfstd.org/issues/210310.1.html

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 libdw/ChangeLog      | 2 ++
 libdw/dwarf_ranges.c | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)
  

Comments

Mark Wielaard Oct. 3, 2023, 4:10 p.m. UTC | #1
Hi Omar,

On Wed, 2023-09-27 at 11:20 -0700, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
> 
> When commit 879f3a4f99df ("libdw: Handle .debug_rnglists in
> dwarf_ranges.") added support for split DWARF 5 in 2018, GCC put all
> range lists for split DWARF in the .debug_rnglists section of the
> skeleton file (similarly to GNU DebugFission, which puts all range lists
> in .debug_ranges in the skeleton file).
> 
> In 2021, after a discussion on the dwarf-discuss mailing list [1], GCC
> changed this to match Clang's behavior.  Now, ranges are in
> .debug_rnglists.dwo in the split file, _except_ for one: the skeleton
> unit DIE has a DW_AT_ranges attribute, and its ranges are in
> .debug_rnglists in the skeleton file.  See GCC commit 4b33c5aaab9e
> ("dwarf2out: Fix up ranges for -gdwarf-5 -gsplit-dwarf [PR99490]") and
> the Issue 210310.1 clarifying the DWARF standard [2].
> 
> Unfortunately, this confuses dwarf_ranges, which always uses
> .debug_rnglists.dwo if it exists.  Fix it by special casing the unit
> DIE: its range lists should be in .debug_rnglists if that exists, and
> .debug_rnglists.dwo otherwise.
> 
> 1: https://lists.dwarfstd.org/pipermail/dwarf-discuss/2021-March/002009.html
> 2: https://dwarfstd.org/issues/210310.1.html

Thanks for all these references in the commit message.
With that the 2 line change looks good. Applied.

Thanks,

Mark
  

Patch

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index af74ce0d..e84432f6 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -2,6 +2,8 @@ 
 
 	* libdw_find_split_unit.c (try_split_file): Make static.
 	* dwarf_entrypc.c (dwarf_entrypc): Call dwarf_lowpc.
+	* dwarf_ranges.c (dwarf_ranges): Use skeleton ranges section for
+	skeleton units.
 
 2023-02-22  Mark Wielaard  <mark@klomp.org>
 
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c
index 520f9ffe..b853e4b9 100644
--- a/libdw/dwarf_ranges.c
+++ b/libdw/dwarf_ranges.c
@@ -489,10 +489,10 @@  dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
 
   size_t secidx = (cu->version < 5 ? IDX_debug_ranges : IDX_debug_rnglists);
   const Elf_Data *d = cu->dbg->sectiondata[secidx];
-  if (d == NULL && cu->unit_type == DW_UT_split_compile)
+  if (cu->unit_type == DW_UT_split_compile && (d == NULL || is_cudie (die)))
     {
       Dwarf_CU *skel = __libdw_find_split_unit (cu);
-      if (skel != NULL)
+      if (skel != NULL && skel->dbg->sectiondata[secidx] != NULL)
 	{
 	  cu = skel;
 	  d = cu->dbg->sectiondata[secidx];