@@ -114,21 +114,68 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
114
114
if err != nil {
115
115
return "" , 0 , nil
116
116
}
117
- fileID := gosym . PCValue ( pcfile , pc - uint64 (s .Data .Offset ), arch . MinLC )
117
+ fileID := int ( pcValue ( pcfile , pc - uint64 (s .Data .Offset ), arch ) )
118
118
fileName := s .Func .File [fileID ]
119
119
pcline := make ([]byte , s .Func .PCLine .Size )
120
120
_ , err = f .f .ReadAt (pcline , s .Func .PCLine .Offset )
121
121
if err != nil {
122
122
return "" , 0 , nil
123
123
}
124
- line := gosym . PCValue ( pcline , pc - uint64 (s .Data .Offset ), arch . MinLC )
124
+ line := int ( pcValue ( pcline , pc - uint64 (s .Data .Offset ), arch ) )
125
125
// Note: we provide only the name in the Func structure.
126
126
// We could provide more if needed.
127
127
return fileName , line , & gosym.Func {Sym : & gosym.Sym {Name : s .Name }}
128
128
}
129
129
return "" , 0 , nil
130
130
}
131
131
132
+ // pcValue looks up the given PC in a pc value table. target is the
133
+ // offset of the pc from the entry point.
134
+ func pcValue (tab []byte , target uint64 , arch * sys.Arch ) int32 {
135
+ val := int32 (- 1 )
136
+ var pc uint64
137
+ for step (& tab , & pc , & val , pc == 0 , arch ) {
138
+ if target < pc {
139
+ return val
140
+ }
141
+ }
142
+ return - 1
143
+ }
144
+
145
+ // step advances to the next pc, value pair in the encoded table.
146
+ func step (p * []byte , pc * uint64 , val * int32 , first bool , arch * sys.Arch ) bool {
147
+ uvdelta := readvarint (p )
148
+ if uvdelta == 0 && ! first {
149
+ return false
150
+ }
151
+ if uvdelta & 1 != 0 {
152
+ uvdelta = ^ (uvdelta >> 1 )
153
+ } else {
154
+ uvdelta >>= 1
155
+ }
156
+ vdelta := int32 (uvdelta )
157
+ pcdelta := readvarint (p ) * uint32 (arch .MinLC )
158
+ * pc += uint64 (pcdelta )
159
+ * val += vdelta
160
+ return true
161
+ }
162
+
163
+ // readvarint reads, removes, and returns a varint from *p.
164
+ func readvarint (p * []byte ) uint32 {
165
+ var v , shift uint32
166
+ s := * p
167
+ for shift = 0 ; ; shift += 7 {
168
+ b := s [0 ]
169
+ s = s [1 :]
170
+ v |= (uint32 (b ) & 0x7F ) << shift
171
+ if b & 0x80 == 0 {
172
+ break
173
+ }
174
+ }
175
+ * p = s
176
+ return v
177
+ }
178
+
132
179
// We treat the whole object file as the text section.
133
180
func (f * goobjFile ) text () (textStart uint64 , text []byte , err error ) {
134
181
var info os.FileInfo
0 commit comments