]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6l: call runtime.addmoduledata from .init_array
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Wed, 1 Apr 2015 01:17:43 +0000 (14:17 +1300)
committerIan Lance Taylor <iant@golang.org>
Wed, 15 Apr 2015 23:54:20 +0000 (23:54 +0000)
Change-Id: I09e84161d106960a69972f5fc845a1e40c28e58f
Reviewed-on: https://go-review.googlesource.com/8331
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/6l/asm.go
src/cmd/internal/ld/data.go
src/cmd/internal/ld/elf.go
src/cmd/internal/ld/symtab.go
src/runtime/asm_amd64.s
src/runtime/symtab.go

index 329eb657a94dd7b34a202d2163c069372cbeb8a2..5bfda22c8cecb39dc05c0811d492d27018d8af76 100644 (file)
@@ -61,7 +61,61 @@ func needlib(name string) int {
        return 0
 }
 
+func Addcall(ctxt *ld.Link, s *ld.LSym, t *ld.LSym) int64 {
+       s.Reachable = true
+       i := s.Size
+       s.Size += 4
+       ld.Symgrow(ctxt, s, s.Size)
+       r := ld.Addrel(s)
+       r.Sym = t
+       r.Off = int32(i)
+       r.Type = ld.R_CALL
+       r.Siz = 4
+       return i + int64(r.Siz)
+}
+
 func gentext() {
+       if !ld.DynlinkingGo() {
+               return
+       }
+       addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0)
+       if addmoduledata.Type == ld.STEXT {
+               // we're linking a module containing the runtime -> no need for
+               // an init function
+               return
+       }
+       addmoduledata.Reachable = true
+       initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
+       initfunc.Type = ld.STEXT
+       initfunc.Local = true
+       initfunc.Reachable = true
+       o := func(op ...uint8) {
+               for _, op1 := range op {
+                       ld.Adduint8(ld.Ctxt, initfunc, op1)
+               }
+       }
+       // 0000000000000000 <local.dso_init>:
+       //    0:        48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 7 <local.dso_init+0x7>
+       //                      3: R_X86_64_PC32        runtime.firstmoduledata-0x4
+       o(0x48, 0x8d, 0x3d)
+       ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Linklookup(ld.Ctxt, "runtime.firstmoduledata", 0), 0)
+       //    7:        e8 00 00 00 00          callq  c <local.dso_init+0xc>
+       //                      8: R_X86_64_PLT32       runtime.addmoduledata-0x4
+       o(0xe8)
+       Addcall(ld.Ctxt, initfunc, addmoduledata)
+       //    c:        c3                      retq
+       o(0xc3)
+       if ld.Ctxt.Etextp != nil {
+               ld.Ctxt.Etextp.Next = initfunc
+       } else {
+               ld.Ctxt.Textp = initfunc
+       }
+       ld.Ctxt.Etextp = initfunc
+       initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
+       initarray_entry.Reachable = true
+       initarray_entry.Local = true
+       initarray_entry.Type = ld.SINITARR
+       ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
 }
 
 func adddynrela(rela *ld.LSym, s *ld.LSym, r *ld.Reloc) {
index 75c8dea96dc92d7f685f2cc2243a975260f90c2f..4175d4d3a1c8dde3f4481011e29500a53de83273 100644 (file)
@@ -1331,10 +1331,15 @@ func dodata() {
 
        sect.Length = uint64(datsize) - sect.Vaddr
 
+       hasinitarr := Linkshared
+
        /* shared library initializer */
        switch Buildmode {
        case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared:
-               // TODO(mwhudson): switch on Linkshared
+               hasinitarr = true
+       }
+
+       if hasinitarr {
                sect := addsection(&Segdata, ".init_array", 06)
                sect.Align = maxalign(s, SINITARR)
                datsize = Rnd(datsize, int64(sect.Align))
index eb2c28fada252fe50051f3e25b1cb7269be59ff2..790c8713ded36f9b6034a8dfabb4ac6b3266b9ec 100644 (file)
@@ -1658,9 +1658,15 @@ func doelf() {
                Addstring(shstrtab, ".note.GNU-stack")
        }
 
+       hasinitarr := Linkshared
+
+       /* shared library initializer */
        switch Buildmode {
        case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared:
-               // TODO(mwhudson): switch on Linkshared
+               hasinitarr = true
+       }
+
+       if hasinitarr {
                Addstring(shstrtab, ".init_array")
                switch Thearch.Thechar {
                case '6', '7', '9':
index 1898a9b818b3ff4da3167a4cbdc08b73b04411f3..e7b107b6691e93e7e37aa38663608d1af857454e 100644 (file)
@@ -464,4 +464,11 @@ func symtab() {
        // The rest of moduledata is zero initialized.
        moduledata.Size = moduledatasize
        Symgrow(Ctxt, moduledata, moduledatasize)
+
+       lastmoduledatap := Linklookup(Ctxt, "runtime.lastmoduledatap", 0)
+       if lastmoduledatap.Type != SDYNIMPORT {
+               lastmoduledatap.Type = SNOPTRDATA
+               lastmoduledatap.Size = 0 // overwrite existing value
+               Addaddr(Ctxt, lastmoduledatap, moduledata)
+       }
 }
index 0e5389fbd7d2658db9f3f55f2ba70e67a54bf5f9..468763f09545f022380feb9450e17cdfd370fd4a 100644 (file)
@@ -1692,3 +1692,10 @@ TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
        MOVQ    addr+0(FP), AX
        PREFETCHNTA     (AX)
        RET
+
+// This is called from .init_array and follows the platform, not Go, ABI.
+TEXT runtime·addmoduledata(SB),NOSPLIT,$0-8
+       MOVQ    runtime·lastmoduledatap(SB), AX
+       MOVQ    DI, moduledata_next(AX)
+       MOVQ    DI, runtime·lastmoduledatap(SB)
+       RET
index 86c1408b850a058d2f52d7d9f0ab7616742c5ebd..e55c357900bc3d10ece40c06c5d7438ff7e0bb59 100644 (file)
@@ -60,7 +60,8 @@ type moduledata struct {
        next *moduledata
 }
 
-var firstmoduledata moduledata // linker symbol
+var firstmoduledata moduledata  // linker symbol
+var lastmoduledatap *moduledata // linker symbol
 
 type functab struct {
        entry   uintptr