mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: make Pciter more idiomatic
Rename it to PCIter and convert it to use methods. Set pcscale once, during construction, to make call sites clearer. Change some ints to bools. Use a simple iteration termination condition, instead of the cap comparison from the c2go translation. Instead of requiring a Pcdata, which requires one caller to synthesize a fake Pcdata, just ask for a byte slice. Passes toolstash-check. Change-Id: I811da0e929cf4a806bd6d70357ccf2911cd0c737 Reviewed-on: https://go-review.googlesource.com/c/go/+/171770 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
134ef176f0
commit
6d64dd731b
4 changed files with 53 additions and 47 deletions
|
|
@ -1205,28 +1205,28 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
|
|||
file := 1
|
||||
ls.AddAddr(ctxt.Arch, s)
|
||||
|
||||
var pcfile Pciter
|
||||
var pcline Pciter
|
||||
var pcstmt Pciter
|
||||
pcfile := newPCIter(ctxt)
|
||||
pcline := newPCIter(ctxt)
|
||||
pcstmt := newPCIter(ctxt)
|
||||
for i, s := range unit.lib.Textp {
|
||||
finddebugruntimepath(s)
|
||||
|
||||
pciterinit(ctxt, &pcfile, &s.FuncInfo.Pcfile)
|
||||
pciterinit(ctxt, &pcline, &s.FuncInfo.Pcline)
|
||||
pcfile.init(s.FuncInfo.Pcfile.P)
|
||||
pcline.init(s.FuncInfo.Pcline.P)
|
||||
|
||||
isStmtSym := dwarfFuncSym(ctxt, s, dwarf.IsStmtPrefix, false)
|
||||
if isStmtSym != nil && len(isStmtSym.P) > 0 {
|
||||
pciterinit(ctxt, &pcstmt, &sym.Pcdata{P: isStmtSym.P})
|
||||
pcstmt.init(isStmtSym.P)
|
||||
} else {
|
||||
// Assembly files lack a pcstmt section, we assume that every instruction
|
||||
// is a valid statement.
|
||||
pcstmt.done = 1
|
||||
pcstmt.done = true
|
||||
pcstmt.value = 1
|
||||
}
|
||||
|
||||
var thispc uint32
|
||||
// TODO this loop looks like it could exit with work remaining.
|
||||
for pcfile.done == 0 && pcline.done == 0 {
|
||||
for !pcfile.done && !pcline.done {
|
||||
// Only changed if it advanced
|
||||
if int32(file) != pcfile.value {
|
||||
ls.AddUint8(dwarf.DW_LNS_set_file)
|
||||
|
|
@ -1266,18 +1266,18 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
|
|||
if pcline.nextpc < thispc {
|
||||
thispc = pcline.nextpc
|
||||
}
|
||||
if pcstmt.done == 0 && pcstmt.nextpc < thispc {
|
||||
if !pcstmt.done && pcstmt.nextpc < thispc {
|
||||
thispc = pcstmt.nextpc
|
||||
}
|
||||
|
||||
if pcfile.nextpc == thispc {
|
||||
pciternext(&pcfile)
|
||||
pcfile.next()
|
||||
}
|
||||
if pcstmt.done == 0 && pcstmt.nextpc == thispc {
|
||||
pciternext(&pcstmt)
|
||||
if !pcstmt.done && pcstmt.nextpc == thispc {
|
||||
pcstmt.next()
|
||||
}
|
||||
if pcline.nextpc == thispc {
|
||||
pciternext(&pcline)
|
||||
pcline.next()
|
||||
}
|
||||
}
|
||||
if is_stmt == 0 && i < len(unit.lib.Textp)-1 {
|
||||
|
|
@ -1442,7 +1442,7 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
|||
fs.AddBytes(zeros[:pad])
|
||||
|
||||
var deltaBuf []byte
|
||||
var pcsp Pciter
|
||||
pcsp := newPCIter(ctxt)
|
||||
for _, s := range ctxt.Textp {
|
||||
if s.FuncInfo == nil {
|
||||
continue
|
||||
|
|
@ -1451,7 +1451,7 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
|||
// Emit a FDE, Section 6.4.1.
|
||||
// First build the section contents into a byte buffer.
|
||||
deltaBuf = deltaBuf[:0]
|
||||
for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
||||
for pcsp.init(s.FuncInfo.Pcsp.P); !pcsp.done; pcsp.next() {
|
||||
nextpc := pcsp.nextpc
|
||||
|
||||
// pciterinit goes up to the end of the function,
|
||||
|
|
|
|||
|
|
@ -2112,9 +2112,9 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
|||
|
||||
endr := len(s.R)
|
||||
var ch1 chain
|
||||
var pcsp Pciter
|
||||
pcsp := newPCIter(ctxt)
|
||||
var r *sym.Reloc
|
||||
for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
||||
for pcsp.init(s.FuncInfo.Pcsp.P); !pcsp.done; pcsp.next() {
|
||||
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
||||
|
||||
// Check stack size in effect for this span.
|
||||
|
|
|
|||
|
|
@ -169,14 +169,3 @@ func addImports(ctxt *Link, l *sym.Library, pn string) {
|
|||
}
|
||||
l.ImportStrings = nil
|
||||
}
|
||||
|
||||
type Pciter struct {
|
||||
d sym.Pcdata
|
||||
p []byte
|
||||
pc uint32
|
||||
nextpc uint32
|
||||
pcscale uint32
|
||||
value int32
|
||||
start int
|
||||
done int
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,32 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// iteration over encoded pcdata tables.
|
||||
// PCIter iterates over encoded pcdata tables.
|
||||
type PCIter struct {
|
||||
p []byte
|
||||
pc uint32
|
||||
nextpc uint32
|
||||
pcscale uint32
|
||||
value int32
|
||||
start bool
|
||||
done bool
|
||||
}
|
||||
|
||||
func pciternext(it *Pciter) {
|
||||
// newPCIter creates a PCIter and configures it for ctxt's architecture.
|
||||
func newPCIter(ctxt *Link) *PCIter {
|
||||
it := new(PCIter)
|
||||
it.pcscale = uint32(ctxt.Arch.MinLC)
|
||||
return it
|
||||
}
|
||||
|
||||
// next advances it to the next pc.
|
||||
func (it *PCIter) next() {
|
||||
it.pc = it.nextpc
|
||||
if it.done != 0 {
|
||||
if it.done {
|
||||
return
|
||||
}
|
||||
if -cap(it.p) >= -cap(it.d.P[len(it.d.P):]) {
|
||||
it.done = 1
|
||||
if len(it.p) == 0 {
|
||||
it.done = true
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -35,12 +52,12 @@ func pciternext(it *Pciter) {
|
|||
}
|
||||
it.p = it.p[n:]
|
||||
|
||||
if val == 0 && it.start == 0 {
|
||||
it.done = 1
|
||||
if val == 0 && !it.start {
|
||||
it.done = true
|
||||
return
|
||||
}
|
||||
|
||||
it.start = 0
|
||||
it.start = false
|
||||
it.value += int32(val)
|
||||
|
||||
// pc delta
|
||||
|
|
@ -53,16 +70,16 @@ func pciternext(it *Pciter) {
|
|||
it.nextpc = it.pc + uint32(pc)*it.pcscale
|
||||
}
|
||||
|
||||
func pciterinit(ctxt *Link, it *Pciter, d *sym.Pcdata) {
|
||||
it.d = *d
|
||||
it.p = it.d.P
|
||||
// init prepares it to iterate over p,
|
||||
// and advances it to the first pc.
|
||||
func (it *PCIter) init(p []byte) {
|
||||
it.p = p
|
||||
it.pc = 0
|
||||
it.nextpc = 0
|
||||
it.value = -1
|
||||
it.start = 1
|
||||
it.done = 0
|
||||
it.pcscale = uint32(ctxt.Arch.MinLC)
|
||||
pciternext(it)
|
||||
it.start = true
|
||||
it.done = false
|
||||
it.next()
|
||||
}
|
||||
|
||||
func addpctab(ctxt *Link, ftab *sym.Symbol, off int32, d *sym.Pcdata) int32 {
|
||||
|
|
@ -101,8 +118,8 @@ func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) {
|
|||
buf := make([]byte, binary.MaxVarintLen32)
|
||||
newval := int32(-1)
|
||||
var out sym.Pcdata
|
||||
var it Pciter
|
||||
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
||||
it := newPCIter(ctxt)
|
||||
for it.init(d.P); !it.done; it.next() {
|
||||
// value delta
|
||||
oldval := it.value
|
||||
|
||||
|
|
@ -316,8 +333,8 @@ func (ctxt *Link) pclntab() {
|
|||
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
|
||||
if false {
|
||||
// Sanity check the new numbering
|
||||
var it Pciter
|
||||
for pciterinit(ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) {
|
||||
it := newPCIter(ctxt)
|
||||
for it.init(pcln.Pcfile.P); !it.done; it.next() {
|
||||
if it.value < 1 || it.value > int32(len(ctxt.Filesyms)) {
|
||||
Errorf(s, "bad file number in pcfile: %d not in range [1, %d]\n", it.value, len(ctxt.Filesyms))
|
||||
errorexit()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue