From: Than McIntosh Date: Fri, 29 May 2020 20:01:08 +0000 (-0400) Subject: cmd/{compile,link}: fix problem with DWARF end_sequence ops X-Git-Tag: go1.15beta1~62 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=58f017bcea3d2f3dbb898ba175fe09beb32b4eb6;p=gostls13.git cmd/{compile,link}: fix problem with DWARF end_sequence ops During DWARF line table emission in the linker, prior to issuing a DW_LNE_end_sequence op to mark the end of the line table for a compilation unit, advance the PC to produce an address beyond the last text address in the unit (this is required by the DWARF standard). Because of the way that GDB interprets end-sequence ops, we were effectively losing the last row in the line table for each unit, which degraded the debugging experience. This problem has been around for a while, but has surfaced recently due to changes in line table generation. Prior to Go 1.14, the DWARF line table was emitted entirely in the linker, and a single monolithic line table was created for each Go package (including functions from assembly). In 1.14 we moved to having the compiler emit line table fragments for each function, and having the linker stitch together the fragments. As part of this change we moved to a model in which each "go tool compile/asm" output has its own DWARF line table instance, meaning that there are many more "end sequence" ops, which made the problem more visible. Fixes #38192. Change-Id: Ic29e2f6e0ac952360c81fcba5268ad70b2b44184 Reviewed-on: https://go-review.googlesource.com/c/go/+/235739 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements Reviewed-by: Jeremy Faller --- diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 95e6b12282..8df03d74f1 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -1264,6 +1264,18 @@ func (d *dwctxt2) writelines(unit *sym.CompilationUnit, ls loader.Sym) { } } + // Issue 38192: the DWARF standard specifies that when you issue + // an end-sequence op, the PC value should be one past the last + // text address in the translation unit, so apply a delta to the + // text address before the end sequence op. If this isn't done, + // GDB will assign a line number of zero the last row in the line + // table, which we don't want. The 1 + ptrsize amount is somewhat + // arbitrary, this is chosen to be consistent with the way LLVM + // emits its end sequence ops. + lsu.AddUint8(dwarf.DW_LNS_advance_pc) + dwarf.Uleb128put(d, lsDwsym, int64(1+d.arch.PtrSize)) + + // Emit an end-sequence at the end of the unit. lsu.AddUint8(0) // start extended opcode dwarf.Uleb128put(d, lsDwsym, 1) lsu.AddUint8(dwarf.DW_LNE_end_sequence)