cmd/link: move build/link mode globals into ctxt

Replace Buildmode with BuildMode and Linkmode with LinkMode.

For #22095

Change-Id: I51a6f5719d107727bca29ec8e68e3e9d87e31e33
Reviewed-on: https://go-review.googlesource.com/68334
Run-TryBot: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
David Crawshaw 2017-10-05 10:20:17 -04:00
parent 9f9bb97420
commit 2e8545531e
22 changed files with 287 additions and 292 deletions

View file

@ -138,7 +138,7 @@ func (ctxt *Link) DynlinkingGo() bool {
if !ctxt.Loaded {
panic("DynlinkingGo called before all symbols loaded")
}
return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || ctxt.CanUsePlugins()
return ctxt.BuildMode == BuildModeShared || *FlagLinkshared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins()
}
// CanUsePlugins returns whether a plugins can be used
@ -148,9 +148,9 @@ func (ctxt *Link) CanUsePlugins() bool {
// UseRelro returns whether to make use of "read only relocations" aka
// relro.
func UseRelro() bool {
switch Buildmode {
case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePIE, BuildmodePlugin:
func (ctxt *Link) UseRelro() bool {
switch ctxt.BuildMode {
case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
return Iself
default:
return *FlagLinkshared
@ -246,15 +246,15 @@ func libinit(ctxt *Link) {
ctxt.Out.f = f
if *flagEntrySymbol == "" {
switch Buildmode {
case BuildmodeCShared, BuildmodeCArchive:
switch ctxt.BuildMode {
case BuildModeCShared, BuildModeCArchive:
*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
case BuildmodeExe, BuildmodePIE:
case BuildModeExe, BuildModePIE:
*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
case BuildmodeShared, BuildmodePlugin:
case BuildModeShared, BuildModePlugin:
// No *flagEntrySymbol for -buildmode=shared and plugin
default:
Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", Buildmode)
Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
}
}
}
@ -331,12 +331,12 @@ func (ctxt *Link) findLibPath(libname string) string {
}
func (ctxt *Link) loadlib() {
switch Buildmode {
case BuildmodeCShared, BuildmodePlugin:
switch ctxt.BuildMode {
case BuildModeCShared, BuildModePlugin:
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
case BuildmodeCArchive:
case BuildModeCArchive:
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
@ -378,21 +378,21 @@ func (ctxt *Link) loadlib() {
// We now have enough information to determine the link mode.
determineLinkMode(ctxt)
// Recalculate pe parameters now that we have Linkmode set.
// Recalculate pe parameters now that we have ctxt.LinkMode set.
if Headtype == objabi.Hwindows {
Peinit(ctxt)
}
if Headtype == objabi.Hdarwin && Linkmode == LinkExternal {
if Headtype == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
*FlagTextAddr = 0
}
if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
toc := ctxt.Syms.Lookup(".TOC.", 0)
toc.Type = sym.SDYNIMPORT
}
if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
// This indicates a user requested -linkmode=external.
// The startup code uses an import of runtime/cgo to decide
// whether to initialize the TLS. So give it one. This could
@ -401,7 +401,7 @@ func (ctxt *Link) loadlib() {
if lib.Shlib != "" {
ldshlibsyms(ctxt, lib.Shlib)
} else {
if Buildmode == BuildmodeShared || *FlagLinkshared {
if ctxt.BuildMode == BuildModeShared || *FlagLinkshared {
Exitf("cannot implicitly include runtime/cgo in a shared library")
}
loadobjfile(ctxt, lib)
@ -409,7 +409,7 @@ func (ctxt *Link) loadlib() {
}
}
if Linkmode == LinkInternal {
if ctxt.LinkMode == LinkInternal {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
for _, s := range ctxt.Syms.Allsym {
@ -441,7 +441,7 @@ func (ctxt *Link) loadlib() {
ctxt.Tlsg = tlsg
var moduledata *sym.Symbol
if Buildmode == BuildmodePlugin {
if ctxt.BuildMode == BuildModePlugin {
moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
moduledata.Attr |= sym.AttrLocal
} else {
@ -485,7 +485,7 @@ func (ctxt *Link) loadlib() {
// Now that we know the link mode, trim the dynexp list.
x := sym.AttrCgoExportDynamic
if Linkmode == LinkExternal {
if ctxt.LinkMode == LinkExternal {
x = sym.AttrCgoExportStatic
}
w := 0
@ -498,7 +498,7 @@ func (ctxt *Link) loadlib() {
dynexp = dynexp[:w]
// In internal link mode, read the host object files.
if Linkmode == LinkInternal {
if ctxt.LinkMode == LinkInternal {
hostobjs(ctxt)
// If we have any undefined symbols in external
@ -553,7 +553,7 @@ func (ctxt *Link) loadlib() {
// 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 Buildmode == BuildmodeExe {
if ctxt.BuildMode == BuildModeExe {
if havedynamic == 0 && Headtype != objabi.Hdarwin && Headtype != objabi.Hsolaris {
*FlagD = true
}
@ -570,7 +570,7 @@ func (ctxt *Link) loadlib() {
// Leave type.runtime. symbols alone, because other parts of
// the linker manipulates them, and also symbols whose names
// would not be shortened by this process.
if typeSymbolMangling(ctxt.Syms) {
if typeSymbolMangling(ctxt) {
*FlagW = true // disable DWARF generation
for _, s := range ctxt.Syms.Allsym {
newName := typeSymbolMangle(ctxt.Syms, s.Name)
@ -582,7 +582,7 @@ func (ctxt *Link) loadlib() {
// If package versioning is required, generate a hash of the
// the packages used in the link.
if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.CanUsePlugins() {
if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
for _, lib := range ctxt.Library {
if lib.Shlib == "" {
genhash(ctxt, lib)
@ -591,7 +591,7 @@ func (ctxt *Link) loadlib() {
}
if ctxt.Arch == sys.Arch386 {
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
if (ctxt.BuildMode == BuildModeCArchive && Iself) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
got.Type = sym.SDYNIMPORT
got.Attr |= sym.AttrReachable
@ -651,15 +651,12 @@ func (ctxt *Link) loadlib() {
// packages. All Go binaries contain these symbols, but only only
// those programs loaded dynamically in multiple parts need these
// symbols to have entries in the symbol table.
func typeSymbolMangling(syms *sym.Symbols) bool {
return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || syms.ROLookup("plugin.Open", 0) != nil
func typeSymbolMangling(ctxt *Link) bool {
return ctxt.BuildMode == BuildModeShared || *FlagLinkshared || ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil
}
// typeSymbolMangle mangles the given symbol name into something shorter.
func typeSymbolMangle(syms *sym.Symbols, name string) string {
if !typeSymbolMangling(syms) {
return name
}
if !strings.HasPrefix(name, "type.") {
return name
}
@ -925,7 +922,7 @@ func rmtemp() {
}
func hostlinksetup(ctxt *Link) {
if Linkmode != LinkExternal {
if ctxt.LinkMode != LinkExternal {
return
}
@ -1027,7 +1024,7 @@ INSERT AFTER .debug_types;
// archive builds a .a archive from the hostobj object files.
func (ctxt *Link) archive() {
if Buildmode != BuildmodeCArchive {
if ctxt.BuildMode != BuildModeCArchive {
return
}
@ -1058,11 +1055,11 @@ func (ctxt *Link) archive() {
}
}
func (l *Link) hostlink() {
if Linkmode != LinkExternal || nerrors > 0 {
func (ctxt *Link) hostlink() {
if ctxt.LinkMode != LinkExternal || nerrors > 0 {
return
}
if Buildmode == BuildmodeCArchive {
if ctxt.BuildMode == BuildModeCArchive {
return
}
@ -1072,7 +1069,7 @@ func (l *Link) hostlink() {
var argv []string
argv = append(argv, *flagExtld)
argv = append(argv, hostlinkArchArgs(l.Arch)...)
argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
if !*FlagS && !debug_s {
argv = append(argv, "-gdwarf-2")
@ -1087,10 +1084,10 @@ func (l *Link) hostlink() {
switch Headtype {
case objabi.Hdarwin:
argv = append(argv, "-Wl,-headerpad,1144")
if l.DynlinkingGo() {
if ctxt.DynlinkingGo() {
argv = append(argv, "-Wl,-flat_namespace")
}
if Buildmode == BuildmodeExe && !l.Arch.InFamily(sys.ARM64) {
if ctxt.BuildMode == BuildModeExe && !ctxt.Arch.InFamily(sys.ARM64) {
argv = append(argv, "-Wl,-no_pie")
}
case objabi.Hopenbsd:
@ -1103,52 +1100,52 @@ func (l *Link) hostlink() {
}
}
switch Buildmode {
case BuildmodeExe:
switch ctxt.BuildMode {
case BuildModeExe:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-Wl,-pagezero_size,4000000")
}
case BuildmodePIE:
case BuildModePIE:
// ELF.
if Headtype != objabi.Hdarwin {
if UseRelro() {
if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-pie")
}
case BuildmodeCShared:
case BuildModeCShared:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-dynamiclib")
if l.Arch.Family != sys.AMD64 {
if ctxt.Arch.Family != sys.AMD64 {
argv = append(argv, "-Wl,-read_only_relocs,suppress")
}
} else {
// ELF.
argv = append(argv, "-Wl,-Bsymbolic")
if UseRelro() {
if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
// Pass -z nodelete to mark the shared library as
// non-closeable: a dlclose will do nothing.
argv = append(argv, "-shared", "-Wl,-z,nodelete")
}
case BuildmodeShared:
if UseRelro() {
case BuildModeShared:
if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-shared")
case BuildmodePlugin:
case BuildModePlugin:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-dynamiclib")
} else {
if UseRelro() {
if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-shared")
}
}
if Iself && l.DynlinkingGo() {
if Iself && ctxt.DynlinkingGo() {
// We force all symbol resolution to be done at program startup
// because lazy PLT resolution can use large amounts of stack at
// times we cannot allow it to do so.
@ -1159,7 +1156,7 @@ func (l *Link) hostlink() {
// from the beginning of the section (like sym.STYPE).
argv = append(argv, "-Wl,-znocopyreloc")
if l.Arch.InFamily(sys.ARM, sys.ARM64) {
if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
// On ARM, the GNU linker will generate COPY relocations
// even with -znocopyreloc set.
// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
@ -1234,13 +1231,13 @@ func (l *Link) hostlink() {
seenLibs[base] = true
}
}
for _, shlib := range l.Shlibs {
for _, shlib := range ctxt.Shlibs {
addshlib(shlib.Path)
for _, dep := range shlib.Deps {
if dep == "" {
continue
}
libpath := findshlib(l, dep)
libpath := findshlib(ctxt, dep)
if libpath != "" {
addshlib(libpath)
}
@ -1257,7 +1254,7 @@ func (l *Link) hostlink() {
// does not work, the resulting programs will not run. See
// issue #17847. To avoid this problem pass -no-pie to the
// toolchain if it is supported.
if Buildmode == BuildmodeExe {
if ctxt.BuildMode == BuildModeExe {
src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
Errorf(nil, "WriteFile trivial.c failed: %v", err)
@ -1307,12 +1304,12 @@ func (l *Link) hostlink() {
argv = append(argv, peimporteddlls()...)
}
if l.Debugvlog != 0 {
l.Logf("%5.2f host link:", Cputime())
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f host link:", Cputime())
for _, v := range argv {
l.Logf(" %q", v)
ctxt.Logf(" %q", v)
}
l.Logf("\n")
ctxt.Logf("\n")
}
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
@ -1320,12 +1317,12 @@ func (l *Link) hostlink() {
} else if len(out) > 0 {
// always print external output even if the command is successful, so that we don't
// swallow linker warnings (see https://golang.org/issue/17935).
l.Logf("%s", out)
ctxt.Logf("%s", out)
}
if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin {
// Skip combining dwarf on arm.
if !l.Arch.InFamily(sys.ARM, sys.ARM64) {
if !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
@ -1336,7 +1333,7 @@ func (l *Link) hostlink() {
}
// For os.Rename to work reliably, must be in same directory as outfile.
combinedOutput := *flagOutfile + "~"
if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil {
if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput, ctxt.BuildMode); err != nil {
Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
}
os.Remove(*flagOutfile)
@ -1775,7 +1772,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
// onlyctxt.Diagnose the direct caller.
// TODO(mwhudson): actually think about this.
if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
Errorf(s, "call to external function")
}
@ -2023,7 +2020,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6
put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
case sym.STLSBSS:
if Linkmode == LinkExternal {
if ctxt.LinkMode == LinkExternal {
put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
}
}