f := &funcs[i]
f.Entry = t.uintptr(t.functab[2*i*int(t.ptrsize):])
f.End = t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):])
- info := t.funcdata[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
+ info := t.funcData(uint32(i))
f.LineTable = t
- f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
+ f.FrameSize = int(info.deferreturn())
f.Sym = &Sym{
Value: f.Entry,
Type: 'T',
- Name: t.funcName(t.binary.Uint32(info[t.ptrsize:])),
+ Name: t.funcName(info.nameoff()),
GoType: 0,
Func: f,
}
return funcs
}
-// findFunc returns the func corresponding to the given program counter.
-func (t *LineTable) findFunc(pc uint64) []byte {
+// findFunc returns the funcData corresponding to the given program counter.
+func (t *LineTable) findFunc(pc uint64) funcData {
if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
- return nil
+ return funcData{}
}
// The function table is a list of 2*nfunctab+1 uintptrs,
m := nf / 2
fm := f[2*t.ptrsize*m:]
if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) {
- return t.funcdata[t.uintptr(fm[t.ptrsize:]):]
+ data := t.funcdata[t.uintptr(fm[t.ptrsize:]):]
+ return funcData{t: t, data: data}
} else if pc < t.uintptr(fm) {
nf = m
} else {
nf -= m + 1
}
}
- return nil
+ return funcData{}
}
// readvarint reads, removes, and returns a varint from *pp.
return t.stringFrom(t.funcdata, off)
}
+// funcData is memory corresponding to an _func struct.
+type funcData struct {
+ t *LineTable // LineTable this data is a part of
+ data []byte // raw memory for the function
+}
+
+// funcData returns the ith funcData in t.functab.
+func (t *LineTable) funcData(i uint32) funcData {
+ data := t.funcdata[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
+ return funcData{t: t, data: data}
+}
+
+// IsZero reports whether f is the zero value.
+func (f funcData) IsZero() bool {
+ return f.t == nil && f.data == nil
+}
+
+// entryPC returns the func's entry PC.
+func (f funcData) entryPC() uint64 {
+ return f.t.uintptr(f.data)
+}
+
+func (f funcData) nameoff() uint32 { return f.field(1) }
+func (f funcData) deferreturn() uint32 { return f.field(3) }
+func (f funcData) pcfile() uint32 { return f.field(5) }
+func (f funcData) pcln() uint32 { return f.field(6) }
+func (f funcData) cuOffset() uint32 { return f.field(8) }
+
+// field returns the nth field of the _func struct.
+// It panics if n == 0 or n > 9; for n == 0, call f.entryPC.
+// Most callers should use a named field accessor (just above).
+func (f funcData) field(n uint32) uint32 {
+ if n == 0 || n > 9 {
+ panic("bad funcdata field")
+ }
+ sz0 := f.t.ptrsize
+ off := sz0 + (n-1)*4 // subsequent fields are 4 bytes each
+ data := f.data[off:]
+ return f.t.binary.Uint32(data)
+}
+
// step advances to the next pc, value pair in the encoded table.
func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
uvdelta := t.readvarint(p)
}()
f := t.findFunc(pc)
- if f == nil {
+ if f.IsZero() {
return -1
}
- entry := t.uintptr(f)
- linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
+ entry := f.entryPC()
+ linetab := f.pcln()
return int(t.pcvalue(linetab, entry, pc))
}
}()
f := t.findFunc(pc)
- if f == nil {
+ if f.IsZero() {
return ""
}
- entry := t.uintptr(f)
- filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
+ entry := f.entryPC()
+ filetab := f.pcfile()
fno := t.pcvalue(filetab, entry, pc)
if t.version == ver12 {
if fno <= 0 {
if fno < 0 { // 0 is valid for ≥ 1.16
return ""
}
- cuoff := t.binary.Uint32(f[t.ptrsize+7*4:])
+ cuoff := f.cuOffset()
if fnoff := t.binary.Uint32(t.cutab[(cuoff+uint32(fno))*4:]); fnoff != ^uint32(0) {
return t.stringFrom(t.filetab, fnoff)
}
// mapping file number to a list of functions with code from that file.
var cutab []byte
for i := uint32(0); i < t.nfunctab; i++ {
- f := t.funcdata[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
- entry := t.uintptr(f)
- filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
- linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
+ f := t.funcData(i)
+ entry := f.entryPC()
+ filetab := f.pcfile()
+ linetab := f.pcln()
if t.version == ver116 {
- cuoff := t.binary.Uint32(f[t.ptrsize+7*4:]) * 4
- cutab = t.cutab[cuoff:]
+ cutab = t.cutab[f.cuOffset()*4:]
}
pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line), cutab)
if pc != 0 {