file := 1
ls.AddAddr(ctxt.Arch, s)
- pcfile := newPCIter(ctxt)
- pcline := newPCIter(ctxt)
- pcstmt := newPCIter(ctxt)
+ pcfile := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
+ pcline := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
+ pcstmt := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
for i, s := range unit.lib.Textp {
finddebugruntimepath(s)
- pcfile.init(s.FuncInfo.Pcfile.P)
- pcline.init(s.FuncInfo.Pcline.P)
+ 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 {
- pcstmt.init(isStmtSym.P)
+ pcstmt.Init(isStmtSym.P)
} else {
// Assembly files lack a pcstmt section, we assume that every instruction
// is a valid statement.
- pcstmt.done = true
- pcstmt.value = 1
+ pcstmt.Done = true
+ pcstmt.Value = 1
}
var thispc uint32
// TODO this loop looks like it could exit with work remaining.
- for !pcfile.done && !pcline.done {
+ for !pcfile.Done && !pcline.Done {
// Only changed if it advanced
- if int32(file) != pcfile.value {
+ if int32(file) != pcfile.Value {
ls.AddUint8(dwarf.DW_LNS_set_file)
- idx, ok := fileNums[int(pcfile.value)]
+ idx, ok := fileNums[int(pcfile.Value)]
if !ok {
Exitf("pcln table file missing from DWARF line table")
}
dwarf.Uleb128put(dwarfctxt, ls, int64(idx))
- file = int(pcfile.value)
+ file = int(pcfile.Value)
}
// Only changed if it advanced
- if is_stmt != uint8(pcstmt.value) {
- new_stmt := uint8(pcstmt.value)
+ if is_stmt != uint8(pcstmt.Value) {
+ new_stmt := uint8(pcstmt.Value)
switch new_stmt &^ 1 {
case obj.PrologueEnd:
ls.AddUint8(uint8(dwarf.DW_LNS_set_prologue_end))
}
// putpcldelta makes a row in the DWARF matrix, always, even if line is unchanged.
- putpclcdelta(ctxt, dwarfctxt, ls, uint64(s.Value+int64(thispc)-pc), int64(pcline.value)-int64(line))
+ putpclcdelta(ctxt, dwarfctxt, ls, uint64(s.Value+int64(thispc)-pc), int64(pcline.Value)-int64(line))
pc = s.Value + int64(thispc)
- line = int(pcline.value)
+ line = int(pcline.Value)
// Take the minimum step forward for the three iterators
- thispc = pcfile.nextpc
- if pcline.nextpc < thispc {
- thispc = pcline.nextpc
+ thispc = pcfile.NextPC
+ if pcline.NextPC < thispc {
+ thispc = pcline.NextPC
}
- if !pcstmt.done && pcstmt.nextpc < thispc {
- thispc = pcstmt.nextpc
+ if !pcstmt.Done && pcstmt.NextPC < thispc {
+ thispc = pcstmt.NextPC
}
- if pcfile.nextpc == thispc {
- pcfile.next()
+ if pcfile.NextPC == thispc {
+ pcfile.Next()
}
- if !pcstmt.done && pcstmt.nextpc == thispc {
- pcstmt.next()
+ if !pcstmt.Done && pcstmt.NextPC == thispc {
+ pcstmt.Next()
}
- if pcline.nextpc == thispc {
- pcline.next()
+ if pcline.NextPC == thispc {
+ pcline.Next()
}
}
if is_stmt == 0 && i < len(unit.lib.Textp)-1 {
fs.AddBytes(zeros[:pad])
var deltaBuf []byte
- pcsp := newPCIter(ctxt)
+ pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
for _, s := range ctxt.Textp {
if s.FuncInfo == nil {
continue
deltaBuf = append(deltaBuf, dwarf.DW_CFA_undefined)
deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
}
- for pcsp.init(s.FuncInfo.Pcsp.P); !pcsp.done; pcsp.next() {
- nextpc := pcsp.nextpc
+ for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
+ nextpc := pcsp.NextPC
// pciterinit goes up to the end of the function,
// but DWARF expects us to stop just before the end.
if int64(nextpc) == s.Size {
nextpc--
- if nextpc < pcsp.pc {
+ if nextpc < pcsp.PC {
continue
}
}
- spdelta := int64(pcsp.value)
+ spdelta := int64(pcsp.Value)
if !haslinkregister(ctxt) {
// Return address has been pushed onto stack.
spdelta += int64(ctxt.Arch.PtrSize)
// TODO(bryanpkc): This is imprecise. In general, the instruction
// that stores the return address to the stack frame is not the
// same one that allocates the frame.
- if pcsp.value > 0 {
+ if pcsp.Value > 0 {
// The return address is preserved at (CFA-frame_size)
// after a stack frame has been allocated.
deltaBuf = append(deltaBuf, dwarf.DW_CFA_offset_extended_sf)
}
}
- deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.pc), spdelta)
+ deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.PC), spdelta)
}
pad := int(Rnd(int64(len(deltaBuf)), int64(ctxt.Arch.PtrSize))) - len(deltaBuf)
deltaBuf = append(deltaBuf, zeros[:pad]...)
"bufio"
"bytes"
"cmd/internal/bio"
+ "cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/loadelf"
endr := len(s.R)
var ch1 chain
- pcsp := newPCIter(ctxt)
+ pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
var r *sym.Reloc
- for pcsp.init(s.FuncInfo.Pcsp.P); !pcsp.done; pcsp.next() {
+ 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.
- if int32(limit)-pcsp.value < 0 {
- stkbroke(ctxt, up, int(int32(limit)-pcsp.value))
+ if int32(limit)-pcsp.Value < 0 {
+ stkbroke(ctxt, up, int(int32(limit)-pcsp.Value))
return -1
}
// Process calls in this span.
- for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
+ for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ {
r = &s.R[ri]
switch r.Type {
// Direct call.
case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS:
- ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
+ ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
ch.sym = r.Sym
if stkcheck(ctxt, &ch, depth+1) < 0 {
return -1
// Arrange the data structures to report both calls, so that
// if there is an error, stkprint shows all the steps involved.
case objabi.R_CALLIND:
- ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
+ ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
ch.sym = nil
ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
package ld
import (
+ "cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
"strings"
)
-// PCIter iterates over encoded pcdata tables.
-type PCIter struct {
- p []byte
- pc uint32
- nextpc uint32
- pcscale uint32
- value int32
- start bool
- done bool
-}
-
-// 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 {
- return
- }
- if len(it.p) == 0 {
- it.done = true
- return
- }
-
- // value delta
- val, n := binary.Varint(it.p)
- if n <= 0 {
- log.Fatalf("bad value varint in pciternext: read %v", n)
- }
- it.p = it.p[n:]
-
- if val == 0 && !it.start {
- it.done = true
- return
- }
-
- it.start = false
- it.value += int32(val)
-
- // pc delta
- pc, n := binary.Uvarint(it.p)
- if n <= 0 {
- log.Fatalf("bad pc varint in pciternext: read %v", n)
- }
- it.p = it.p[n:]
-
- it.nextpc = it.pc + uint32(pc)*it.pcscale
-}
-
-// 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 = true
- it.done = false
- it.next()
-}
-
func ftabaddstring(ftab *sym.Symbol, s string) int32 {
start := len(ftab.P)
ftab.Grow(int64(start + len(s) + 1)) // make room for s plus trailing NUL
buf := make([]byte, binary.MaxVarintLen32)
newval := int32(-1)
var out sym.Pcdata
- it := newPCIter(ctxt)
- for it.init(d.P); !it.done; it.next() {
+ it := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
+ for it.Init(d.P); !it.Done; it.Next() {
// value delta
- oldval := it.value
+ oldval := it.Value
var val int32
if oldval == -1 {
out.P = append(out.P, buf[:n]...)
// pc delta
- pc := (it.nextpc - it.pc) / it.pcscale
+ pc := (it.NextPC - it.PC) / it.PCScale
n = binary.PutUvarint(buf, uint64(pc))
out.P = append(out.P, buf[:n]...)
}
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
if false {
// Sanity check the new numbering
- 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))
+ it := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
+ 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()
}
}