cmd/link: call moduledata symbols "local.moduledata" if they are created by the linker
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>
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 8ccbec9..f31070f 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -564,6 +564,24 @@
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
diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go
index 33b17c5..5415434 100644
--- a/src/cmd/link/internal/ld/link.go
+++ b/src/cmd/link/internal/ld/link.go
@@ -121,31 +121,32 @@
}
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 {
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 5360ec1..250c053 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -452,11 +452,7 @@
// 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))