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
|
file := 1
|
||||||
ls.AddAddr(ctxt.Arch, s)
|
ls.AddAddr(ctxt.Arch, s)
|
||||||
|
|
||||||
var pcfile Pciter
|
pcfile := newPCIter(ctxt)
|
||||||
var pcline Pciter
|
pcline := newPCIter(ctxt)
|
||||||
var pcstmt Pciter
|
pcstmt := newPCIter(ctxt)
|
||||||
for i, s := range unit.lib.Textp {
|
for i, s := range unit.lib.Textp {
|
||||||
finddebugruntimepath(s)
|
finddebugruntimepath(s)
|
||||||
|
|
||||||
pciterinit(ctxt, &pcfile, &s.FuncInfo.Pcfile)
|
pcfile.init(s.FuncInfo.Pcfile.P)
|
||||||
pciterinit(ctxt, &pcline, &s.FuncInfo.Pcline)
|
pcline.init(s.FuncInfo.Pcline.P)
|
||||||
|
|
||||||
isStmtSym := dwarfFuncSym(ctxt, s, dwarf.IsStmtPrefix, false)
|
isStmtSym := dwarfFuncSym(ctxt, s, dwarf.IsStmtPrefix, false)
|
||||||
if isStmtSym != nil && len(isStmtSym.P) > 0 {
|
if isStmtSym != nil && len(isStmtSym.P) > 0 {
|
||||||
pciterinit(ctxt, &pcstmt, &sym.Pcdata{P: isStmtSym.P})
|
pcstmt.init(isStmtSym.P)
|
||||||
} else {
|
} else {
|
||||||
// Assembly files lack a pcstmt section, we assume that every instruction
|
// Assembly files lack a pcstmt section, we assume that every instruction
|
||||||
// is a valid statement.
|
// is a valid statement.
|
||||||
pcstmt.done = 1
|
pcstmt.done = true
|
||||||
pcstmt.value = 1
|
pcstmt.value = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var thispc uint32
|
var thispc uint32
|
||||||
// TODO this loop looks like it could exit with work remaining.
|
// 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
|
// Only changed if it advanced
|
||||||
if int32(file) != pcfile.value {
|
if int32(file) != pcfile.value {
|
||||||
ls.AddUint8(dwarf.DW_LNS_set_file)
|
ls.AddUint8(dwarf.DW_LNS_set_file)
|
||||||
|
|
@ -1266,18 +1266,18 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
|
||||||
if pcline.nextpc < thispc {
|
if pcline.nextpc < thispc {
|
||||||
thispc = pcline.nextpc
|
thispc = pcline.nextpc
|
||||||
}
|
}
|
||||||
if pcstmt.done == 0 && pcstmt.nextpc < thispc {
|
if !pcstmt.done && pcstmt.nextpc < thispc {
|
||||||
thispc = pcstmt.nextpc
|
thispc = pcstmt.nextpc
|
||||||
}
|
}
|
||||||
|
|
||||||
if pcfile.nextpc == thispc {
|
if pcfile.nextpc == thispc {
|
||||||
pciternext(&pcfile)
|
pcfile.next()
|
||||||
}
|
}
|
||||||
if pcstmt.done == 0 && pcstmt.nextpc == thispc {
|
if !pcstmt.done && pcstmt.nextpc == thispc {
|
||||||
pciternext(&pcstmt)
|
pcstmt.next()
|
||||||
}
|
}
|
||||||
if pcline.nextpc == thispc {
|
if pcline.nextpc == thispc {
|
||||||
pciternext(&pcline)
|
pcline.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_stmt == 0 && i < len(unit.lib.Textp)-1 {
|
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])
|
fs.AddBytes(zeros[:pad])
|
||||||
|
|
||||||
var deltaBuf []byte
|
var deltaBuf []byte
|
||||||
var pcsp Pciter
|
pcsp := newPCIter(ctxt)
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
if s.FuncInfo == nil {
|
if s.FuncInfo == nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1451,7 +1451,7 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||||
// Emit a FDE, Section 6.4.1.
|
// Emit a FDE, Section 6.4.1.
|
||||||
// First build the section contents into a byte buffer.
|
// First build the section contents into a byte buffer.
|
||||||
deltaBuf = deltaBuf[:0]
|
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
|
nextpc := pcsp.nextpc
|
||||||
|
|
||||||
// pciterinit goes up to the end of the function,
|
// 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)
|
endr := len(s.R)
|
||||||
var ch1 chain
|
var ch1 chain
|
||||||
var pcsp Pciter
|
pcsp := newPCIter(ctxt)
|
||||||
var r *sym.Reloc
|
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).
|
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
||||||
|
|
||||||
// Check stack size in effect for this span.
|
// Check stack size in effect for this span.
|
||||||
|
|
|
||||||
|
|
@ -169,14 +169,3 @@ func addImports(ctxt *Link, l *sym.Library, pn string) {
|
||||||
}
|
}
|
||||||
l.ImportStrings = nil
|
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"
|
"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
|
it.pc = it.nextpc
|
||||||
if it.done != 0 {
|
if it.done {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if -cap(it.p) >= -cap(it.d.P[len(it.d.P):]) {
|
if len(it.p) == 0 {
|
||||||
it.done = 1
|
it.done = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,12 +52,12 @@ func pciternext(it *Pciter) {
|
||||||
}
|
}
|
||||||
it.p = it.p[n:]
|
it.p = it.p[n:]
|
||||||
|
|
||||||
if val == 0 && it.start == 0 {
|
if val == 0 && !it.start {
|
||||||
it.done = 1
|
it.done = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
it.start = 0
|
it.start = false
|
||||||
it.value += int32(val)
|
it.value += int32(val)
|
||||||
|
|
||||||
// pc delta
|
// pc delta
|
||||||
|
|
@ -53,16 +70,16 @@ func pciternext(it *Pciter) {
|
||||||
it.nextpc = it.pc + uint32(pc)*it.pcscale
|
it.nextpc = it.pc + uint32(pc)*it.pcscale
|
||||||
}
|
}
|
||||||
|
|
||||||
func pciterinit(ctxt *Link, it *Pciter, d *sym.Pcdata) {
|
// init prepares it to iterate over p,
|
||||||
it.d = *d
|
// and advances it to the first pc.
|
||||||
it.p = it.d.P
|
func (it *PCIter) init(p []byte) {
|
||||||
|
it.p = p
|
||||||
it.pc = 0
|
it.pc = 0
|
||||||
it.nextpc = 0
|
it.nextpc = 0
|
||||||
it.value = -1
|
it.value = -1
|
||||||
it.start = 1
|
it.start = true
|
||||||
it.done = 0
|
it.done = false
|
||||||
it.pcscale = uint32(ctxt.Arch.MinLC)
|
it.next()
|
||||||
pciternext(it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpctab(ctxt *Link, ftab *sym.Symbol, off int32, d *sym.Pcdata) int32 {
|
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)
|
buf := make([]byte, binary.MaxVarintLen32)
|
||||||
newval := int32(-1)
|
newval := int32(-1)
|
||||||
var out sym.Pcdata
|
var out sym.Pcdata
|
||||||
var it Pciter
|
it := newPCIter(ctxt)
|
||||||
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
for it.init(d.P); !it.done; it.next() {
|
||||||
// value delta
|
// value delta
|
||||||
oldval := it.value
|
oldval := it.value
|
||||||
|
|
||||||
|
|
@ -316,8 +333,8 @@ func (ctxt *Link) pclntab() {
|
||||||
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
|
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
|
||||||
if false {
|
if false {
|
||||||
// Sanity check the new numbering
|
// Sanity check the new numbering
|
||||||
var it Pciter
|
it := newPCIter(ctxt)
|
||||||
for pciterinit(ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) {
|
for it.init(pcln.Pcfile.P); !it.done; it.next() {
|
||||||
if it.value < 1 || it.value > int32(len(ctxt.Filesyms)) {
|
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))
|
Errorf(s, "bad file number in pcfile: %d not in range [1, %d]\n", it.value, len(ctxt.Filesyms))
|
||||||
errorexit()
|
errorexit()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue