Commit fa896733 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

runtime: check consistency of all module data objects

Current code just checks the consistency (that the functab is correctly
sorted by PC, etc) of the moduledata object that the runtime belongs to.
Change to check all of them.

Change-Id: I544a44c5de7445fff87d3cdb4840ff04c5e2bf75
Reviewed-on: https://go-review.googlesource.com/9773Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent d0a05f51
...@@ -51,7 +51,7 @@ func schedinit() { ...@@ -51,7 +51,7 @@ func schedinit() {
framepointer_enabled = haveexperiment("framepointer") framepointer_enabled = haveexperiment("framepointer")
tracebackinit() tracebackinit()
symtabverify() moduledataverify()
stackinit() stackinit()
mallocinit() mallocinit()
mcommoninit(_g_.m) mcommoninit(_g_.m)
......
...@@ -84,38 +84,44 @@ type findfuncbucket struct { ...@@ -84,38 +84,44 @@ type findfuncbucket struct {
subbuckets [16]byte subbuckets [16]byte
} }
func symtabverify() { func moduledataverify() {
for datap := &firstmoduledata; datap != nil; datap = datap.next {
moduledataverify1(datap)
}
}
func moduledataverify1(datap *moduledata) {
// See golang.org/s/go12symtab for header: 0xfffffffb, // See golang.org/s/go12symtab for header: 0xfffffffb,
// two zero bytes, a byte giving the PC quantum, // two zero bytes, a byte giving the PC quantum,
// and a byte giving the pointer width in bytes. // and a byte giving the pointer width in bytes.
pcln := *(**[8]byte)(unsafe.Pointer(&firstmoduledata.pclntable)) pcln := *(**[8]byte)(unsafe.Pointer(&datap.pclntable))
pcln32 := *(**[2]uint32)(unsafe.Pointer(&firstmoduledata.pclntable)) pcln32 := *(**[2]uint32)(unsafe.Pointer(&datap.pclntable))
if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != _PCQuantum || pcln[7] != ptrSize { if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != _PCQuantum || pcln[7] != ptrSize {
println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7])) println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7]))
throw("invalid function symbol table\n") throw("invalid function symbol table\n")
} }
// ftab is lookup table for function by program counter. // ftab is lookup table for function by program counter.
nftab := len(firstmoduledata.ftab) - 1 nftab := len(datap.ftab) - 1
for i := 0; i < nftab; i++ { for i := 0; i < nftab; i++ {
// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function. // NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
if firstmoduledata.ftab[i].entry > firstmoduledata.ftab[i+1].entry { if datap.ftab[i].entry > datap.ftab[i+1].entry {
f1 := (*_func)(unsafe.Pointer(&firstmoduledata.pclntable[firstmoduledata.ftab[i].funcoff])) f1 := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff]))
f2 := (*_func)(unsafe.Pointer(&firstmoduledata.pclntable[firstmoduledata.ftab[i+1].funcoff])) f2 := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff]))
f2name := "end" f2name := "end"
if i+1 < nftab { if i+1 < nftab {
f2name = funcname(f2) f2name = funcname(f2)
} }
println("function symbol table not sorted by program counter:", hex(firstmoduledata.ftab[i].entry), funcname(f1), ">", hex(firstmoduledata.ftab[i+1].entry), f2name) println("function symbol table not sorted by program counter:", hex(datap.ftab[i].entry), funcname(f1), ">", hex(datap.ftab[i+1].entry), f2name)
for j := 0; j <= i; j++ { for j := 0; j <= i; j++ {
print("\t", hex(firstmoduledata.ftab[j].entry), " ", funcname((*_func)(unsafe.Pointer(&firstmoduledata.pclntable[firstmoduledata.ftab[j].funcoff]))), "\n") print("\t", hex(datap.ftab[j].entry), " ", funcname((*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff]))), "\n")
} }
throw("invalid runtime symbol table") throw("invalid runtime symbol table")
} }
} }
if firstmoduledata.minpc != firstmoduledata.ftab[0].entry || if datap.minpc != datap.ftab[0].entry ||
firstmoduledata.maxpc != firstmoduledata.ftab[nftab].entry { datap.maxpc != datap.ftab[nftab].entry {
throw("minpc or maxpc invalid") throw("minpc or maxpc invalid")
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment