1
2
3
4
5 package dwarfgen
6
7 import (
8 "sort"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/ir"
12 "cmd/internal/dwarf"
13 "cmd/internal/obj"
14 "cmd/internal/src"
15 )
16
17
18 func xposBefore(p, q src.XPos) bool {
19 return base.Ctxt.PosTable.Pos(p).Before(base.Ctxt.PosTable.Pos(q))
20 }
21
22 func findScope(marks []ir.Mark, pos src.XPos) ir.ScopeID {
23 i := sort.Search(len(marks), func(i int) bool {
24 return xposBefore(pos, marks[i].Pos)
25 })
26 if i == 0 {
27 return 0
28 }
29 return marks[i-1].Scope
30 }
31
32 func assembleScopes(fnsym *obj.LSym, fn *ir.Func, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope {
33
34 dwarfScopes := make([]dwarf.Scope, 1+len(fn.Parents))
35 for i, parent := range fn.Parents {
36 dwarfScopes[i+1].Parent = int32(parent)
37 }
38
39 scopeVariables(dwarfVars, varScopes, dwarfScopes, fnsym.ABI() != obj.ABI0)
40 if fnsym.Func().Text != nil {
41 scopePCs(fnsym, fn.Marks, dwarfScopes)
42 }
43 return compactScopes(dwarfScopes)
44 }
45
46
47 func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ir.ScopeID, dwarfScopes []dwarf.Scope, regabi bool) {
48 if regabi {
49 sort.Stable(varsByScope{dwarfVars, varScopes})
50 } else {
51 sort.Stable(varsByScopeAndOffset{dwarfVars, varScopes})
52 }
53
54 i0 := 0
55 for i := range dwarfVars {
56 if varScopes[i] == varScopes[i0] {
57 continue
58 }
59 dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:i]
60 i0 = i
61 }
62 if i0 < len(dwarfVars) {
63 dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:]
64 }
65 }
66
67
68 func scopePCs(fnsym *obj.LSym, marks []ir.Mark, dwarfScopes []dwarf.Scope) {
69
70
71 if len(marks) == 0 {
72 return
73 }
74 p0 := fnsym.Func().Text
75 scope := findScope(marks, p0.Pos)
76 for p := p0; p != nil; p = p.Link {
77 if p.Pos == p0.Pos {
78 continue
79 }
80 dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: p.Pc})
81 p0 = p
82 scope = findScope(marks, p0.Pos)
83 }
84 if p0.Pc < fnsym.Size {
85 dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: fnsym.Size})
86 }
87 }
88
89 func compactScopes(dwarfScopes []dwarf.Scope) []dwarf.Scope {
90
91 for i := len(dwarfScopes) - 1; i > 0; i-- {
92 s := &dwarfScopes[i]
93 dwarfScopes[s.Parent].UnifyRanges(s)
94 }
95
96 return dwarfScopes
97 }
98
99 type varsByScopeAndOffset struct {
100 vars []*dwarf.Var
101 scopes []ir.ScopeID
102 }
103
104 func (v varsByScopeAndOffset) Len() int {
105 return len(v.vars)
106 }
107
108 func (v varsByScopeAndOffset) Less(i, j int) bool {
109 if v.scopes[i] != v.scopes[j] {
110 return v.scopes[i] < v.scopes[j]
111 }
112 return v.vars[i].StackOffset < v.vars[j].StackOffset
113 }
114
115 func (v varsByScopeAndOffset) Swap(i, j int) {
116 v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
117 v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
118 }
119
120 type varsByScope struct {
121 vars []*dwarf.Var
122 scopes []ir.ScopeID
123 }
124
125 func (v varsByScope) Len() int {
126 return len(v.vars)
127 }
128
129 func (v varsByScope) Less(i, j int) bool {
130 return v.scopes[i] < v.scopes[j]
131 }
132
133 func (v varsByScope) Swap(i, j int) {
134 v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
135 v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
136 }
137
View as plain text