]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: call moduledata symbols "local.moduledata" if they are created by the linker
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Wed, 19 Aug 2015 01:34:33 +0000 (13:34 +1200)
committerIan Lance Taylor <iant@golang.org>
Tue, 25 Aug 2015 23:48:12 +0000 (23:48 +0000)
This was always a bit confusing, but it also fixes a problem: runtime.firstmoduledata
was always overridden in the linker to be a local symbol but cmd/internal/obj had
already rewritten code accessing it to access it via the GOT. This works on amd64, but
causes link failures on other platforms (e.g. arm64).

Change-Id: I9b8153af74b4d0f092211d63a000d15818f39773
Reviewed-on: https://go-review.googlesource.com/13786
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/symtab.go

index 74ec9dd3ea6ef8dc5e98b91a8f25ae726f2ccc82..3e316e64e4a09aee83577787a8fe677d39a1de5a 100644 (file)
@@ -81,7 +81,7 @@ func gentext() {
        //    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)
+       ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Ctxt.Moduledata, 0)
        //    7:        e8 00 00 00 00          callq  c <local.dso_init+0xc>
        //                      8: R_X86_64_PLT32       runtime.addmoduledata-0x4
        o(0xe8)
index 8ccbec9dd6342c35ae7e7482721bfc715de60299..f31070f41bbadde29693248e07965fbc2b0ba77a 100644 (file)
@@ -564,6 +564,24 @@ func loadlib() {
        tlsg.Reachable = true
        Ctxt.Tlsg = tlsg
 
+       moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0)
+       if moduledata.Type == 0 || moduledata.Type == obj.SDYNIMPORT {
+               // If the module we are linking does not define the
+               // runtime.firstmoduledata symbol, create a local symbol for
+               // the moduledata.
+               moduledata = Linklookup(Ctxt, "local.moduledata", 0)
+               moduledata.Local = true
+       } else {
+               // If OTOH the module does define the symbol, we truncate the
+               // symbol back to 0 bytes so we can define its entire
+               // contents.
+               moduledata.Size = 0
+       }
+       // Either way we mark it as noptrdata to hide it from the GC.
+       moduledata.Type = obj.SNOPTRDATA
+       moduledata.Reachable = true
+       Ctxt.Moduledata = moduledata
+
        // Now that we know the link mode, trim the dynexp list.
        x := CgoExportDynamic
 
index 33b17c59852b85e76e3084fd29512d006292c1c6..54154340e04759608a556bcd06d0bb550e6b1c91 100644 (file)
@@ -121,31 +121,32 @@ type Shlib struct {
 }
 
 type Link struct {
-       Thechar   int32
-       Thestring string
-       Goarm     int32
-       Headtype  int
-       Arch      *LinkArch
-       Debugasm  int32
-       Debugvlog int32
-       Bso       *obj.Biobuf
-       Windows   int32
-       Goroot    string
-       Hash      map[symVer]*LSym
-       Allsym    *LSym
-       Nsymbol   int32
-       Tlsg      *LSym
-       Libdir    []string
-       Library   []*Library
-       Shlibs    []Shlib
-       Tlsoffset int
-       Diag      func(string, ...interface{})
-       Cursym    *LSym
-       Version   int
-       Textp     *LSym
-       Etextp    *LSym
-       Nhistfile int32
-       Filesyms  *LSym
+       Thechar    int32
+       Thestring  string
+       Goarm      int32
+       Headtype   int
+       Arch       *LinkArch
+       Debugasm   int32
+       Debugvlog  int32
+       Bso        *obj.Biobuf
+       Windows    int32
+       Goroot     string
+       Hash       map[symVer]*LSym
+       Allsym     *LSym
+       Nsymbol    int32
+       Tlsg       *LSym
+       Libdir     []string
+       Library    []*Library
+       Shlibs     []Shlib
+       Tlsoffset  int
+       Diag       func(string, ...interface{})
+       Cursym     *LSym
+       Version    int
+       Textp      *LSym
+       Etextp     *LSym
+       Nhistfile  int32
+       Filesyms   *LSym
+       Moduledata *LSym
 }
 
 type LinkArch struct {
index 5360ec15a1da5a5f11803fdf6a9e550641483433..250c053143c220fbd192538e2723b7afb3d3839b 100644 (file)
@@ -452,11 +452,7 @@ func symtab() {
        // 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.firstmoduledata", 0)
-       moduledata.Type = obj.SNOPTRDATA
-       moduledata.Size = 0 // truncate symbol back to 0 bytes to reinitialize
-       moduledata.Reachable = true
-       moduledata.Local = true
+       moduledata := Ctxt.Moduledata
        // The pclntab slice
        Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0))
        adduint(Ctxt, moduledata, uint64(Linklookup(Ctxt, "runtime.pclntab", 0).Size))