]> Cypherpunks repositories - gostls13.git/commitdiff
runtime, cmd/internal/ld: initialize themoduledata slices directly
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Sun, 15 Mar 2015 22:53:08 +0000 (11:53 +1300)
committerIan Lance Taylor <iant@golang.org>
Wed, 8 Apr 2015 16:20:57 +0000 (16:20 +0000)
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: Ian Lance Taylor <iant@golang.org>
src/cmd/internal/ld/data.go
src/cmd/internal/ld/pcln.go
src/cmd/internal/ld/symtab.go
src/runtime/proc1.go
src/runtime/runtime1.go
src/runtime/symtab.go

index bc2021aaf07bfb74dbc71e7b45f63401be3b5795..e67451419f7d2076f382f52949fff292fb3d47a9 100644 (file)
@@ -102,6 +102,10 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
        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 {
        return setuintxx(ctxt, s, r, uint64(v), 1)
 }
index 0250ca0eb829cac133d7f7f88a8ab76a514c402a..65ca0c32eab6b7e3cc5d6ac45d5294939cef782a 100644 (file)
@@ -202,6 +202,13 @@ func container(s *LSym) int {
 
 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() {
        funcdata_bytes := int64(0)
        ftab := Linklookup(Ctxt, "runtime.pclntab", 0)
@@ -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)
        setuint32(Ctxt, ftab, 0, 0xfffffffb)
        setuint8(Ctxt, ftab, 6, uint8(Thearch.Minlc))
        setuint8(Ctxt, ftab, 7, uint8(Thearch.Ptrsize))
        setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize))
+       pclntabPclntabOffset = int32(8 + Thearch.Ptrsize)
 
        nfunc = 0
        var last *LSym
@@ -246,6 +255,10 @@ func pclntab() {
                        pcln = &pclntab_zpcln
                }
 
+               if pclntabFirstFunc == nil {
+                       pclntabFirstFunc = Ctxt.Cursym
+               }
+
                funcstart = int32(len(ftab.P))
                funcstart += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
 
@@ -330,6 +343,7 @@ func pclntab() {
                nfunc++
        }
 
+       pclntabLastFunc = last
        // Final entry of table is just end pc.
        setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size)
 
@@ -337,6 +351,7 @@ func pclntab() {
        start := int32(len(ftab.P))
 
        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))
 
        Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4)
index c5b32fd21f9483b46324106017334ac298e46fc9..4e1bfc685df077bc74d546a642e779b8b0e72b01 100644 (file)
@@ -348,6 +348,8 @@ func symtab() {
        symt.Size = 0
        symt.Reachable = true
 
+       ntypelinks := 0
+
        // assign specific types so that they sort together.
        // within a type they sort by size, so the .* symbols
        // just defined above will be first.
@@ -363,6 +365,7 @@ func symtab() {
                }
 
                if strings.HasPrefix(s.Name, "go.typelink.") {
+                       ntypelinks++
                        s.Type = STYPELINK
                        s.Hide = 1
                        s.Outer = symtypelink
@@ -392,21 +395,29 @@ func symtab() {
        // 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.
+       // This code uses several global variables that are set by pcln.go:pclntab.
        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
+       // The pclntab slice
        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))
-       // 2 more uintptrs (minpc, maxpc), uninitalized
-       moduledata.Size += int64(2 * Thearch.Ptrsize)
-       Symgrow(Ctxt, moduledata, moduledata.Size)
-       // more initialized uintptrs
+       // minpc, maxpc
+       Addaddr(Ctxt, moduledata, pclntabFirstFunc)
+       Addaddrplus(Ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
+       // pointers to specific parts of the module
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.text", 0))
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etext", 0))
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrdata", 0))
@@ -420,6 +431,8 @@ func symtab() {
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.end", 0))
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcdata", 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.etypelink", 0))
+       adduint(Ctxt, moduledata, uint64(ntypelinks))
+       adduint(Ctxt, moduledata, uint64(ntypelinks))
 }
index b8ea36c5ba9306d9915fc973eb30b6bb8a8282ad..772fa0962afaefaddc43912434da05045df6b31d 100644 (file)
@@ -51,7 +51,7 @@ func schedinit() {
        framepointer_enabled = haveexperiment("framepointer")
 
        tracebackinit()
-       symtabinit()
+       symtabverify()
        stackinit()
        mallocinit()
        mcommoninit(_g_.m)
index 072a58552e6dc5cd6b3b3c55af21a924eea7ff2e..5fddc582e92ea9ab9ca9acffe1f2a859ba61a94d 100644 (file)
@@ -427,12 +427,7 @@ func gomcache() *mcache {
 //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(themoduledata.typelink))
-       sp.len = uint((themoduledata.etypelink - themoduledata.typelink) / unsafe.Sizeof(ret[0]))
-       sp.cap = sp.len
-       return ret
+       return themoduledata.typelinks
 }
 
 // TODO: move back into mgc.go
index 689a3361a8bce10b1dd688b475d2e968442b10a5..8ee80c8eedadfc1ab01eab5e60581e85b2a97006 100644 (file)
@@ -33,11 +33,11 @@ const (
 // 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
+       pclntable    []byte
+       ftab         []functab
+       filetab      []uint32
+       findfunctab  uintptr
+       minpc, maxpc uintptr
 
        text, etext           uintptr
        noptrdata, enoptrdata uintptr
@@ -46,7 +46,7 @@ type moduledata struct {
        noptrbss, enoptrbss   uintptr
        end, gcdata, gcbss    uintptr
 
-       typelink, etypelink uintptr
+       typelinks []*_type
 }
 
 var themoduledata moduledata // linker symbol
@@ -72,30 +72,19 @@ type findfuncbucket struct {
        subbuckets [16]byte
 }
 
-func symtabinit() {
+func symtabverify() {
        // 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(themoduledata.pclntab))
-       pcln32 := (*[2]uint32)(unsafe.Pointer(themoduledata.pclntab))
+       pcln := *(**[8]byte)(unsafe.Pointer(&themoduledata.pclntable))
+       pcln32 := *(**[2]uint32)(unsafe.Pointer(&themoduledata.pclntable))
        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(&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(&themoduledata.ftab))
-       sp.array = p
-       sp.len = nftab + 1
-       sp.cap = sp.len
+       nftab := len(themoduledata.ftab) - 1
        for i := 0; i < nftab; i++ {
                // NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
                if themoduledata.ftab[i].entry > themoduledata.ftab[i+1].entry {
@@ -113,22 +102,10 @@ 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(&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
+       if themoduledata.minpc != themoduledata.ftab[0].entry ||
+               themoduledata.maxpc != themoduledata.ftab[nftab].entry {
+               throw("minpc or maxpc invalid")
+       }
 }
 
 // FuncForPC returns a *Func describing the function that contains the