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

runtime, cmd/internal/ld: initialize themoduledata slices directly

This CL is quite conservative in some ways.  It continues to define
symbols that have no real purpose (e.g. epclntab).  These could be
deleted if there is no concern that external tools might look for them.

It would also now be possible to make some changes to the pcln data but
I get the impression that would definitely require some thought and
discussion.

Change-Id: Ib33cde07e4ec38ecc1d6c319a10138c9347933a3
Reviewed-on: https://go-review.googlesource.com/7616
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent c468f946
...@@ -102,6 +102,10 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 { ...@@ -102,6 +102,10 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
return adduintxx(ctxt, s, v, 8) return adduintxx(ctxt, s, v, 8)
} }
func adduint(ctxt *Link, s *LSym, v uint64) int64 {
return adduintxx(ctxt, s, v, Thearch.Intsize)
}
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 { func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
return setuintxx(ctxt, s, r, uint64(v), 1) return setuintxx(ctxt, s, r, uint64(v), 1)
} }
......
...@@ -202,6 +202,13 @@ func container(s *LSym) int { ...@@ -202,6 +202,13 @@ func container(s *LSym) int {
var pclntab_zpcln Pcln var pclntab_zpcln Pcln
// These variables are used to initialize runtime.themoduledata, see symtab.go:symtab.
var pclntabNfunc int32
var pclntabFiletabOffset int32
var pclntabPclntabOffset int32
var pclntabFirstFunc *LSym
var pclntabLastFunc *LSym
func pclntab() { func pclntab() {
funcdata_bytes := int64(0) funcdata_bytes := int64(0)
ftab := Linklookup(Ctxt, "runtime.pclntab", 0) ftab := Linklookup(Ctxt, "runtime.pclntab", 0)
...@@ -222,11 +229,13 @@ func pclntab() { ...@@ -222,11 +229,13 @@ func pclntab() {
} }
} }
pclntabNfunc = nfunc
Symgrow(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize)+4) Symgrow(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize)+4)
setuint32(Ctxt, ftab, 0, 0xfffffffb) setuint32(Ctxt, ftab, 0, 0xfffffffb)
setuint8(Ctxt, ftab, 6, uint8(Thearch.Minlc)) setuint8(Ctxt, ftab, 6, uint8(Thearch.Minlc))
setuint8(Ctxt, ftab, 7, uint8(Thearch.Ptrsize)) setuint8(Ctxt, ftab, 7, uint8(Thearch.Ptrsize))
setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize)) setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize))
pclntabPclntabOffset = int32(8 + Thearch.Ptrsize)
nfunc = 0 nfunc = 0
var last *LSym var last *LSym
...@@ -246,6 +255,10 @@ func pclntab() { ...@@ -246,6 +255,10 @@ func pclntab() {
pcln = &pclntab_zpcln pcln = &pclntab_zpcln
} }
if pclntabFirstFunc == nil {
pclntabFirstFunc = Ctxt.Cursym
}
funcstart = int32(len(ftab.P)) funcstart = int32(len(ftab.P))
funcstart += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1) funcstart += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
...@@ -330,6 +343,7 @@ func pclntab() { ...@@ -330,6 +343,7 @@ func pclntab() {
nfunc++ nfunc++
} }
pclntabLastFunc = last
// Final entry of table is just end pc. // Final entry of table is just end pc.
setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size) setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size)
...@@ -337,6 +351,7 @@ func pclntab() { ...@@ -337,6 +351,7 @@ func pclntab() {
start := int32(len(ftab.P)) start := int32(len(ftab.P))
start += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1) start += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
pclntabFiletabOffset = start
setuint32(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint32(start)) setuint32(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint32(start))
Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4) Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4)
......
...@@ -348,6 +348,8 @@ func symtab() { ...@@ -348,6 +348,8 @@ func symtab() {
symt.Size = 0 symt.Size = 0
symt.Reachable = true symt.Reachable = true
ntypelinks := 0
// assign specific types so that they sort together. // assign specific types so that they sort together.
// within a type they sort by size, so the .* symbols // within a type they sort by size, so the .* symbols
// just defined above will be first. // just defined above will be first.
...@@ -363,6 +365,7 @@ func symtab() { ...@@ -363,6 +365,7 @@ func symtab() {
} }
if strings.HasPrefix(s.Name, "go.typelink.") { if strings.HasPrefix(s.Name, "go.typelink.") {
ntypelinks++
s.Type = STYPELINK s.Type = STYPELINK
s.Hide = 1 s.Hide = 1
s.Outer = symtypelink s.Outer = symtypelink
...@@ -392,21 +395,29 @@ func symtab() { ...@@ -392,21 +395,29 @@ func symtab() {
// Information about the layout of the executable image for the // Information about the layout of the executable image for the
// runtime to use. Any changes here must be matched by changes to // runtime to use. Any changes here must be matched by changes to
// the definition of moduledata in runtime/symtab.go. // the definition of moduledata in runtime/symtab.go.
// This code uses several global variables that are set by pcln.go:pclntab.
moduledata := Linklookup(Ctxt, "runtime.themoduledata", 0) moduledata := Linklookup(Ctxt, "runtime.themoduledata", 0)
moduledata.Type = SNOPTRDATA moduledata.Type = SNOPTRDATA
moduledata.Size = 0 // truncate symbol back to 0 bytes to reinitialize moduledata.Size = 0 // truncate symbol back to 0 bytes to reinitialize
moduledata.Reachable = true moduledata.Reachable = true
// Three slices (pclntable, ftab, filetab), uninitalized // The pclntab slice
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.pclntab", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.epclntab", 0)) adduint(Ctxt, moduledata, uint64(Linklookup(Ctxt, "runtime.pclntab", 0).Size))
adduint(Ctxt, moduledata, uint64(Linklookup(Ctxt, "runtime.pclntab", 0).Size))
// The ftab slice
Addaddrplus(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0), int64(pclntabPclntabOffset))
adduint(Ctxt, moduledata, uint64(pclntabNfunc+1))
adduint(Ctxt, moduledata, uint64(pclntabNfunc+1))
// The filetab slice
Addaddrplus(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0), int64(pclntabFiletabOffset))
adduint(Ctxt, moduledata, uint64(Ctxt.Nhistfile))
adduint(Ctxt, moduledata, uint64(Ctxt.Nhistfile))
// findfunctab
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.findfunctab", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.findfunctab", 0))
// 2 more uintptrs (minpc, maxpc), uninitalized // minpc, maxpc
moduledata.Size += int64(2 * Thearch.Ptrsize) Addaddr(Ctxt, moduledata, pclntabFirstFunc)
Symgrow(Ctxt, moduledata, moduledata.Size) Addaddrplus(Ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
// more initialized uintptrs // pointers to specific parts of the module
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.text", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.text", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etext", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etext", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrdata", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrdata", 0))
...@@ -420,6 +431,8 @@ func symtab() { ...@@ -420,6 +431,8 @@ func symtab() {
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.end", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.end", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcdata", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcdata", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0))
// The typelinks slice
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etypelink", 0)) adduint(Ctxt, moduledata, uint64(ntypelinks))
adduint(Ctxt, moduledata, uint64(ntypelinks))
} }
...@@ -51,7 +51,7 @@ func schedinit() { ...@@ -51,7 +51,7 @@ func schedinit() {
framepointer_enabled = haveexperiment("framepointer") framepointer_enabled = haveexperiment("framepointer")
tracebackinit() tracebackinit()
symtabinit() symtabverify()
stackinit() stackinit()
mallocinit() mallocinit()
mcommoninit(_g_.m) mcommoninit(_g_.m)
......
...@@ -427,12 +427,7 @@ func gomcache() *mcache { ...@@ -427,12 +427,7 @@ func gomcache() *mcache {
//go:linkname reflect_typelinks reflect.typelinks //go:linkname reflect_typelinks reflect.typelinks
//go:nosplit //go:nosplit
func reflect_typelinks() []*_type { func reflect_typelinks() []*_type {
var ret []*_type return themoduledata.typelinks
sp := (*slice)(unsafe.Pointer(&ret))
sp.array = (*byte)(unsafe.Pointer(themoduledata.typelink))
sp.len = uint((themoduledata.etypelink - themoduledata.typelink) / unsafe.Sizeof(ret[0]))
sp.cap = sp.len
return ret
} }
// TODO: move back into mgc.go // TODO: move back into mgc.go
......
...@@ -33,11 +33,11 @@ const ( ...@@ -33,11 +33,11 @@ const (
// image. It is written by the linker. Any changes here must be // image. It is written by the linker. Any changes here must be
// matched changes to the code in cmd/internal/ld/symtab.go:symtab. // matched changes to the code in cmd/internal/ld/symtab.go:symtab.
type moduledata struct { type moduledata struct {
pclntable []byte pclntable []byte
ftab []functab ftab []functab
filetab []uint32 filetab []uint32
pclntab, epclntab, findfunctab uintptr findfunctab uintptr
minpc, maxpc uintptr minpc, maxpc uintptr
text, etext uintptr text, etext uintptr
noptrdata, enoptrdata uintptr noptrdata, enoptrdata uintptr
...@@ -46,7 +46,7 @@ type moduledata struct { ...@@ -46,7 +46,7 @@ type moduledata struct {
noptrbss, enoptrbss uintptr noptrbss, enoptrbss uintptr
end, gcdata, gcbss uintptr end, gcdata, gcbss uintptr
typelink, etypelink uintptr typelinks []*_type
} }
var themoduledata moduledata // linker symbol var themoduledata moduledata // linker symbol
...@@ -72,30 +72,19 @@ type findfuncbucket struct { ...@@ -72,30 +72,19 @@ type findfuncbucket struct {
subbuckets [16]byte subbuckets [16]byte
} }
func symtabinit() { func symtabverify() {
// 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(themoduledata.pclntab)) pcln := *(**[8]byte)(unsafe.Pointer(&themoduledata.pclntable))
pcln32 := (*[2]uint32)(unsafe.Pointer(themoduledata.pclntab)) pcln32 := *(**[2]uint32)(unsafe.Pointer(&themoduledata.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")
} }
// pclntable is all bytes of pclntab symbol.
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. // ftab is lookup table for function by program counter.
nftab := int(*(*uintptr)(add(unsafe.Pointer(pcln), 8))) nftab := len(themoduledata.ftab) - 1
p := add(unsafe.Pointer(pcln), 8+ptrSize)
sp = (*sliceStruct)(unsafe.Pointer(&themoduledata.ftab))
sp.array = p
sp.len = nftab + 1
sp.cap = sp.len
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 themoduledata.ftab[i].entry > themoduledata.ftab[i+1].entry { if themoduledata.ftab[i].entry > themoduledata.ftab[i+1].entry {
...@@ -113,22 +102,10 @@ func symtabinit() { ...@@ -113,22 +102,10 @@ func symtabinit() {
} }
} }
// The ftab ends with a half functab consisting only of if themoduledata.minpc != themoduledata.ftab[0].entry ||
// 'entry', followed by a uint32 giving the pcln-relative themoduledata.maxpc != themoduledata.ftab[nftab].entry {
// offset of the file table. throw("minpc or maxpc invalid")
sp = (*sliceStruct)(unsafe.Pointer(&themoduledata.filetab)) }
end := unsafe.Pointer(&themoduledata.ftab[nftab].funcoff) // just beyond ftab
fileoffset := *(*uint32)(end)
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(themoduledata.filetab[0])
sp.cap = sp.len
themoduledata.minpc = themoduledata.ftab[0].entry
themoduledata.maxpc = themoduledata.ftab[nftab].entry
} }
// FuncForPC returns a *Func describing the function that contains the // FuncForPC returns a *Func describing the function that contains the
......
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