Skip to content

Commit

Permalink
cmd/link: call moduledata symbols "local.moduledata" if they are crea…
Browse files Browse the repository at this point in the history
…ted 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 <[email protected]>
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
mwhudson authored and ianlancetaylor committed Aug 25, 2015
1 parent 6ec1809 commit 7f9e443
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/cmd/link/internal/amd64/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 18 additions & 0 deletions src/cmd/link/internal/ld/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
51 changes: 26 additions & 25 deletions src/cmd/link/internal/ld/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 1 addition & 5 deletions src/cmd/link/internal/ld/symtab.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 7f9e443

Please sign in to comment.