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)
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 {
fs.AddBytes(zeros[:pad])
var deltaBuf []byte
- var pcsp Pciter
+ pcsp := newPCIter(ctxt)
for _, s := range ctxt.Textp {
if s.FuncInfo == nil {
continue
// 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,
"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
}
}
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
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 {
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
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()