]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert Link.linksetup method to work with loader
authorThan McIntosh <thanm@google.com>
Mon, 30 Dec 2019 19:12:54 +0000 (14:12 -0500)
committerThan McIntosh <thanm@google.com>
Fri, 10 Jan 2020 12:36:22 +0000 (12:36 +0000)
Switch the linker's Link.linksetup method to work with loader.Sym
instead of sym.Symbols. Currently enabled when the new ELF host object
loader is turned on.

Change-Id: I336cc9f36166767baac574455531e195b6f1ac57
Reviewed-on: https://go-review.googlesource.com/c/go/+/213423
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/main.go

index dfca7e969bb6c3a3a74336e0bc58a1caf5a32c6c..3e79b92d750c970d364bb07f65e7df5aaf22cf06 100644 (file)
@@ -626,7 +626,144 @@ func (ctxt *Link) loadcgodirectives(useLoader bool) {
 }
 
 // Set up flags and special symbols depending on the platform build mode.
+// This version works with loader.Loader.
 func (ctxt *Link) linksetup() {
+       if !*FlagNewLdElf {
+               panic("should not get here, -newldelf not on")
+       }
+       switch ctxt.BuildMode {
+       case BuildModeCShared, BuildModePlugin:
+               symIdx := ctxt.loader.LookupOrCreateSym("runtime.islibrary", 0)
+               sb, _ := ctxt.loader.MakeSymbolUpdater(symIdx)
+               sb.SetType(sym.SNOPTRDATA)
+               sb.AddUint8(1)
+       case BuildModeCArchive:
+               symIdx := ctxt.loader.LookupOrCreateSym("runtime.isarchive", 0)
+               sb, _ := ctxt.loader.MakeSymbolUpdater(symIdx)
+               sb.SetType(sym.SNOPTRDATA)
+               sb.AddUint8(1)
+       }
+
+       // Recalculate pe parameters now that we have ctxt.LinkMode set.
+       if ctxt.HeadType == objabi.Hwindows {
+               Peinit(ctxt)
+       }
+
+       if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
+               *FlagTextAddr = 0
+       }
+
+       // If there are no dynamic libraries needed, gcc disables dynamic linking.
+       // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
+       // assumes that a dynamic binary always refers to at least one dynamic library.
+       // Rather than be a source of test cases for glibc, disable dynamic linking
+       // the same way that gcc would.
+       //
+       // Exception: on OS X, programs such as Shark only work with dynamic
+       // binaries, so leave it enabled on OS X (Mach-O) binaries.
+       // Also leave it enabled on Solaris which doesn't support
+       // statically linked binaries.
+       if ctxt.BuildMode == BuildModeExe {
+               if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
+                       *FlagD = true
+               }
+       }
+
+       if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
+               toc := ctxt.loader.LookupOrCreateSym(".TOC.", 0)
+               sb, _ := ctxt.loader.MakeSymbolUpdater(toc)
+               sb.SetType(sym.SDYNIMPORT)
+       }
+
+       // The Android Q linker started to complain about underalignment of the our TLS
+       // section. We don't actually use the section on android, so don't
+       // generate it.
+       if objabi.GOOS != "android" {
+               symIdx := ctxt.loader.LookupOrCreateSym("runtime.tlsg", 0)
+               sb, tlsg := ctxt.loader.MakeSymbolUpdater(symIdx)
+
+               // runtime.tlsg is used for external linking on platforms that do not define
+               // a variable to hold g in assembly (currently only intel).
+               if sb.Type() == 0 {
+                       sb.SetType(sym.STLSBSS)
+                       sb.SetSize(int64(ctxt.Arch.PtrSize))
+               } else if sb.Type() != sym.SDYNIMPORT {
+                       Errorf(nil, "runtime declared tlsg variable %v", sb.Type())
+               }
+               ctxt.loader.SetAttrReachable(tlsg, true)
+               ctxt.Tlsg2 = tlsg
+       }
+
+       var moduledata loader.Sym
+       var mdsb *loader.SymbolBuilder
+       if ctxt.BuildMode == BuildModePlugin {
+               pmd := ctxt.loader.LookupOrCreateSym("local.pluginmoduledata", 0)
+               mdsb, moduledata = ctxt.loader.MakeSymbolUpdater(pmd)
+               ctxt.loader.SetAttrLocal(moduledata, true)
+       } else {
+               fmd := ctxt.loader.LookupOrCreateSym("runtime.firstmoduledata", 0)
+               mdsb, moduledata = ctxt.loader.MakeSymbolUpdater(fmd)
+       }
+       if mdsb.Type() != 0 && mdsb.Type() != sym.SDYNIMPORT {
+               // If the module (toolchain-speak for "executable or shared
+               // library") we are linking contains the runtime package, it
+               // will define the runtime.firstmoduledata symbol and we
+               // truncate it back to 0 bytes so we can define its entire
+               // contents in symtab.go:symtab().
+               mdsb.SetSize(0)
+
+               // In addition, on ARM, the runtime depends on the linker
+               // recording the value of GOARM.
+               if ctxt.Arch.Family == sys.ARM {
+                       goarm := ctxt.loader.LookupOrCreateSym("runtime.goarm", 0)
+                       sb, _ := ctxt.loader.MakeSymbolUpdater(goarm)
+                       sb.SetType(sym.SDATA)
+                       sb.SetSize(0)
+                       sb.AddUint8(uint8(objabi.GOARM))
+               }
+
+               if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+                       fpe := ctxt.loader.LookupOrCreateSym("runtime.framepointer_enabled", 0)
+                       sb, _ := ctxt.loader.MakeSymbolUpdater(fpe)
+                       sb.SetType(sym.SNOPTRDATA)
+                       sb.SetSize(0)
+                       sb.AddUint8(1)
+               }
+       } else {
+               // If OTOH the module does not contain the runtime package,
+               // create a local symbol for the moduledata.
+               lmd := ctxt.loader.LookupOrCreateSym("local.moduledata", 0)
+               mdsb, moduledata = ctxt.loader.MakeSymbolUpdater(lmd)
+               ctxt.loader.SetAttrLocal(moduledata, true)
+       }
+       // In all cases way we mark the moduledata as noptrdata to hide it from
+       // the GC.
+       mdsb.SetType(sym.SNOPTRDATA)
+       ctxt.loader.SetAttrReachable(moduledata, true)
+       ctxt.Moduledata2 = moduledata
+
+       // If package versioning is required, generate a hash of the
+       // packages used in the link.
+       if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
+               for _, lib := range ctxt.Library {
+                       if lib.Shlib == "" {
+                               genhash(ctxt, lib)
+                       }
+               }
+       }
+
+       if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
+               if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
+                       symIdx := ctxt.loader.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0)
+                       sb, got := ctxt.loader.MakeSymbolUpdater(symIdx)
+                       sb.SetType(sym.SDYNIMPORT)
+                       ctxt.loader.SetAttrReachable(got, true)
+               }
+       }
+}
+
+// Set up flags and special symbols depending on the platform build mode.
+func (ctxt *Link) linksetupold() {
        switch ctxt.BuildMode {
        case BuildModeCShared, BuildModePlugin:
                s := ctxt.Syms.Lookup("runtime.islibrary", 0)
@@ -2713,6 +2850,12 @@ func (ctxt *Link) loadlibfull() {
        // Load full symbol contents, resolve indexed references.
        ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
 
+       // Convert ctxt.Moduledata2 to ctxt.Moduledata, etc
+       if ctxt.Moduledata2 != 0 {
+               ctxt.Moduledata = ctxt.loader.Syms[ctxt.Moduledata2]
+               ctxt.Tlsg = ctxt.loader.Syms[ctxt.Tlsg2]
+       }
+
        // Pull the symbols out.
        ctxt.loader.ExtractSymbols(ctxt.Syms)
 
index 2c915f05568360f318b14c6a4df7aef2d36286d2..fa1dc389d7150a57547fcaa95f9ef4a2640938ed 100644 (file)
@@ -73,6 +73,7 @@ type Link struct {
        compressDWARF bool
 
        Tlsg         *sym.Symbol
+       Tlsg2        loader.Sym
        Libdir       []string
        Library      []*sym.Library
        LibraryByPkg map[string]*sym.Library
@@ -82,6 +83,7 @@ type Link struct {
        Textp2       []loader.Sym
        Filesyms     []*sym.Symbol
        Moduledata   *sym.Symbol
+       Moduledata2  loader.Sym
 
        PackageFile  map[string]string
        PackageShlib map[string]string
index c23da8679ebfd3c4e5b96307b330ece0a3d71147..4ed8a02d67508f132faa52ea12fc1c9bc5811c17 100644 (file)
@@ -210,11 +210,19 @@ func Main(arch *sys.Arch, theArch Arch) {
        ctxt.loadlib()
 
        deadcode(ctxt)
+
+       if *FlagNewLdElf {
+               ctxt.linksetup()
+       }
+
        ctxt.loadlibfull() // XXX do it here for now
-       ctxt.linksetup()
-       ctxt.dostrdata()
 
+       if !*FlagNewLdElf {
+               ctxt.linksetupold()
+       }
+       ctxt.dostrdata()
        dwarfGenerateDebugInfo(ctxt)
+
        if objabi.Fieldtrack_enabled != 0 {
                fieldtrack(ctxt)
        }