From 955cf0873f7a1c3d54cff34164f81d2b44127c30 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 12 Mar 2025 12:05:11 -0400 Subject: [PATCH] cmd/internal/dwarf: fix bug in inlined func DIE range DWARF 5 info This patch changes the strategy we use in the compiler for handling range information for inlined subroutine bodies, fixing a bug in how this was handled for DWARF 5. The high and lo PC values being emitted for DW_TAG_inlined_subroutine DIEs were incorrect, pointing to the start of functions instead of the proper location. The fix in this patch is to move to unconditionally using DW_AT_ranges for inlined subroutines, even those with only a single range. Background: prior to this point, if a given inlined function body had a single contiguous range, we'd pick an abbrev entry for it with explicit DW_AT_low_pc and DW_AT_high_pc attributes. If the extent of the code for the inlined body was not contiguous (which can happen), we'd select an abbrev that used a DW_AT_ranges attribute instead. This strategy (preferring explicit hi/lo PC attrs for a single-range func) made sense for DWARF 4, since in DWARF 4 the representation used in the .debug_ranges section was especially heavyweight (lots of space, lots of relocations), so having explicit hi/lo PC attrs was less expensive. With DWARF 5 range info is written to the .debug_rnglists section, and the representation here is much more compact. Specifically, a single hi/lo range can be represented using a base address in addrx format (max of 4 bytes, but more likely 2 or 3) followed by start and endpoints of the range in ULEB128 format. This combination is more compact spacewise than the explicit hi/lo values, and has fewer relocations (0 as opposed to 2). Note: we should at some point consider applying this same strategy to lexical scopes, since we can probably reap some of the same benefits there as well. Updates #26379. Fixes #72821. Change-Id: Ifb65ecc6221601bad2ca3939f9b69964c1fafc7c Reviewed-on: https://go-review.googlesource.com/c/go/+/657175 Reviewed-by: Ian Lance Taylor Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI Reviewed-by: Alessandro Arzilli --- src/cmd/internal/dwarf/dwarf.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index 88dac10c1b..7673c3f6ba 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -1295,8 +1295,11 @@ func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error { ic := s.InlCalls.Calls[callIdx] callee := ic.AbsFunSym + // For DWARF 5, we always use the ranges form of the abbrev, since + // it is more compact than using explicit hi/lo PC attrs. See + // issue #72821 for more on why this makes sense. abbrev := DW_ABRV_INLINED_SUBROUTINE_RANGES - if len(ic.Ranges) == 1 { + if len(ic.Ranges) == 1 && !buildcfg.Experiment.Dwarf5 { abbrev = DW_ABRV_INLINED_SUBROUTINE } Uleb128put(ctxt, s.Info, int64(abbrev)) -- 2.50.0