Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(174)

Delta Between Two Patch Sets: src/cmd/link/pclntab.go

Issue 53820043: code review 53820043: cmd/link: pclntab generation (Closed)
Left Patch Set: diff -r 5069dab9a825 https://code.google.com/p/go/ Created 11 years, 2 months ago
Right Patch Set: diff -r 30b337011ce5 https://code.google.com/p/go/ Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/cmd/link/pclntab_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2014 The Go Authors. All rights reserved. 1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Generation of runtime function information (pclntab). 5 // Generation of runtime function information (pclntab).
6 // See runtime.go.
7 6
8 package main 7 package main
9 8
10 import ( 9 import (
11 "debug/goobj" 10 "debug/goobj"
12 "encoding/binary" 11 "encoding/binary"
13 "os" 12 "os"
14 "sort" 13 "sort"
15 ) 14 )
16 15
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } 92 }
94 93
95 // off is the offset of the table entry where we're going to wri te 94 // off is the offset of the table entry where we're going to wri te
96 // the encoded form of Func. 95 // the encoded form of Func.
97 // indexOff is the current position in the table index; 96 // indexOff is the current position in the table index;
98 // we add an entry in the index pointing at off. 97 // we add an entry in the index pointing at off.
99 off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1) 98 off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
100 indexOff = buf.Addr(indexOff, sym.SymID, 0) 99 indexOff = buf.Addr(indexOff, sym.SymID, 0)
101 indexOff = buf.Uint(indexOff, uint64(off), p.ptrsize) 100 indexOff = buf.Uint(indexOff, uint64(off), p.ptrsize)
102 101
103 » » // The Func encoding starts with a fixed size header and then 102 » » // The Func encoding starts with a header giving offsets
104 » » // variable-sized data. end gives the current write position for 103 » » // to data blobs, and then the data blobs themselves.
105 » » // the variable-sized data. 104 » » // end gives the current write position for the data blobs.
106 end := off + p.ptrsize + 3*4 + 5*4 + len(f.PCData)*4 + len(f.Fun cData)*p.ptrsize 105 end := off + p.ptrsize + 3*4 + 5*4 + len(f.PCData)*4 + len(f.Fun cData)*p.ptrsize
107 if len(f.FuncData) > 0 { 106 if len(f.FuncData) > 0 {
108 end += -end & (p.ptrsize - 1) 107 end += -end & (p.ptrsize - 1)
109 } 108 }
110 buf.SetSize(end) 109 buf.SetSize(end)
111 110
112 // entry uintptr 111 // entry uintptr
113 // name int32 112 // name int32
114 // args int32 113 // args int32
115 // frame int32 114 // frame int32
115 //
116 // The frame recorded in the object file is
117 // the frame size used in an assembly listing, which does
118 // not include the caller PC on the stack.
119 // The frame size we want to list here is the delta from
120 // this function's SP to its caller's SP, which does include
121 // the caller PC. Add p.ptrsize to f.Frame to adjust.
122 // TODO(rsc): Record the same frame size in the object file.
116 off = buf.Addr(off, sym.SymID, 0) 123 off = buf.Addr(off, sym.SymID, 0)
117 off = buf.Uint32(off, uint32(addString(buf, sym.Name))) 124 off = buf.Uint32(off, uint32(addString(buf, sym.Name)))
118 off = buf.Uint32(off, uint32(f.Args)) 125 off = buf.Uint32(off, uint32(f.Args))
119 off = buf.Uint32(off, uint32(f.Frame+p.ptrsize)) 126 off = buf.Uint32(off, uint32(f.Frame+p.ptrsize))
120 127
121 // pcdata 128 // pcdata
122 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCSP))) 129 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCSP)))
123 off = buf.Uint32(off, uint32(addPCFileTable(p, buf, file, f.PCFi le, sym, files))) 130 off = buf.Uint32(off, uint32(addPCFileTable(p, buf, file, f.PCFi le, sym, files)))
124 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCLine)) ) 131 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCLine)) )
125 off = buf.Uint32(off, uint32(len(f.PCData))) 132 off = buf.Uint32(off, uint32(len(f.PCData)))
126 off = buf.Uint32(off, uint32(len(f.FuncData))) 133 off = buf.Uint32(off, uint32(len(f.FuncData)))
127 for _, pcdata := range f.PCData { 134 for _, pcdata := range f.PCData {
128 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, pc data))) 135 off = buf.Uint32(off, uint32(addPCTable(p, buf, file, pc data)))
129 } 136 }
130 137
131 // funcdata 138 // funcdata
132 if len(f.FuncData) > 0 { 139 if len(f.FuncData) > 0 {
133 » » » off += off & 4 // must be pointer-aligned and we're only int32-aligned. 140 » » » off += -off & (p.ptrsize - 1) // must be pointer-aligned
134 for _, funcdata := range f.FuncData { 141 for _, funcdata := range f.FuncData {
135 if funcdata.Sym.Name == "" { 142 if funcdata.Sym.Name == "" {
136 off = buf.Uint(off, uint64(funcdata.Offs et), p.ptrsize) 143 off = buf.Uint(off, uint64(funcdata.Offs et), p.ptrsize)
137 } else { 144 } else {
138 off = buf.Addr(off, funcdata.Sym, funcda ta.Offset) 145 off = buf.Addr(off, funcdata.Sym, funcda ta.Offset)
139 } 146 }
140 } 147 }
141 } 148 }
142 149
143 if off != end { 150 if off != end {
144 p.errorf("internal error: invalid math in pclntab: off=% #x end=%#x", off, end) 151 p.errorf("internal error: invalid math in pclntab: off=% #x end=%#x", off, end)
145 break 152 break
146 } 153 }
147 } 154 }
148 if file != nil { 155 if file != nil {
149 file.Close() 156 file.Close()
150 } 157 }
151 158
152 // Final entry of index is end PC of last function. 159 // Final entry of index is end PC of last function.
153 indexOff = buf.Addr(indexOff, lastSym.SymID, int64(lastSym.Size)) 160 indexOff = buf.Addr(indexOff, lastSym.SymID, int64(lastSym.Size))
154 161
155 // Start file table. 162 // Start file table.
156 // Function index is immediately followed by offset to file table. 163 // Function index is immediately followed by offset to file table.
157 off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1) 164 off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
158 buf.Uint32(indexOff, uint32(off)) 165 buf.Uint32(indexOff, uint32(off))
159 166
160 // File table is an array of uint32s. 167 // File table is an array of uint32s.
161 » // The first entry gives n, the size of the array. 168 » // The first entry gives 1+n, the size of the array.
162 » // The following n-1 entries hold offsets to string data. 169 » // The following n entries hold offsets to string data.
163 // File number n uses the string pointed at by entry n. 170 // File number n uses the string pointed at by entry n.
164 // File number 0 is invalid. 171 // File number 0 is invalid.
165 » buf.SetSize(off + (len(files)+1)*4) 172 » buf.SetSize(off + (1+len(files))*4)
166 » buf.Uint32(off, uint32(len(files)+1)) 173 » buf.Uint32(off, uint32(1+len(files)))
167 var filestr []string 174 var filestr []string
168 for file := range files { 175 for file := range files {
169 filestr = append(filestr, file) 176 filestr = append(filestr, file)
170 } 177 }
171 sort.Strings(filestr) 178 sort.Strings(filestr)
172 for _, file := range filestr { 179 for _, file := range filestr {
173 id := files[file] 180 id := files[file]
174 buf.Uint32(off+4*id, uint32(addString(buf, file))) 181 buf.Uint32(off+4*id, uint32(addString(buf, file)))
175 } 182 }
176 183
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 val = int32(filenum[oldval]) 259 val = int32(filenum[oldval])
253 } 260 }
254 dv := val - newval 261 dv := val - newval
255 newval = val 262 newval = val
256 uv := uint32(dv<<1) ^ uint32(dv>>31) 263 uv := uint32(dv<<1) ^ uint32(dv>>31)
257 dst = appendVarint(dst, uv) 264 dst = appendVarint(dst, uv)
258 265
259 // pc delta 266 // pc delta
260 dst = appendVarint(dst, it.NextPC-it.PC) 267 dst = appendVarint(dst, it.NextPC-it.PC)
261 } 268 }
262 » if it.Error { 269 » if it.Corrupt {
263 p.errorf("%s: corrupt pc-file table", sym) 270 p.errorf("%s: corrupt pc-file table", sym)
264 } 271 }
265 272
266 // terminating value delta 273 // terminating value delta
267 dst = appendVarint(dst, 0) 274 dst = appendVarint(dst, 0)
268 275
269 b.SetSize(off + len(dst)) 276 b.SetSize(off + len(dst))
270 copy(b.data[off:], dst) 277 copy(b.data[off:], dst)
271 return off 278 return off
272 } 279 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 return off + b.ptrsize 376 return off + b.ptrsize
370 } 377 }
371 378
372 // A PCIter implements iteration over PC-data tables. 379 // A PCIter implements iteration over PC-data tables.
373 // 380 //
374 // var it PCIter 381 // var it PCIter
375 // it.Init(p, data) 382 // it.Init(p, data)
376 // for it.Init(p, data); !it.Done; it.Next() { 383 // for it.Init(p, data); !it.Done; it.Next() {
377 // it.Value holds from it.PC up to (but not including) it.NextPC 384 // it.Value holds from it.PC up to (but not including) it.NextPC
378 // } 385 // }
379 //» if it.Error { 386 //» if it.Corrupt {
380 // data was malformed 387 // data was malformed
381 // } 388 // }
382 // 389 //
383 type PCIter struct { 390 type PCIter struct {
384 PC uint32 391 PC uint32
385 NextPC uint32 392 NextPC uint32
386 Value int32 393 Value int32
387 Done bool 394 Done bool
388 » Error bool 395 » Corrupt bool
389 p []byte 396 p []byte
390 start bool 397 start bool
391 pcquantum uint32 398 pcquantum uint32
392 } 399 }
393 400
394 // Init initializes the iteration. 401 // Init initializes the iteration.
395 // On return, if it.Done is true, the iteration is over. 402 // On return, if it.Done is true, the iteration is over.
396 // Otherwise it.Value applies in the pc range [it.PC, it.NextPC). 403 // Otherwise it.Value applies in the pc range [it.PC, it.NextPC).
397 func (it *PCIter) Init(p *Prog, buf []byte) { 404 func (it *PCIter) Init(p *Prog, buf []byte) {
398 it.p = buf 405 it.p = buf
(...skipping 16 matching lines...) Expand all
415 } 422 }
416 if len(it.p) == 0 { 423 if len(it.p) == 0 {
417 it.Done = true 424 it.Done = true
418 return 425 return
419 } 426 }
420 427
421 // value delta 428 // value delta
422 uv, p, ok := decodeVarint(it.p) 429 uv, p, ok := decodeVarint(it.p)
423 if !ok { 430 if !ok {
424 it.Done = true 431 it.Done = true
425 » » it.Error = true 432 » » it.Corrupt = true
426 return 433 return
427 } 434 }
428 it.p = p 435 it.p = p
429 if uv == 0 && !it.start { 436 if uv == 0 && !it.start {
430 it.Done = true 437 it.Done = true
431 return 438 return
432 } 439 }
433 it.start = false 440 it.start = false
434 sv := int32(uv)>>1 ^ int32(uv)<<31>>31 441 sv := int32(uv)>>1 ^ int32(uv)<<31>>31
435 it.Value += sv 442 it.Value += sv
436 443
437 // pc delta 444 // pc delta
438 uv, it.p, ok = decodeVarint(it.p) 445 uv, it.p, ok = decodeVarint(it.p)
439 if !ok { 446 if !ok {
440 it.Done = true 447 it.Done = true
441 » » it.Error = true 448 » » it.Corrupt = true
442 return 449 return
443 } 450 }
444 it.NextPC = it.PC + uv*it.pcquantum 451 it.NextPC = it.PC + uv*it.pcquantum
445 } 452 }
446 453
447 // decodeVarint decodes an unsigned varint from p, 454 // decodeVarint decodes an unsigned varint from p,
448 // reporting the value, the remainder of the data, and 455 // reporting the value, the remainder of the data, and
449 // whether the decoding was successful. 456 // whether the decoding was successful.
450 func decodeVarint(p []byte) (v uint32, rest []byte, ok bool) { 457 func decodeVarint(p []byte) (v uint32, rest []byte, ok bool) {
451 for shift := uint(0); ; shift += 7 { 458 for shift := uint(0); ; shift += 7 {
(...skipping 12 matching lines...) Expand all
464 471
465 // appendVarint appends an unsigned varint encoding of v to p 472 // appendVarint appends an unsigned varint encoding of v to p
466 // and returns the resulting slice. 473 // and returns the resulting slice.
467 func appendVarint(p []byte, v uint32) []byte { 474 func appendVarint(p []byte, v uint32) []byte {
468 for ; v >= 0x80; v >>= 7 { 475 for ; v >= 0x80; v >>= 7 {
469 p = append(p, byte(v)|0x80) 476 p = append(p, byte(v)|0x80)
470 } 477 }
471 p = append(p, byte(v)) 478 p = append(p, byte(v))
472 return p 479 return p
473 } 480 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b