mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: output DWARF lexical blocks for local variables
Change compiler and linker to emit DWARF lexical blocks in debug_info. Version of debug_info is updated from DWARF v.2 to DWARF v.3 since version 2 does not allow lexical blocks with discontinuous ranges. Second attempt at https://go-review.googlesource.com/#/c/29591/ Remaining open problems: - scope information is removed from inlined functions - variables in debug_info do not have DW_AT_start_scope attributes so a variable will shadow other variables with the same name as soon as its containing scope begins, before its declaration. Updates golang/go#12899, golang/go#6913 Change-Id: I0e260a45b564d14a87b88974eb16c5387cb410a5 Reviewed-on: https://go-review.googlesource.com/36879 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
7165bcc6ba
commit
c8b889cc48
21 changed files with 890 additions and 110 deletions
91
src/cmd/compile/internal/gc/scope.go
Normal file
91
src/cmd/compile/internal/gc/scope.go
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gc
|
||||
|
||||
import (
|
||||
"cmd/internal/dwarf"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/src"
|
||||
)
|
||||
|
||||
// findScope returns the most specific scope containing pos.
|
||||
func findScope(pos src.XPos, scopes []dwarf.Scope) int32 {
|
||||
if !pos.IsKnown() {
|
||||
return 0
|
||||
}
|
||||
for i := len(scopes) - 1; i > 0; i-- {
|
||||
if pos.After(scopes[i].Start) && pos.Before(scopes[i].End) {
|
||||
return int32(i)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type scopedProg struct {
|
||||
p *obj.Prog
|
||||
scope int32
|
||||
}
|
||||
|
||||
// scopeRanges calculates scope ranges for symbol fnsym.
|
||||
func scopeRanges(fnsym *obj.LSym, scopes []dwarf.Scope) {
|
||||
var sp []scopedProg
|
||||
|
||||
for p := fnsym.Text; p != nil; p = p.Link {
|
||||
sp = append(sp, scopedProg{p, -1})
|
||||
}
|
||||
|
||||
for scopeID := int32(len(scopes) - 1); scopeID >= 0; scopeID-- {
|
||||
if scope := &scopes[scopeID]; scope.Start.IsKnown() && scope.End.IsKnown() {
|
||||
scopeProgs(sp, scopeID, scope.Start, scope.End)
|
||||
}
|
||||
}
|
||||
|
||||
scopedProgsToRanges(sp, scopes, fnsym.Size)
|
||||
|
||||
// Propagate scope's pc ranges to parent
|
||||
for i := len(scopes) - 1; i > 0; i-- {
|
||||
cur := &scopes[i]
|
||||
if scopes[i].Parent != 0 {
|
||||
parent := &scopes[scopes[i].Parent]
|
||||
parent.UnifyRanges(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scopeProgs marks all scopedProgs between start and end that don't already
|
||||
// belong to a scope as belonging to scopeId.
|
||||
func scopeProgs(sp []scopedProg, scopeId int32, start, end src.XPos) {
|
||||
for i := range sp {
|
||||
if sp[i].scope >= 0 {
|
||||
continue
|
||||
}
|
||||
if pos := sp[i].p.Pos; pos.After(start) && pos.Before(end) {
|
||||
sp[i].scope = scopeId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scopedProgsToRanges scans sp and collects in the Ranges field of each
|
||||
// scope the start and end instruction of the scope.
|
||||
func scopedProgsToRanges(sp []scopedProg, scopes []dwarf.Scope, symSize int64) {
|
||||
var curscope int32 = -1
|
||||
for i := range sp {
|
||||
if sp[i].scope == curscope {
|
||||
continue
|
||||
}
|
||||
if curscope >= 0 {
|
||||
curranges := scopes[curscope].Ranges
|
||||
curranges[len(curranges)-1].End = sp[i].p.Pc
|
||||
}
|
||||
curscope = sp[i].scope
|
||||
if curscope >= 0 {
|
||||
scopes[curscope].Ranges = append(scopes[curscope].Ranges, dwarf.Range{Start: sp[i].p.Pc, End: -1})
|
||||
}
|
||||
}
|
||||
if curscope >= 0 {
|
||||
curranges := scopes[curscope].Ranges
|
||||
curranges[len(curranges)-1].End = symSize
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue