mirror of
https://github.com/golang/go
synced 2024-11-19 16:44:43 -07:00
runtime, cmd/internal/ld: change runtime to use a single linker symbol
In preparation for being able to run a go program that has code in several objects, this changes from having several linker symbols used by the runtime into having one linker symbol that points at a structure containing the needed data. Multiple object support will construct a linked list of such structures. A follow up will initialize the slices in the themoduledata structure directly from the linker but I was aiming for a minimal diff for now. Change-Id: I613cce35309801cf265a1d5ae5aaca8d689c5cbf Reviewed-on: https://go-review.googlesource.com/7441 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
0de359da30
commit
67426a8a9e
@ -395,4 +395,38 @@ func symtab() {
|
||||
liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Information about the layout of the executable image for the
|
||||
// runtime to use. Any changes here must be matched by changes to
|
||||
// the definition of moduledata in runtime/symtab.go.
|
||||
moduledata := Linklookup(Ctxt, "runtime.themoduledata", 0)
|
||||
moduledata.Type = SNOPTRDATA
|
||||
moduledata.Size = 0 // truncate symbol back to 0 bytes to reinitialize
|
||||
moduledata.Reachable = true
|
||||
// Three slices (pclntable, ftab, filetab), uninitalized
|
||||
moduledata.Size += int64((3 * 3 * Thearch.Ptrsize))
|
||||
Symgrow(Ctxt, moduledata, moduledata.Size)
|
||||
// Three uintptrs, initialized
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.epclntab", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.findfunctab", 0))
|
||||
// 2 more uintptrs (minpc, maxpc), uninitalized
|
||||
moduledata.Size += int64(2 * Thearch.Ptrsize)
|
||||
Symgrow(Ctxt, moduledata, moduledata.Size)
|
||||
// more initialized uintptrs
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.text", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etext", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrdata", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.enoptrdata", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.data", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.edata", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.bss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.ebss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrbss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.enoptrbss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.end", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcdata", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etypelink", 0))
|
||||
}
|
||||
|
@ -432,17 +432,17 @@ func finq_callback(fn *funcval, obj unsafe.Pointer, nret uintptr, fint *_type, o
|
||||
|
||||
func dumproots() {
|
||||
// data segment
|
||||
dumpbvtypes(&gcdatamask, unsafe.Pointer(&data))
|
||||
dumpbvtypes(&gcdatamask, unsafe.Pointer(themoduledata.data))
|
||||
dumpint(tagData)
|
||||
dumpint(uint64(uintptr(unsafe.Pointer(&data))))
|
||||
dumpmemrange(unsafe.Pointer(&data), uintptr(unsafe.Pointer(&edata))-uintptr(unsafe.Pointer(&data)))
|
||||
dumpint(uint64(themoduledata.data))
|
||||
dumpmemrange(unsafe.Pointer(themoduledata.data), themoduledata.edata-themoduledata.data)
|
||||
dumpfields(gcdatamask)
|
||||
|
||||
// bss segment
|
||||
dumpbvtypes(&gcbssmask, unsafe.Pointer(&bss))
|
||||
dumpbvtypes(&gcbssmask, unsafe.Pointer(themoduledata.bss))
|
||||
dumpint(tagBSS)
|
||||
dumpint(uint64(uintptr(unsafe.Pointer(&bss))))
|
||||
dumpmemrange(unsafe.Pointer(&bss), uintptr(unsafe.Pointer(&ebss))-uintptr(unsafe.Pointer(&bss)))
|
||||
dumpint(uint64(themoduledata.bss))
|
||||
dumpmemrange(unsafe.Pointer(themoduledata.bss), themoduledata.ebss-themoduledata.bss)
|
||||
dumpfields(gcbssmask)
|
||||
|
||||
// MSpan.types
|
||||
|
@ -322,7 +322,7 @@ func mallocinit() {
|
||||
// So adjust it upward a little bit ourselves: 1/4 MB to get
|
||||
// away from the running binary image and then round up
|
||||
// to a MB boundary.
|
||||
p = round(uintptr(unsafe.Pointer(&end))+(1<<18), 1<<20)
|
||||
p = round(themoduledata.end+(1<<18), 1<<20)
|
||||
pSize = bitmapSize + spansSize + arenaSize + _PageSize
|
||||
p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved))
|
||||
if p != 0 {
|
||||
|
@ -428,29 +428,29 @@ func wbshadowinit() {
|
||||
mheap_.shadow_reserved = reserved
|
||||
start := ^uintptr(0)
|
||||
end := uintptr(0)
|
||||
if start > uintptr(unsafe.Pointer(&noptrdata)) {
|
||||
start = uintptr(unsafe.Pointer(&noptrdata))
|
||||
if start > themoduledata.noptrdata {
|
||||
start = themoduledata.noptrdata
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&data)) {
|
||||
start = uintptr(unsafe.Pointer(&data))
|
||||
if start > themoduledata.data {
|
||||
start = themoduledata.data
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&noptrbss)) {
|
||||
start = uintptr(unsafe.Pointer(&noptrbss))
|
||||
if start > themoduledata.noptrbss {
|
||||
start = themoduledata.noptrbss
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&bss)) {
|
||||
start = uintptr(unsafe.Pointer(&bss))
|
||||
if start > themoduledata.bss {
|
||||
start = themoduledata.bss
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&enoptrdata)) {
|
||||
end = uintptr(unsafe.Pointer(&enoptrdata))
|
||||
if end < themoduledata.enoptrdata {
|
||||
end = themoduledata.enoptrdata
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&edata)) {
|
||||
end = uintptr(unsafe.Pointer(&edata))
|
||||
if end < themoduledata.edata {
|
||||
end = themoduledata.edata
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&enoptrbss)) {
|
||||
end = uintptr(unsafe.Pointer(&enoptrbss))
|
||||
if end < themoduledata.enoptrbss {
|
||||
end = themoduledata.enoptrbss
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&ebss)) {
|
||||
end = uintptr(unsafe.Pointer(&ebss))
|
||||
if end < themoduledata.ebss {
|
||||
end = themoduledata.ebss
|
||||
}
|
||||
start &^= _PhysPageSize - 1
|
||||
end = round(end, _PhysPageSize)
|
||||
|
@ -747,12 +747,12 @@ func getgcmask(p unsafe.Pointer, t *_type, mask **byte, len *uintptr) {
|
||||
const typeBitsPerByte = 8 / typeBitsWidth
|
||||
|
||||
// data
|
||||
if uintptr(unsafe.Pointer(&data)) <= uintptr(p) && uintptr(p) < uintptr(unsafe.Pointer(&edata)) {
|
||||
if themoduledata.data <= uintptr(p) && uintptr(p) < themoduledata.edata {
|
||||
n := (*ptrtype)(unsafe.Pointer(t)).elem.size
|
||||
*len = n / ptrSize
|
||||
*mask = &make([]byte, *len)[0]
|
||||
for i := uintptr(0); i < n; i += ptrSize {
|
||||
off := (uintptr(p) + i - uintptr(unsafe.Pointer(&data))) / ptrSize
|
||||
off := (uintptr(p) + i - themoduledata.data) / ptrSize
|
||||
bits := (*(*byte)(add(unsafe.Pointer(gcdatamask.bytedata), off/typeBitsPerByte)) >> ((off % typeBitsPerByte) * typeBitsWidth)) & typeMask
|
||||
*(*byte)(add(unsafe.Pointer(*mask), i/ptrSize)) = bits
|
||||
}
|
||||
@ -760,12 +760,12 @@ func getgcmask(p unsafe.Pointer, t *_type, mask **byte, len *uintptr) {
|
||||
}
|
||||
|
||||
// bss
|
||||
if uintptr(unsafe.Pointer(&bss)) <= uintptr(p) && uintptr(p) < uintptr(unsafe.Pointer(&ebss)) {
|
||||
if themoduledata.bss <= uintptr(p) && uintptr(p) < themoduledata.ebss {
|
||||
n := (*ptrtype)(unsafe.Pointer(t)).elem.size
|
||||
*len = n / ptrSize
|
||||
*mask = &make([]byte, *len)[0]
|
||||
for i := uintptr(0); i < n; i += ptrSize {
|
||||
off := (uintptr(p) + i - uintptr(unsafe.Pointer(&bss))) / ptrSize
|
||||
off := (uintptr(p) + i - themoduledata.bss) / ptrSize
|
||||
bits := (*(*byte)(add(unsafe.Pointer(gcbssmask.bytedata), off/typeBitsPerByte)) >> ((off % typeBitsPerByte) * typeBitsWidth)) & typeMask
|
||||
*(*byte)(add(unsafe.Pointer(*mask), i/ptrSize)) = bits
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func memRound(p uintptr) uintptr {
|
||||
}
|
||||
|
||||
func initBloc() {
|
||||
bloc = memRound(uintptr(unsafe.Pointer(&end)))
|
||||
bloc = memRound(themoduledata.end)
|
||||
}
|
||||
|
||||
func sbrk(n uintptr) unsafe.Pointer {
|
||||
|
@ -289,10 +289,10 @@ func SetFinalizer(obj interface{}, finalizer interface{}) {
|
||||
// The relevant segments are: noptrdata, data, bss, noptrbss.
|
||||
// We cannot assume they are in any order or even contiguous,
|
||||
// due to external linking.
|
||||
if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrdata)) ||
|
||||
uintptr(unsafe.Pointer(&data)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&edata)) ||
|
||||
uintptr(unsafe.Pointer(&bss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&ebss)) ||
|
||||
uintptr(unsafe.Pointer(&noptrbss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
|
||||
if themoduledata.noptrdata <= uintptr(e.data) && uintptr(e.data) < themoduledata.enoptrdata ||
|
||||
themoduledata.data <= uintptr(e.data) && uintptr(e.data) < themoduledata.edata ||
|
||||
themoduledata.bss <= uintptr(e.data) && uintptr(e.data) < themoduledata.ebss ||
|
||||
themoduledata.noptrbss <= uintptr(e.data) && uintptr(e.data) < themoduledata.enoptrbss {
|
||||
return
|
||||
}
|
||||
throw("runtime.SetFinalizer: pointer not in allocated block")
|
||||
|
@ -130,9 +130,6 @@ const (
|
||||
_RootCount = 5
|
||||
)
|
||||
|
||||
// linker-provided
|
||||
var data, edata, bss, ebss, gcdata, gcbss, noptrdata, enoptrdata, noptrbss, enoptrbss, end struct{}
|
||||
|
||||
//go:linkname weak_cgo_allocate go.weak.runtime._cgo_allocate_internal
|
||||
var weak_cgo_allocate byte
|
||||
|
||||
@ -160,8 +157,8 @@ func gcinit() {
|
||||
|
||||
work.markfor = parforalloc(_MaxGcproc)
|
||||
gcpercent = readgogc()
|
||||
gcdatamask = unrollglobgcprog((*byte)(unsafe.Pointer(&gcdata)), uintptr(unsafe.Pointer(&edata))-uintptr(unsafe.Pointer(&data)))
|
||||
gcbssmask = unrollglobgcprog((*byte)(unsafe.Pointer(&gcbss)), uintptr(unsafe.Pointer(&ebss))-uintptr(unsafe.Pointer(&bss)))
|
||||
gcdatamask = unrollglobgcprog((*byte)(unsafe.Pointer(themoduledata.gcdata)), themoduledata.edata-themoduledata.data)
|
||||
gcbssmask = unrollglobgcprog((*byte)(unsafe.Pointer(themoduledata.gcbss)), themoduledata.ebss-themoduledata.bss)
|
||||
memstats.next_gc = heapminimum
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,10 @@ func markroot(desc *parfor, i uint32) {
|
||||
// Note: if you add a case here, please also update heapdump.go:dumproots.
|
||||
switch i {
|
||||
case _RootData:
|
||||
scanblock(uintptr(unsafe.Pointer(&data)), uintptr(unsafe.Pointer(&edata))-uintptr(unsafe.Pointer(&data)), gcdatamask.bytedata, &gcw)
|
||||
scanblock(themoduledata.data, themoduledata.edata-themoduledata.data, gcdatamask.bytedata, &gcw)
|
||||
|
||||
case _RootBss:
|
||||
scanblock(uintptr(unsafe.Pointer(&bss)), uintptr(unsafe.Pointer(&ebss))-uintptr(unsafe.Pointer(&bss)), gcbssmask.bytedata, &gcw)
|
||||
scanblock(themoduledata.bss, themoduledata.ebss-themoduledata.bss, gcbssmask.bytedata, &gcw)
|
||||
|
||||
case _RootFinalizers:
|
||||
for fb := allfin; fb != nil; fb = fb.alllink {
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var text struct{}
|
||||
|
||||
func dumpregs(r *context) {
|
||||
print("eax ", hex(r.eax), "\n")
|
||||
print("ebx ", hex(r.ebx), "\n")
|
||||
@ -29,7 +27,7 @@ func dumpregs(r *context) {
|
||||
func isgoexception(info *exceptionrecord, r *context) bool {
|
||||
// Only handle exception if executing instructions in Go binary
|
||||
// (not Windows library code).
|
||||
if r.eip < uint32(uintptr(unsafe.Pointer(&text))) || uint32(uintptr(unsafe.Pointer(&etext))) < r.eip {
|
||||
if r.eip < uint32(themoduledata.text) || uint32(themoduledata.etext) < r.eip {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var text struct{}
|
||||
|
||||
func dumpregs(r *context) {
|
||||
print("rax ", hex(r.rax), "\n")
|
||||
print("rbx ", hex(r.rbx), "\n")
|
||||
@ -36,7 +34,7 @@ func dumpregs(r *context) {
|
||||
func isgoexception(info *exceptionrecord, r *context) bool {
|
||||
// Only handle exception if executing instructions in Go binary
|
||||
// (not Windows library code).
|
||||
if r.rip < uint64(uintptr(unsafe.Pointer(&text))) || uint64(uintptr(unsafe.Pointer(&etext))) < r.rip {
|
||||
if r.rip < uint64(themoduledata.text) || uint64(themoduledata.etext) < r.rip {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -2293,8 +2293,6 @@ func _System() { _System() }
|
||||
func _ExternalCode() { _ExternalCode() }
|
||||
func _GC() { _GC() }
|
||||
|
||||
var etext struct{}
|
||||
|
||||
// Called if we receive a SIGPROF signal.
|
||||
func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
|
||||
if prof.hz == 0 {
|
||||
@ -2408,7 +2406,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
|
||||
// If all of the above has failed, account it against abstract "System" or "GC".
|
||||
n = 2
|
||||
// "ExternalCode" is better than "etext".
|
||||
if pc > uintptr(unsafe.Pointer(&etext)) {
|
||||
if pc > themoduledata.etext {
|
||||
pc = funcPC(_ExternalCode) + _PCQuantum
|
||||
}
|
||||
stk[0] = pc
|
||||
|
@ -119,29 +119,29 @@ func raceinit() uintptr {
|
||||
// Round data segment to page boundaries, because it's used in mmap().
|
||||
start := ^uintptr(0)
|
||||
end := uintptr(0)
|
||||
if start > uintptr(unsafe.Pointer(&noptrdata)) {
|
||||
start = uintptr(unsafe.Pointer(&noptrdata))
|
||||
if start > themoduledata.noptrdata {
|
||||
start = themoduledata.noptrdata
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&data)) {
|
||||
start = uintptr(unsafe.Pointer(&data))
|
||||
if start > themoduledata.data {
|
||||
start = themoduledata.data
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&noptrbss)) {
|
||||
start = uintptr(unsafe.Pointer(&noptrbss))
|
||||
if start > themoduledata.noptrbss {
|
||||
start = themoduledata.noptrbss
|
||||
}
|
||||
if start > uintptr(unsafe.Pointer(&bss)) {
|
||||
start = uintptr(unsafe.Pointer(&bss))
|
||||
if start > themoduledata.bss {
|
||||
start = themoduledata.bss
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&enoptrdata)) {
|
||||
end = uintptr(unsafe.Pointer(&enoptrdata))
|
||||
if end < themoduledata.enoptrdata {
|
||||
end = themoduledata.enoptrdata
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&edata)) {
|
||||
end = uintptr(unsafe.Pointer(&edata))
|
||||
if end < themoduledata.edata {
|
||||
end = themoduledata.edata
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&enoptrbss)) {
|
||||
end = uintptr(unsafe.Pointer(&enoptrbss))
|
||||
if end < themoduledata.enoptrbss {
|
||||
end = themoduledata.enoptrbss
|
||||
}
|
||||
if end < uintptr(unsafe.Pointer(&ebss)) {
|
||||
end = uintptr(unsafe.Pointer(&ebss))
|
||||
if end < themoduledata.ebss {
|
||||
end = themoduledata.ebss
|
||||
}
|
||||
size := round(end-start, _PageSize)
|
||||
racecall(&__tsan_map_shadow, start, size, 0, 0)
|
||||
|
@ -424,15 +424,13 @@ func gomcache() *mcache {
|
||||
return getg().m.mcache
|
||||
}
|
||||
|
||||
var typelink, etypelink [0]byte
|
||||
|
||||
//go:linkname reflect_typelinks reflect.typelinks
|
||||
//go:nosplit
|
||||
func reflect_typelinks() []*_type {
|
||||
var ret []*_type
|
||||
sp := (*slice)(unsafe.Pointer(&ret))
|
||||
sp.array = (*byte)(unsafe.Pointer(&typelink))
|
||||
sp.len = uint((uintptr(unsafe.Pointer(&etypelink)) - uintptr(unsafe.Pointer(&typelink))) / unsafe.Sizeof(ret[0]))
|
||||
sp.array = (*byte)(unsafe.Pointer(themoduledata.typelink))
|
||||
sp.len = uint((themoduledata.etypelink - themoduledata.typelink) / unsafe.Sizeof(ret[0]))
|
||||
sp.cap = sp.len
|
||||
return ret
|
||||
}
|
||||
|
@ -29,15 +29,27 @@ const (
|
||||
_ArgsSizeUnknown = -0x80000000
|
||||
)
|
||||
|
||||
var (
|
||||
pclntable []byte
|
||||
ftab []functab
|
||||
filetab []uint32
|
||||
// moduledata records information about the layout of the executable
|
||||
// image. It is written by the linker. Any changes here must be
|
||||
// matched changes to the code in cmd/internal/ld/symtab.go:symtab.
|
||||
type moduledata struct {
|
||||
pclntable []byte
|
||||
ftab []functab
|
||||
filetab []uint32
|
||||
pclntab, epclntab, findfunctab uintptr
|
||||
minpc, maxpc uintptr
|
||||
|
||||
pclntab, epclntab, findfunctab struct{} // linker symbols
|
||||
text, etext uintptr
|
||||
noptrdata, enoptrdata uintptr
|
||||
data, edata uintptr
|
||||
bss, ebss uintptr
|
||||
noptrbss, enoptrbss uintptr
|
||||
end, gcdata, gcbss uintptr
|
||||
|
||||
minpc, maxpc uintptr
|
||||
)
|
||||
typelink, etypelink uintptr
|
||||
}
|
||||
|
||||
var themoduledata moduledata // linker symbol
|
||||
|
||||
type functab struct {
|
||||
entry uintptr
|
||||
@ -64,38 +76,38 @@ func symtabinit() {
|
||||
// See golang.org/s/go12symtab for header: 0xfffffffb,
|
||||
// two zero bytes, a byte giving the PC quantum,
|
||||
// and a byte giving the pointer width in bytes.
|
||||
pcln := (*[8]byte)(unsafe.Pointer(&pclntab))
|
||||
pcln32 := (*[2]uint32)(unsafe.Pointer(&pclntab))
|
||||
pcln := (*[8]byte)(unsafe.Pointer(themoduledata.pclntab))
|
||||
pcln32 := (*[2]uint32)(unsafe.Pointer(themoduledata.pclntab))
|
||||
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]))
|
||||
throw("invalid function symbol table\n")
|
||||
}
|
||||
|
||||
// pclntable is all bytes of pclntab symbol.
|
||||
sp := (*sliceStruct)(unsafe.Pointer(&pclntable))
|
||||
sp.array = unsafe.Pointer(&pclntab)
|
||||
sp.len = int(uintptr(unsafe.Pointer(&epclntab)) - uintptr(unsafe.Pointer(&pclntab)))
|
||||
sp := (*sliceStruct)(unsafe.Pointer(&themoduledata.pclntable))
|
||||
sp.array = unsafe.Pointer(themoduledata.pclntab)
|
||||
sp.len = int(uintptr(unsafe.Pointer(themoduledata.epclntab)) - uintptr(unsafe.Pointer(themoduledata.pclntab)))
|
||||
sp.cap = sp.len
|
||||
|
||||
// ftab is lookup table for function by program counter.
|
||||
nftab := int(*(*uintptr)(add(unsafe.Pointer(pcln), 8)))
|
||||
p := add(unsafe.Pointer(pcln), 8+ptrSize)
|
||||
sp = (*sliceStruct)(unsafe.Pointer(&ftab))
|
||||
sp = (*sliceStruct)(unsafe.Pointer(&themoduledata.ftab))
|
||||
sp.array = p
|
||||
sp.len = nftab + 1
|
||||
sp.cap = sp.len
|
||||
for i := 0; i < nftab; i++ {
|
||||
// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
|
||||
if ftab[i].entry > ftab[i+1].entry {
|
||||
f1 := (*_func)(unsafe.Pointer(&pclntable[ftab[i].funcoff]))
|
||||
f2 := (*_func)(unsafe.Pointer(&pclntable[ftab[i+1].funcoff]))
|
||||
if themoduledata.ftab[i].entry > themoduledata.ftab[i+1].entry {
|
||||
f1 := (*_func)(unsafe.Pointer(&themoduledata.pclntable[themoduledata.ftab[i].funcoff]))
|
||||
f2 := (*_func)(unsafe.Pointer(&themoduledata.pclntable[themoduledata.ftab[i+1].funcoff]))
|
||||
f2name := "end"
|
||||
if i+1 < nftab {
|
||||
f2name = funcname(f2)
|
||||
}
|
||||
println("function symbol table not sorted by program counter:", hex(ftab[i].entry), funcname(f1), ">", hex(ftab[i+1].entry), f2name)
|
||||
println("function symbol table not sorted by program counter:", hex(themoduledata.ftab[i].entry), funcname(f1), ">", hex(themoduledata.ftab[i+1].entry), f2name)
|
||||
for j := 0; j <= i; j++ {
|
||||
print("\t", hex(ftab[j].entry), " ", funcname((*_func)(unsafe.Pointer(&pclntable[ftab[j].funcoff]))), "\n")
|
||||
print("\t", hex(themoduledata.ftab[j].entry), " ", funcname((*_func)(unsafe.Pointer(&themoduledata.pclntable[themoduledata.ftab[j].funcoff]))), "\n")
|
||||
}
|
||||
throw("invalid runtime symbol table")
|
||||
}
|
||||
@ -104,19 +116,19 @@ func symtabinit() {
|
||||
// The ftab ends with a half functab consisting only of
|
||||
// 'entry', followed by a uint32 giving the pcln-relative
|
||||
// offset of the file table.
|
||||
sp = (*sliceStruct)(unsafe.Pointer(&filetab))
|
||||
end := unsafe.Pointer(&ftab[nftab].funcoff) // just beyond ftab
|
||||
sp = (*sliceStruct)(unsafe.Pointer(&themoduledata.filetab))
|
||||
end := unsafe.Pointer(&themoduledata.ftab[nftab].funcoff) // just beyond ftab
|
||||
fileoffset := *(*uint32)(end)
|
||||
sp.array = unsafe.Pointer(&pclntable[fileoffset])
|
||||
sp.array = unsafe.Pointer(&themoduledata.pclntable[fileoffset])
|
||||
// length is in first element of array.
|
||||
// set len to 1 so we can get first element.
|
||||
sp.len = 1
|
||||
sp.cap = 1
|
||||
sp.len = int(filetab[0])
|
||||
sp.len = int(themoduledata.filetab[0])
|
||||
sp.cap = sp.len
|
||||
|
||||
minpc = ftab[0].entry
|
||||
maxpc = ftab[nftab].entry
|
||||
themoduledata.minpc = themoduledata.ftab[0].entry
|
||||
themoduledata.maxpc = themoduledata.ftab[nftab].entry
|
||||
}
|
||||
|
||||
// FuncForPC returns a *Func describing the function that contains the
|
||||
@ -147,33 +159,33 @@ func (f *Func) FileLine(pc uintptr) (file string, line int) {
|
||||
}
|
||||
|
||||
func findfunc(pc uintptr) *_func {
|
||||
if pc < minpc || pc >= maxpc {
|
||||
if pc < themoduledata.minpc || pc >= themoduledata.maxpc {
|
||||
return nil
|
||||
}
|
||||
const nsub = uintptr(len(findfuncbucket{}.subbuckets))
|
||||
|
||||
x := pc - minpc
|
||||
x := pc - themoduledata.minpc
|
||||
b := x / pcbucketsize
|
||||
i := x % pcbucketsize / (pcbucketsize / nsub)
|
||||
|
||||
ffb := (*findfuncbucket)(add(unsafe.Pointer(&findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
|
||||
ffb := (*findfuncbucket)(add(unsafe.Pointer(themoduledata.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
|
||||
idx := ffb.idx + uint32(ffb.subbuckets[i])
|
||||
if pc < ftab[idx].entry {
|
||||
if pc < themoduledata.ftab[idx].entry {
|
||||
throw("findfunc: bad findfunctab entry")
|
||||
}
|
||||
|
||||
// linear search to find func with pc >= entry.
|
||||
for ftab[idx+1].entry <= pc {
|
||||
for themoduledata.ftab[idx+1].entry <= pc {
|
||||
idx++
|
||||
}
|
||||
return (*_func)(unsafe.Pointer(&pclntable[ftab[idx].funcoff]))
|
||||
return (*_func)(unsafe.Pointer(&themoduledata.pclntable[themoduledata.ftab[idx].funcoff]))
|
||||
}
|
||||
|
||||
func pcvalue(f *_func, off int32, targetpc uintptr, strict bool) int32 {
|
||||
if off == 0 {
|
||||
return -1
|
||||
}
|
||||
p := pclntable[off:]
|
||||
p := themoduledata.pclntable[off:]
|
||||
pc := f.entry
|
||||
val := int32(-1)
|
||||
for {
|
||||
@ -195,7 +207,7 @@ func pcvalue(f *_func, off int32, targetpc uintptr, strict bool) int32 {
|
||||
|
||||
print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
|
||||
|
||||
p = pclntable[off:]
|
||||
p = themoduledata.pclntable[off:]
|
||||
pc = f.entry
|
||||
val = -1
|
||||
for {
|
||||
@ -215,7 +227,7 @@ func cfuncname(f *_func) *byte {
|
||||
if f == nil || f.nameoff == 0 {
|
||||
return nil
|
||||
}
|
||||
return (*byte)(unsafe.Pointer(&pclntable[f.nameoff]))
|
||||
return (*byte)(unsafe.Pointer(&themoduledata.pclntable[f.nameoff]))
|
||||
}
|
||||
|
||||
func funcname(f *_func) string {
|
||||
@ -225,11 +237,11 @@ func funcname(f *_func) string {
|
||||
func funcline1(f *_func, targetpc uintptr, strict bool) (file string, line int32) {
|
||||
fileno := int(pcvalue(f, f.pcfile, targetpc, strict))
|
||||
line = pcvalue(f, f.pcln, targetpc, strict)
|
||||
if fileno == -1 || line == -1 || fileno >= len(filetab) {
|
||||
if fileno == -1 || line == -1 || fileno >= len(themoduledata.filetab) {
|
||||
// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
|
||||
return "?", 0
|
||||
}
|
||||
file = gostringnocopy(&pclntable[filetab[fileno]])
|
||||
file = gostringnocopy(&themoduledata.pclntable[themoduledata.filetab[fileno]])
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user