Source file src/cmd/link/internal/ld/lib.go

     1  // Inferno utils/8l/asm.c
     2  // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/8l/asm.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  package ld
    32  
    33  import (
    34  	"bytes"
    35  	"cmd/internal/bio"
    36  	"cmd/internal/goobj"
    37  	"cmd/internal/obj"
    38  	"cmd/internal/objabi"
    39  	"cmd/internal/sys"
    40  	"cmd/link/internal/loadelf"
    41  	"cmd/link/internal/loader"
    42  	"cmd/link/internal/loadmacho"
    43  	"cmd/link/internal/loadpe"
    44  	"cmd/link/internal/loadxcoff"
    45  	"cmd/link/internal/sym"
    46  	"crypto/sha1"
    47  	"debug/elf"
    48  	"debug/macho"
    49  	"encoding/base64"
    50  	"encoding/binary"
    51  	"fmt"
    52  	"internal/buildcfg"
    53  	exec "internal/execabs"
    54  	"io"
    55  	"io/ioutil"
    56  	"log"
    57  	"os"
    58  	"path/filepath"
    59  	"runtime"
    60  	"strings"
    61  	"sync"
    62  )
    63  
    64  // Data layout and relocation.
    65  
    66  // Derived from Inferno utils/6l/l.h
    67  // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h
    68  //
    69  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
    70  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
    71  //	Portions Copyright © 1997-1999 Vita Nuova Limited
    72  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
    73  //	Portions Copyright © 2004,2006 Bruce Ellis
    74  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    75  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    76  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    77  //
    78  // Permission is hereby granted, free of charge, to any person obtaining a copy
    79  // of this software and associated documentation files (the "Software"), to deal
    80  // in the Software without restriction, including without limitation the rights
    81  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    82  // copies of the Software, and to permit persons to whom the Software is
    83  // furnished to do so, subject to the following conditions:
    84  //
    85  // The above copyright notice and this permission notice shall be included in
    86  // all copies or substantial portions of the Software.
    87  //
    88  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    89  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    90  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    91  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    92  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    93  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    94  // THE SOFTWARE.
    95  
    96  // ArchSyms holds a number of architecture specific symbols used during
    97  // relocation.  Rather than allowing them universal access to all symbols,
    98  // we keep a subset for relocation application.
    99  type ArchSyms struct {
   100  	Rel     loader.Sym
   101  	Rela    loader.Sym
   102  	RelPLT  loader.Sym
   103  	RelaPLT loader.Sym
   104  
   105  	LinkEditGOT loader.Sym
   106  	LinkEditPLT loader.Sym
   107  
   108  	TOC    loader.Sym
   109  	DotTOC []loader.Sym // for each version
   110  
   111  	GOT    loader.Sym
   112  	PLT    loader.Sym
   113  	GOTPLT loader.Sym
   114  
   115  	Tlsg      loader.Sym
   116  	Tlsoffset int
   117  
   118  	Dynamic loader.Sym
   119  	DynSym  loader.Sym
   120  	DynStr  loader.Sym
   121  
   122  	unreachableMethod loader.Sym
   123  }
   124  
   125  // mkArchSym is a helper for setArchSyms, to set up a special symbol.
   126  func (ctxt *Link) mkArchSym(name string, ver int, ls *loader.Sym) {
   127  	*ls = ctxt.loader.LookupOrCreateSym(name, ver)
   128  	ctxt.loader.SetAttrReachable(*ls, true)
   129  }
   130  
   131  // mkArchVecSym is similar to  setArchSyms, but operates on elements within
   132  // a slice, where each element corresponds to some symbol version.
   133  func (ctxt *Link) mkArchSymVec(name string, ver int, ls []loader.Sym) {
   134  	ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
   135  	ctxt.loader.SetAttrReachable(ls[ver], true)
   136  }
   137  
   138  // setArchSyms sets up the ArchSyms structure, and must be called before
   139  // relocations are applied.
   140  func (ctxt *Link) setArchSyms() {
   141  	ctxt.mkArchSym(".got", 0, &ctxt.GOT)
   142  	ctxt.mkArchSym(".plt", 0, &ctxt.PLT)
   143  	ctxt.mkArchSym(".got.plt", 0, &ctxt.GOTPLT)
   144  	ctxt.mkArchSym(".dynamic", 0, &ctxt.Dynamic)
   145  	ctxt.mkArchSym(".dynsym", 0, &ctxt.DynSym)
   146  	ctxt.mkArchSym(".dynstr", 0, &ctxt.DynStr)
   147  	ctxt.mkArchSym("runtime.unreachableMethod", abiInternalVer, &ctxt.unreachableMethod)
   148  
   149  	if ctxt.IsPPC64() {
   150  		ctxt.mkArchSym("TOC", 0, &ctxt.TOC)
   151  
   152  		ctxt.DotTOC = make([]loader.Sym, ctxt.MaxVersion()+1)
   153  		for i := 0; i <= ctxt.MaxVersion(); i++ {
   154  			if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
   155  				continue
   156  			}
   157  			ctxt.mkArchSymVec(".TOC.", i, ctxt.DotTOC)
   158  		}
   159  	}
   160  	if ctxt.IsElf() {
   161  		ctxt.mkArchSym(".rel", 0, &ctxt.Rel)
   162  		ctxt.mkArchSym(".rela", 0, &ctxt.Rela)
   163  		ctxt.mkArchSym(".rel.plt", 0, &ctxt.RelPLT)
   164  		ctxt.mkArchSym(".rela.plt", 0, &ctxt.RelaPLT)
   165  	}
   166  	if ctxt.IsDarwin() {
   167  		ctxt.mkArchSym(".linkedit.got", 0, &ctxt.LinkEditGOT)
   168  		ctxt.mkArchSym(".linkedit.plt", 0, &ctxt.LinkEditPLT)
   169  	}
   170  }
   171  
   172  type Arch struct {
   173  	Funcalign  int
   174  	Maxalign   int
   175  	Minalign   int
   176  	Dwarfregsp int
   177  	Dwarfreglr int
   178  
   179  	// Threshold of total text size, used for trampoline insertion. If the total
   180  	// text size is smaller than TrampLimit, we won't need to insert trampolines.
   181  	// It is pretty close to the offset range of a direct CALL machine instruction.
   182  	// We leave some room for extra stuff like PLT stubs.
   183  	TrampLimit uint64
   184  
   185  	Androiddynld   string
   186  	Linuxdynld     string
   187  	Freebsddynld   string
   188  	Netbsddynld    string
   189  	Openbsddynld   string
   190  	Dragonflydynld string
   191  	Solarisdynld   string
   192  
   193  	// Empty spaces between codeblocks will be padded with this value.
   194  	// For example an architecture might want to pad with a trap instruction to
   195  	// catch wayward programs. Architectures that do not define a padding value
   196  	// are padded with zeros.
   197  	CodePad []byte
   198  
   199  	// Plan 9 variables.
   200  	Plan9Magic  uint32
   201  	Plan9_64Bit bool
   202  
   203  	Adddynrel func(*Target, *loader.Loader, *ArchSyms, loader.Sym, loader.Reloc, int) bool
   204  	Archinit  func(*Link)
   205  	// Archreloc is an arch-specific hook that assists in relocation processing
   206  	// (invoked by 'relocsym'); it handles target-specific relocation tasks.
   207  	// Here "rel" is the current relocation being examined, "sym" is the symbol
   208  	// containing the chunk of data to which the relocation applies, and "off"
   209  	// is the contents of the to-be-relocated data item (from sym.P). Return
   210  	// value is the appropriately relocated value (to be written back to the
   211  	// same spot in sym.P), number of external _host_ relocations needed (i.e.
   212  	// ELF/Mach-O/etc. relocations, not Go relocations, this must match Elfreloc1,
   213  	// etc.), and a boolean indicating success/failure (a failing value indicates
   214  	// a fatal error).
   215  	Archreloc func(*Target, *loader.Loader, *ArchSyms, loader.Reloc, loader.Sym,
   216  		int64) (relocatedOffset int64, nExtReloc int, ok bool)
   217  	// Archrelocvariant is a second arch-specific hook used for
   218  	// relocation processing; it handles relocations where r.Type is
   219  	// insufficient to describe the relocation (r.Variant !=
   220  	// sym.RV_NONE). Here "rel" is the relocation being applied, "sym"
   221  	// is the symbol containing the chunk of data to which the
   222  	// relocation applies, and "off" is the contents of the
   223  	// to-be-relocated data item (from sym.P). Return is an updated
   224  	// offset value.
   225  	Archrelocvariant func(target *Target, ldr *loader.Loader, rel loader.Reloc,
   226  		rv sym.RelocVariant, sym loader.Sym, offset int64, data []byte) (relocatedOffset int64)
   227  
   228  	// Generate a trampoline for a call from s to rs if necessary. ri is
   229  	// index of the relocation.
   230  	Trampoline func(ctxt *Link, ldr *loader.Loader, ri int, rs, s loader.Sym)
   231  
   232  	// Assembling the binary breaks into two phases, writing the code/data/
   233  	// dwarf information (which is rather generic), and some more architecture
   234  	// specific work like setting up the elf headers/dynamic relocations, etc.
   235  	// The phases are called "Asmb" and "Asmb2". Asmb2 needs to be defined for
   236  	// every architecture, but only if architecture has an Asmb function will
   237  	// it be used for assembly.  Otherwise a generic assembly Asmb function is
   238  	// used.
   239  	Asmb  func(*Link, *loader.Loader)
   240  	Asmb2 func(*Link, *loader.Loader)
   241  
   242  	// Extreloc is an arch-specific hook that converts a Go relocation to an
   243  	// external relocation. Return the external relocation and whether it is
   244  	// needed.
   245  	Extreloc func(*Target, *loader.Loader, loader.Reloc, loader.Sym) (loader.ExtReloc, bool)
   246  
   247  	Elfreloc1      func(*Link, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int, int64) bool
   248  	ElfrelocSize   uint32 // size of an ELF relocation record, must match Elfreloc1.
   249  	Elfsetupplt    func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
   250  	Gentext        func(*Link, *loader.Loader) // Generate text before addressing has been performed.
   251  	Machoreloc1    func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool
   252  	MachorelocSize uint32 // size of an Mach-O relocation record, must match Machoreloc1.
   253  	PEreloc1       func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool
   254  	Xcoffreloc1    func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool
   255  
   256  	// Generate additional symbols for the native symbol table just prior to
   257  	// code generation.
   258  	GenSymsLate func(*Link, *loader.Loader)
   259  
   260  	// TLSIEtoLE converts a TLS Initial Executable relocation to
   261  	// a TLS Local Executable relocation.
   262  	//
   263  	// This is possible when a TLS IE relocation refers to a local
   264  	// symbol in an executable, which is typical when internally
   265  	// linking PIE binaries.
   266  	TLSIEtoLE func(P []byte, off, size int)
   267  
   268  	// optional override for assignAddress
   269  	AssignAddress func(ldr *loader.Loader, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp bool) (*sym.Section, int, uint64)
   270  }
   271  
   272  var (
   273  	thearch Arch
   274  	lcSize  int32
   275  	rpath   Rpath
   276  	spSize  int32
   277  	symSize int32
   278  )
   279  
   280  const (
   281  	MINFUNC = 16 // minimum size for a function
   282  )
   283  
   284  // Symbol version of ABIInternal symbols. It is sym.SymVerABIInternal if ABI wrappers
   285  // are used, 0 otherwise.
   286  var abiInternalVer = sym.SymVerABIInternal
   287  
   288  // DynlinkingGo reports whether we are producing Go code that can live
   289  // in separate shared libraries linked together at runtime.
   290  func (ctxt *Link) DynlinkingGo() bool {
   291  	if !ctxt.Loaded {
   292  		panic("DynlinkingGo called before all symbols loaded")
   293  	}
   294  	return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins
   295  }
   296  
   297  // CanUsePlugins reports whether a plugins can be used
   298  func (ctxt *Link) CanUsePlugins() bool {
   299  	if !ctxt.Loaded {
   300  		panic("CanUsePlugins called before all symbols loaded")
   301  	}
   302  	return ctxt.canUsePlugins
   303  }
   304  
   305  // NeedCodeSign reports whether we need to code-sign the output binary.
   306  func (ctxt *Link) NeedCodeSign() bool {
   307  	return ctxt.IsDarwin() && ctxt.IsARM64()
   308  }
   309  
   310  var (
   311  	dynlib          []string
   312  	ldflag          []string
   313  	havedynamic     int
   314  	Funcalign       int
   315  	iscgo           bool
   316  	elfglobalsymndx int
   317  	interpreter     string
   318  
   319  	debug_s bool // backup old value of debug['s']
   320  	HEADR   int32
   321  
   322  	nerrors  int
   323  	liveness int64 // size of liveness data (funcdata), printed if -v
   324  
   325  	// See -strictdups command line flag.
   326  	checkStrictDups   int // 0=off 1=warning 2=error
   327  	strictDupMsgCount int
   328  )
   329  
   330  var (
   331  	Segtext      sym.Segment
   332  	Segrodata    sym.Segment
   333  	Segrelrodata sym.Segment
   334  	Segdata      sym.Segment
   335  	Segdwarf     sym.Segment
   336  
   337  	Segments = []*sym.Segment{&Segtext, &Segrodata, &Segrelrodata, &Segdata, &Segdwarf}
   338  )
   339  
   340  const pkgdef = "__.PKGDEF"
   341  
   342  var (
   343  	// externalobj is set to true if we see an object compiled by
   344  	// the host compiler that is not from a package that is known
   345  	// to support internal linking mode.
   346  	externalobj = false
   347  
   348  	// unknownObjFormat is set to true if we see an object whose
   349  	// format we don't recognize.
   350  	unknownObjFormat = false
   351  
   352  	theline string
   353  )
   354  
   355  func Lflag(ctxt *Link, arg string) {
   356  	ctxt.Libdir = append(ctxt.Libdir, arg)
   357  }
   358  
   359  /*
   360   * Unix doesn't like it when we write to a running (or, sometimes,
   361   * recently run) binary, so remove the output file before writing it.
   362   * On Windows 7, remove() can force a subsequent create() to fail.
   363   * S_ISREG() does not exist on Plan 9.
   364   */
   365  func mayberemoveoutfile() {
   366  	if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
   367  		return
   368  	}
   369  	os.Remove(*flagOutfile)
   370  }
   371  
   372  func libinit(ctxt *Link) {
   373  	Funcalign = thearch.Funcalign
   374  
   375  	// add goroot to the end of the libdir list.
   376  	suffix := ""
   377  
   378  	suffixsep := ""
   379  	if *flagInstallSuffix != "" {
   380  		suffixsep = "_"
   381  		suffix = *flagInstallSuffix
   382  	} else if *flagRace {
   383  		suffixsep = "_"
   384  		suffix = "race"
   385  	} else if *flagMsan {
   386  		suffixsep = "_"
   387  		suffix = "msan"
   388  	} else if *flagAsan {
   389  		suffixsep = "_"
   390  		suffix = "asan"
   391  	}
   392  
   393  	Lflag(ctxt, filepath.Join(buildcfg.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", buildcfg.GOOS, buildcfg.GOARCH, suffixsep, suffix)))
   394  
   395  	mayberemoveoutfile()
   396  
   397  	if err := ctxt.Out.Open(*flagOutfile); err != nil {
   398  		Exitf("cannot create %s: %v", *flagOutfile, err)
   399  	}
   400  
   401  	if *flagEntrySymbol == "" {
   402  		switch ctxt.BuildMode {
   403  		case BuildModeCShared, BuildModeCArchive:
   404  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", buildcfg.GOARCH, buildcfg.GOOS)
   405  		case BuildModeExe, BuildModePIE:
   406  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", buildcfg.GOARCH, buildcfg.GOOS)
   407  		case BuildModeShared, BuildModePlugin:
   408  			// No *flagEntrySymbol for -buildmode=shared and plugin
   409  		default:
   410  			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
   411  		}
   412  	}
   413  }
   414  
   415  func exitIfErrors() {
   416  	if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 {
   417  		mayberemoveoutfile()
   418  		Exit(2)
   419  	}
   420  
   421  }
   422  
   423  func errorexit() {
   424  	exitIfErrors()
   425  	Exit(0)
   426  }
   427  
   428  func loadinternal(ctxt *Link, name string) *sym.Library {
   429  	zerofp := goobj.FingerprintType{}
   430  	if ctxt.linkShared && ctxt.PackageShlib != nil {
   431  		if shlib := ctxt.PackageShlib[name]; shlib != "" {
   432  			return addlibpath(ctxt, "internal", "internal", "", name, shlib, zerofp)
   433  		}
   434  	}
   435  	if ctxt.PackageFile != nil {
   436  		if pname := ctxt.PackageFile[name]; pname != "" {
   437  			return addlibpath(ctxt, "internal", "internal", pname, name, "", zerofp)
   438  		}
   439  		ctxt.Logf("loadinternal: cannot find %s\n", name)
   440  		return nil
   441  	}
   442  
   443  	for _, libdir := range ctxt.Libdir {
   444  		if ctxt.linkShared {
   445  			shlibname := filepath.Join(libdir, name+".shlibname")
   446  			if ctxt.Debugvlog != 0 {
   447  				ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
   448  			}
   449  			if _, err := os.Stat(shlibname); err == nil {
   450  				return addlibpath(ctxt, "internal", "internal", "", name, shlibname, zerofp)
   451  			}
   452  		}
   453  		pname := filepath.Join(libdir, name+".a")
   454  		if ctxt.Debugvlog != 0 {
   455  			ctxt.Logf("searching for %s.a in %s\n", name, pname)
   456  		}
   457  		if _, err := os.Stat(pname); err == nil {
   458  			return addlibpath(ctxt, "internal", "internal", pname, name, "", zerofp)
   459  		}
   460  	}
   461  
   462  	ctxt.Logf("warning: unable to find %s.a\n", name)
   463  	return nil
   464  }
   465  
   466  // extld returns the current external linker.
   467  func (ctxt *Link) extld() []string {
   468  	if len(flagExtld) == 0 {
   469  		flagExtld = []string{"gcc"}
   470  	}
   471  	return flagExtld
   472  }
   473  
   474  // findLibPathCmd uses cmd command to find gcc library libname.
   475  // It returns library full path if found, or "none" if not found.
   476  func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
   477  	extld := ctxt.extld()
   478  	name, args := extld[0], extld[1:]
   479  	args = append(args, hostlinkArchArgs(ctxt.Arch)...)
   480  	args = append(args, cmd)
   481  	if ctxt.Debugvlog != 0 {
   482  		ctxt.Logf("%s %v\n", extld, args)
   483  	}
   484  	out, err := exec.Command(name, args...).Output()
   485  	if err != nil {
   486  		if ctxt.Debugvlog != 0 {
   487  			ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
   488  		}
   489  		return "none"
   490  	}
   491  	return strings.TrimSpace(string(out))
   492  }
   493  
   494  // findLibPath searches for library libname.
   495  // It returns library full path if found, or "none" if not found.
   496  func (ctxt *Link) findLibPath(libname string) string {
   497  	return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
   498  }
   499  
   500  func (ctxt *Link) loadlib() {
   501  	var flags uint32
   502  	switch *FlagStrictDups {
   503  	case 0:
   504  		// nothing to do
   505  	case 1, 2:
   506  		flags |= loader.FlagStrictDups
   507  	default:
   508  		log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
   509  	}
   510  	elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) }
   511  	ctxt.loader = loader.NewLoader(flags, elfsetstring1, &ctxt.ErrorReporter.ErrorReporter)
   512  	ctxt.ErrorReporter.SymName = func(s loader.Sym) string {
   513  		return ctxt.loader.SymName(s)
   514  	}
   515  
   516  	// ctxt.Library grows during the loop, so not a range loop.
   517  	i := 0
   518  	for ; i < len(ctxt.Library); i++ {
   519  		lib := ctxt.Library[i]
   520  		if lib.Shlib == "" {
   521  			if ctxt.Debugvlog > 1 {
   522  				ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
   523  			}
   524  			loadobjfile(ctxt, lib)
   525  		}
   526  	}
   527  
   528  	// load internal packages, if not already
   529  	if *flagRace {
   530  		loadinternal(ctxt, "runtime/race")
   531  	}
   532  	if *flagMsan {
   533  		loadinternal(ctxt, "runtime/msan")
   534  	}
   535  	if *flagAsan {
   536  		loadinternal(ctxt, "runtime/asan")
   537  	}
   538  	loadinternal(ctxt, "runtime")
   539  	for ; i < len(ctxt.Library); i++ {
   540  		lib := ctxt.Library[i]
   541  		if lib.Shlib == "" {
   542  			loadobjfile(ctxt, lib)
   543  		}
   544  	}
   545  	// At this point, the Go objects are "preloaded". Not all the symbols are
   546  	// added to the symbol table (only defined package symbols are). Looking
   547  	// up symbol by name may not get expected result.
   548  
   549  	iscgo = ctxt.LibraryByPkg["runtime/cgo"] != nil
   550  
   551  	// Plugins a require cgo support to function. Similarly, plugins may require additional
   552  	// internal linker support on some platforms which may not be implemented.
   553  	ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil && iscgo
   554  
   555  	// We now have enough information to determine the link mode.
   556  	determineLinkMode(ctxt)
   557  
   558  	if ctxt.LinkMode == LinkExternal && !iscgo && !(buildcfg.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) {
   559  		// This indicates a user requested -linkmode=external.
   560  		// The startup code uses an import of runtime/cgo to decide
   561  		// whether to initialize the TLS.  So give it one. This could
   562  		// be handled differently but it's an unusual case.
   563  		if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil && lib.Shlib == "" {
   564  			if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
   565  				Exitf("cannot implicitly include runtime/cgo in a shared library")
   566  			}
   567  			for ; i < len(ctxt.Library); i++ {
   568  				lib := ctxt.Library[i]
   569  				if lib.Shlib == "" {
   570  					loadobjfile(ctxt, lib)
   571  				}
   572  			}
   573  		}
   574  	}
   575  
   576  	// Add non-package symbols and references of externally defined symbols.
   577  	ctxt.loader.LoadSyms(ctxt.Arch)
   578  
   579  	// Load symbols from shared libraries, after all Go object symbols are loaded.
   580  	for _, lib := range ctxt.Library {
   581  		if lib.Shlib != "" {
   582  			if ctxt.Debugvlog > 1 {
   583  				ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref)
   584  			}
   585  			ldshlibsyms(ctxt, lib.Shlib)
   586  		}
   587  	}
   588  
   589  	// Process cgo directives (has to be done before host object loading).
   590  	ctxt.loadcgodirectives()
   591  
   592  	// Conditionally load host objects, or setup for external linking.
   593  	hostobjs(ctxt)
   594  	hostlinksetup(ctxt)
   595  
   596  	if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
   597  		// If we have any undefined symbols in external
   598  		// objects, try to read them from the libgcc file.
   599  		any := false
   600  		undefs := ctxt.loader.UndefinedRelocTargets(1)
   601  		if len(undefs) > 0 {
   602  			any = true
   603  		}
   604  		if any {
   605  			if *flagLibGCC == "" {
   606  				*flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
   607  			}
   608  			if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" {
   609  				// On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a".
   610  				// In this case we fail to load libgcc.a and can encounter link
   611  				// errors - see if we can find libcompiler_rt.a instead.
   612  				*flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
   613  			}
   614  			if ctxt.HeadType == objabi.Hwindows {
   615  				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
   616  					hostArchive(ctxt, p)
   617  				}
   618  				if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
   619  					hostArchive(ctxt, p)
   620  				}
   621  				// Link libmsvcrt.a to resolve '__acrt_iob_func' symbol
   622  				// (see https://golang.org/issue/23649 for details).
   623  				if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" {
   624  					hostArchive(ctxt, p)
   625  				}
   626  				// TODO: maybe do something similar to peimporteddlls to collect all lib names
   627  				// and try link them all to final exe just like libmingwex.a and libmingw32.a:
   628  				/*
   629  					for:
   630  					#cgo windows LDFLAGS: -lmsvcrt -lm
   631  					import:
   632  					libmsvcrt.a libm.a
   633  				*/
   634  			}
   635  			if *flagLibGCC != "none" {
   636  				hostArchive(ctxt, *flagLibGCC)
   637  			}
   638  		}
   639  	}
   640  
   641  	// We've loaded all the code now.
   642  	ctxt.Loaded = true
   643  
   644  	importcycles()
   645  
   646  	strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
   647  }
   648  
   649  // loadcgodirectives reads the previously discovered cgo directives, creating
   650  // symbols in preparation for host object loading or use later in the link.
   651  func (ctxt *Link) loadcgodirectives() {
   652  	l := ctxt.loader
   653  	hostObjSyms := make(map[loader.Sym]struct{})
   654  	for _, d := range ctxt.cgodata {
   655  		setCgoAttr(ctxt, d.file, d.pkg, d.directives, hostObjSyms)
   656  	}
   657  	ctxt.cgodata = nil
   658  
   659  	if ctxt.LinkMode == LinkInternal {
   660  		// Drop all the cgo_import_static declarations.
   661  		// Turns out we won't be needing them.
   662  		for symIdx := range hostObjSyms {
   663  			if l.SymType(symIdx) == sym.SHOSTOBJ {
   664  				// If a symbol was marked both
   665  				// cgo_import_static and cgo_import_dynamic,
   666  				// then we want to make it cgo_import_dynamic
   667  				// now.
   668  				su := l.MakeSymbolUpdater(symIdx)
   669  				if l.SymExtname(symIdx) != "" && l.SymDynimplib(symIdx) != "" && !(l.AttrCgoExportStatic(symIdx) || l.AttrCgoExportDynamic(symIdx)) {
   670  					su.SetType(sym.SDYNIMPORT)
   671  				} else {
   672  					su.SetType(0)
   673  				}
   674  			}
   675  		}
   676  	}
   677  }
   678  
   679  // Set up flags and special symbols depending on the platform build mode.
   680  // This version works with loader.Loader.
   681  func (ctxt *Link) linksetup() {
   682  	switch ctxt.BuildMode {
   683  	case BuildModeCShared, BuildModePlugin:
   684  		symIdx := ctxt.loader.LookupOrCreateSym("runtime.islibrary", 0)
   685  		sb := ctxt.loader.MakeSymbolUpdater(symIdx)
   686  		sb.SetType(sym.SNOPTRDATA)
   687  		sb.AddUint8(1)
   688  	case BuildModeCArchive:
   689  		symIdx := ctxt.loader.LookupOrCreateSym("runtime.isarchive", 0)
   690  		sb := ctxt.loader.MakeSymbolUpdater(symIdx)
   691  		sb.SetType(sym.SNOPTRDATA)
   692  		sb.AddUint8(1)
   693  	}
   694  
   695  	// Recalculate pe parameters now that we have ctxt.LinkMode set.
   696  	if ctxt.HeadType == objabi.Hwindows {
   697  		Peinit(ctxt)
   698  	}
   699  
   700  	if ctxt.LinkMode == LinkExternal {
   701  		// When external linking, we are creating an object file. The
   702  		// absolute address is irrelevant.
   703  		*FlagTextAddr = 0
   704  	}
   705  
   706  	// If there are no dynamic libraries needed, gcc disables dynamic linking.
   707  	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   708  	// assumes that a dynamic binary always refers to at least one dynamic library.
   709  	// Rather than be a source of test cases for glibc, disable dynamic linking
   710  	// the same way that gcc would.
   711  	//
   712  	// Exception: on OS X, programs such as Shark only work with dynamic
   713  	// binaries, so leave it enabled on OS X (Mach-O) binaries.
   714  	// Also leave it enabled on Solaris which doesn't support
   715  	// statically linked binaries.
   716  	if ctxt.BuildMode == BuildModeExe {
   717  		if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
   718  			*FlagD = true
   719  		}
   720  	}
   721  
   722  	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && buildcfg.GOOS != "aix" {
   723  		toc := ctxt.loader.LookupOrCreateSym(".TOC.", 0)
   724  		sb := ctxt.loader.MakeSymbolUpdater(toc)
   725  		sb.SetType(sym.SDYNIMPORT)
   726  	}
   727  
   728  	// The Android Q linker started to complain about underalignment of the our TLS
   729  	// section. We don't actually use the section on android, so don't
   730  	// generate it.
   731  	if buildcfg.GOOS != "android" {
   732  		tlsg := ctxt.loader.LookupOrCreateSym("runtime.tlsg", 0)
   733  		sb := ctxt.loader.MakeSymbolUpdater(tlsg)
   734  
   735  		// runtime.tlsg is used for external linking on platforms that do not define
   736  		// a variable to hold g in assembly (currently only intel).
   737  		if sb.Type() == 0 {
   738  			sb.SetType(sym.STLSBSS)
   739  			sb.SetSize(int64(ctxt.Arch.PtrSize))
   740  		} else if sb.Type() != sym.SDYNIMPORT {
   741  			Errorf(nil, "runtime declared tlsg variable %v", sb.Type())
   742  		}
   743  		ctxt.loader.SetAttrReachable(tlsg, true)
   744  		ctxt.Tlsg = tlsg
   745  	}
   746  
   747  	var moduledata loader.Sym
   748  	var mdsb *loader.SymbolBuilder
   749  	if ctxt.BuildMode == BuildModePlugin {
   750  		moduledata = ctxt.loader.LookupOrCreateSym("local.pluginmoduledata", 0)
   751  		mdsb = ctxt.loader.MakeSymbolUpdater(moduledata)
   752  		ctxt.loader.SetAttrLocal(moduledata, true)
   753  	} else {
   754  		moduledata = ctxt.loader.LookupOrCreateSym("runtime.firstmoduledata", 0)
   755  		mdsb = ctxt.loader.MakeSymbolUpdater(moduledata)
   756  	}
   757  	if mdsb.Type() != 0 && mdsb.Type() != sym.SDYNIMPORT {
   758  		// If the module (toolchain-speak for "executable or shared
   759  		// library") we are linking contains the runtime package, it
   760  		// will define the runtime.firstmoduledata symbol and we
   761  		// truncate it back to 0 bytes so we can define its entire
   762  		// contents in symtab.go:symtab().
   763  		mdsb.SetSize(0)
   764  
   765  		// In addition, on ARM, the runtime depends on the linker
   766  		// recording the value of GOARM.
   767  		if ctxt.Arch.Family == sys.ARM {
   768  			goarm := ctxt.loader.LookupOrCreateSym("runtime.goarm", 0)
   769  			sb := ctxt.loader.MakeSymbolUpdater(goarm)
   770  			sb.SetType(sym.SDATA)
   771  			sb.SetSize(0)
   772  			sb.AddUint8(uint8(buildcfg.GOARM))
   773  		}
   774  
   775  		// Set runtime.disableMemoryProfiling bool if
   776  		// runtime.MemProfile is not retained in the binary after
   777  		// deadcode (and we're not dynamically linking).
   778  		memProfile := ctxt.loader.Lookup("runtime.MemProfile", abiInternalVer)
   779  		if memProfile != 0 && !ctxt.loader.AttrReachable(memProfile) && !ctxt.DynlinkingGo() {
   780  			memProfSym := ctxt.loader.LookupOrCreateSym("runtime.disableMemoryProfiling", 0)
   781  			sb := ctxt.loader.MakeSymbolUpdater(memProfSym)
   782  			sb.SetType(sym.SDATA)
   783  			sb.SetSize(0)
   784  			sb.AddUint8(1) // true bool
   785  		}
   786  	} else {
   787  		// If OTOH the module does not contain the runtime package,
   788  		// create a local symbol for the moduledata.
   789  		moduledata = ctxt.loader.LookupOrCreateSym("local.moduledata", 0)
   790  		mdsb = ctxt.loader.MakeSymbolUpdater(moduledata)
   791  		ctxt.loader.SetAttrLocal(moduledata, true)
   792  	}
   793  	// In all cases way we mark the moduledata as noptrdata to hide it from
   794  	// the GC.
   795  	mdsb.SetType(sym.SNOPTRDATA)
   796  	ctxt.loader.SetAttrReachable(moduledata, true)
   797  	ctxt.Moduledata = moduledata
   798  
   799  	if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
   800  		if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
   801  			got := ctxt.loader.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0)
   802  			sb := ctxt.loader.MakeSymbolUpdater(got)
   803  			sb.SetType(sym.SDYNIMPORT)
   804  			ctxt.loader.SetAttrReachable(got, true)
   805  		}
   806  	}
   807  
   808  	// DWARF-gen and other phases require that the unit Textp slices
   809  	// be populated, so that it can walk the functions in each unit.
   810  	// Call into the loader to do this (requires that we collect the
   811  	// set of internal libraries first). NB: might be simpler if we
   812  	// moved isRuntimeDepPkg to cmd/internal and then did the test in
   813  	// loader.AssignTextSymbolOrder.
   814  	ctxt.Library = postorder(ctxt.Library)
   815  	intlibs := []bool{}
   816  	for _, lib := range ctxt.Library {
   817  		intlibs = append(intlibs, isRuntimeDepPkg(lib.Pkg))
   818  	}
   819  	ctxt.Textp = ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs, ctxt.Textp)
   820  }
   821  
   822  // mangleTypeSym shortens the names of symbols that represent Go types
   823  // if they are visible in the symbol table.
   824  //
   825  // As the names of these symbols are derived from the string of
   826  // the type, they can run to many kilobytes long. So we shorten
   827  // them using a SHA-1 when the name appears in the final binary.
   828  // This also removes characters that upset external linkers.
   829  //
   830  // These are the symbols that begin with the prefix 'type.' and
   831  // contain run-time type information used by the runtime and reflect
   832  // packages. All Go binaries contain these symbols, but only
   833  // those programs loaded dynamically in multiple parts need these
   834  // symbols to have entries in the symbol table.
   835  func (ctxt *Link) mangleTypeSym() {
   836  	if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() {
   837  		return
   838  	}
   839  
   840  	ldr := ctxt.loader
   841  	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
   842  		if !ldr.AttrReachable(s) && !ctxt.linkShared {
   843  			// If -linkshared, the GCProg generation code may need to reach
   844  			// out to the shared library for the type descriptor's data, even
   845  			// the type descriptor itself is not actually needed at run time
   846  			// (therefore not reachable). We still need to mangle its name,
   847  			// so it is consistent with the one stored in the shared library.
   848  			continue
   849  		}
   850  		name := ldr.SymName(s)
   851  		newName := typeSymbolMangle(name)
   852  		if newName != name {
   853  			ldr.SetSymExtname(s, newName)
   854  
   855  			// When linking against a shared library, the Go object file may
   856  			// have reference to the original symbol name whereas the shared
   857  			// library provides a symbol with the mangled name. We need to
   858  			// copy the payload of mangled to original.
   859  			// XXX maybe there is a better way to do this.
   860  			dup := ldr.Lookup(newName, ldr.SymVersion(s))
   861  			if dup != 0 {
   862  				st := ldr.SymType(s)
   863  				dt := ldr.SymType(dup)
   864  				if st == sym.Sxxx && dt != sym.Sxxx {
   865  					ldr.CopySym(dup, s)
   866  				}
   867  			}
   868  		}
   869  	}
   870  }
   871  
   872  // typeSymbolMangle mangles the given symbol name into something shorter.
   873  //
   874  // Keep the type.. prefix, which parts of the linker (like the
   875  // DWARF generator) know means the symbol is not decodable.
   876  // Leave type.runtime. symbols alone, because other parts of
   877  // the linker manipulates them.
   878  func typeSymbolMangle(name string) string {
   879  	if !strings.HasPrefix(name, "type.") {
   880  		return name
   881  	}
   882  	if strings.HasPrefix(name, "type.runtime.") {
   883  		return name
   884  	}
   885  	if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
   886  		return name
   887  	}
   888  	hash := sha1.Sum([]byte(name))
   889  	prefix := "type."
   890  	if name[5] == '.' {
   891  		prefix = "type.."
   892  	}
   893  	return prefix + base64.StdEncoding.EncodeToString(hash[:6])
   894  }
   895  
   896  /*
   897   * look for the next file in an archive.
   898   * adapted from libmach.
   899   */
   900  func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
   901  	if off&1 != 0 {
   902  		off++
   903  	}
   904  	bp.MustSeek(off, 0)
   905  	var buf [SAR_HDR]byte
   906  	if n, err := io.ReadFull(bp, buf[:]); err != nil {
   907  		if n == 0 && err != io.EOF {
   908  			return -1
   909  		}
   910  		return 0
   911  	}
   912  
   913  	a.name = artrim(buf[0:16])
   914  	a.date = artrim(buf[16:28])
   915  	a.uid = artrim(buf[28:34])
   916  	a.gid = artrim(buf[34:40])
   917  	a.mode = artrim(buf[40:48])
   918  	a.size = artrim(buf[48:58])
   919  	a.fmag = artrim(buf[58:60])
   920  
   921  	arsize := atolwhex(a.size)
   922  	if arsize&1 != 0 {
   923  		arsize++
   924  	}
   925  	return arsize + SAR_HDR
   926  }
   927  
   928  func loadobjfile(ctxt *Link, lib *sym.Library) {
   929  	pkg := objabi.PathToPrefix(lib.Pkg)
   930  
   931  	if ctxt.Debugvlog > 1 {
   932  		ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg)
   933  	}
   934  	f, err := bio.Open(lib.File)
   935  	if err != nil {
   936  		Exitf("cannot open file %s: %v", lib.File, err)
   937  	}
   938  	defer f.Close()
   939  	defer func() {
   940  		if pkg == "main" && !lib.Main {
   941  			Exitf("%s: not package main", lib.File)
   942  		}
   943  	}()
   944  
   945  	for i := 0; i < len(ARMAG); i++ {
   946  		if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
   947  			continue
   948  		}
   949  
   950  		/* load it as a regular file */
   951  		l := f.MustSeek(0, 2)
   952  		f.MustSeek(0, 0)
   953  		ldobj(ctxt, f, lib, l, lib.File, lib.File)
   954  		return
   955  	}
   956  
   957  	/*
   958  	 * load all the object files from the archive now.
   959  	 * this gives us sequential file access and keeps us
   960  	 * from needing to come back later to pick up more
   961  	 * objects.  it breaks the usual C archive model, but
   962  	 * this is Go, not C.  the common case in Go is that
   963  	 * we need to load all the objects, and then we throw away
   964  	 * the individual symbols that are unused.
   965  	 *
   966  	 * loading every object will also make it possible to
   967  	 * load foreign objects not referenced by __.PKGDEF.
   968  	 */
   969  	var arhdr ArHdr
   970  	off := f.Offset()
   971  	for {
   972  		l := nextar(f, off, &arhdr)
   973  		if l == 0 {
   974  			break
   975  		}
   976  		if l < 0 {
   977  			Exitf("%s: malformed archive", lib.File)
   978  		}
   979  		off += l
   980  
   981  		// __.PKGDEF isn't a real Go object file, and it's
   982  		// absent in -linkobj builds anyway. Skipping it
   983  		// ensures consistency between -linkobj and normal
   984  		// build modes.
   985  		if arhdr.name == pkgdef {
   986  			continue
   987  		}
   988  
   989  		// Skip other special (non-object-file) sections that
   990  		// build tools may have added. Such sections must have
   991  		// short names so that the suffix is not truncated.
   992  		if len(arhdr.name) < 16 {
   993  			if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" {
   994  				continue
   995  			}
   996  		}
   997  
   998  		pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
   999  		l = atolwhex(arhdr.size)
  1000  		ldobj(ctxt, f, lib, l, pname, lib.File)
  1001  	}
  1002  }
  1003  
  1004  type Hostobj struct {
  1005  	ld     func(*Link, *bio.Reader, string, int64, string)
  1006  	pkg    string
  1007  	pn     string
  1008  	file   string
  1009  	off    int64
  1010  	length int64
  1011  }
  1012  
  1013  var hostobj []Hostobj
  1014  
  1015  // These packages can use internal linking mode.
  1016  // Others trigger external mode.
  1017  var internalpkg = []string{
  1018  	"crypto/x509",
  1019  	"net",
  1020  	"os/user",
  1021  	"runtime/cgo",
  1022  	"runtime/race",
  1023  	"runtime/msan",
  1024  	"runtime/asan",
  1025  }
  1026  
  1027  func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
  1028  	isinternal := false
  1029  	for _, intpkg := range internalpkg {
  1030  		if pkg == intpkg {
  1031  			isinternal = true
  1032  			break
  1033  		}
  1034  	}
  1035  
  1036  	// DragonFly declares errno with __thread, which results in a symbol
  1037  	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
  1038  	// currently know how to handle TLS relocations, hence we have to
  1039  	// force external linking for any libraries that link in code that
  1040  	// uses errno. This can be removed if the Go linker ever supports
  1041  	// these relocation types.
  1042  	if headType == objabi.Hdragonfly {
  1043  		if pkg == "net" || pkg == "os/user" {
  1044  			isinternal = false
  1045  		}
  1046  	}
  1047  
  1048  	if !isinternal {
  1049  		externalobj = true
  1050  	}
  1051  
  1052  	hostobj = append(hostobj, Hostobj{})
  1053  	h := &hostobj[len(hostobj)-1]
  1054  	h.ld = ld
  1055  	h.pkg = pkg
  1056  	h.pn = pn
  1057  	h.file = file
  1058  	h.off = f.Offset()
  1059  	h.length = length
  1060  	return h
  1061  }
  1062  
  1063  func hostobjs(ctxt *Link) {
  1064  	if ctxt.LinkMode != LinkInternal {
  1065  		return
  1066  	}
  1067  	var h *Hostobj
  1068  
  1069  	for i := 0; i < len(hostobj); i++ {
  1070  		h = &hostobj[i]
  1071  		f, err := bio.Open(h.file)
  1072  		if err != nil {
  1073  			Exitf("cannot reopen %s: %v", h.pn, err)
  1074  		}
  1075  
  1076  		f.MustSeek(h.off, 0)
  1077  		if h.ld == nil {
  1078  			Errorf(nil, "%s: unrecognized object file format", h.pn)
  1079  			continue
  1080  		}
  1081  		h.ld(ctxt, f, h.pkg, h.length, h.pn)
  1082  		f.Close()
  1083  	}
  1084  }
  1085  
  1086  func hostlinksetup(ctxt *Link) {
  1087  	if ctxt.LinkMode != LinkExternal {
  1088  		return
  1089  	}
  1090  
  1091  	// For external link, record that we need to tell the external linker -s,
  1092  	// and turn off -s internally: the external linker needs the symbol
  1093  	// information for its final link.
  1094  	debug_s = *FlagS
  1095  	*FlagS = false
  1096  
  1097  	// create temporary directory and arrange cleanup
  1098  	if *flagTmpdir == "" {
  1099  		dir, err := ioutil.TempDir("", "go-link-")
  1100  		if err != nil {
  1101  			log.Fatal(err)
  1102  		}
  1103  		*flagTmpdir = dir
  1104  		ownTmpDir = true
  1105  		AtExit(func() {
  1106  			os.RemoveAll(*flagTmpdir)
  1107  		})
  1108  	}
  1109  
  1110  	// change our output to temporary object file
  1111  	if err := ctxt.Out.Close(); err != nil {
  1112  		Exitf("error closing output file")
  1113  	}
  1114  	mayberemoveoutfile()
  1115  
  1116  	p := filepath.Join(*flagTmpdir, "go.o")
  1117  	if err := ctxt.Out.Open(p); err != nil {
  1118  		Exitf("cannot create %s: %v", p, err)
  1119  	}
  1120  }
  1121  
  1122  // hostobjCopy creates a copy of the object files in hostobj in a
  1123  // temporary directory.
  1124  func hostobjCopy() (paths []string) {
  1125  	var wg sync.WaitGroup
  1126  	sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
  1127  	for i, h := range hostobj {
  1128  		h := h
  1129  		dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
  1130  		paths = append(paths, dst)
  1131  
  1132  		wg.Add(1)
  1133  		go func() {
  1134  			sema <- struct{}{}
  1135  			defer func() {
  1136  				<-sema
  1137  				wg.Done()
  1138  			}()
  1139  			f, err := os.Open(h.file)
  1140  			if err != nil {
  1141  				Exitf("cannot reopen %s: %v", h.pn, err)
  1142  			}
  1143  			defer f.Close()
  1144  			if _, err := f.Seek(h.off, 0); err != nil {
  1145  				Exitf("cannot seek %s: %v", h.pn, err)
  1146  			}
  1147  
  1148  			w, err := os.Create(dst)
  1149  			if err != nil {
  1150  				Exitf("cannot create %s: %v", dst, err)
  1151  			}
  1152  			if _, err := io.CopyN(w, f, h.length); err != nil {
  1153  				Exitf("cannot write %s: %v", dst, err)
  1154  			}
  1155  			if err := w.Close(); err != nil {
  1156  				Exitf("cannot close %s: %v", dst, err)
  1157  			}
  1158  		}()
  1159  	}
  1160  	wg.Wait()
  1161  	return paths
  1162  }
  1163  
  1164  // writeGDBLinkerScript creates gcc linker script file in temp
  1165  // directory. writeGDBLinkerScript returns created file path.
  1166  // The script is used to work around gcc bug
  1167  // (see https://golang.org/issue/20183 for details).
  1168  func writeGDBLinkerScript() string {
  1169  	name := "fix_debug_gdb_scripts.ld"
  1170  	path := filepath.Join(*flagTmpdir, name)
  1171  	src := `SECTIONS
  1172  {
  1173    .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
  1174    {
  1175      *(.debug_gdb_scripts)
  1176    }
  1177  }
  1178  INSERT AFTER .debug_types;
  1179  `
  1180  	err := ioutil.WriteFile(path, []byte(src), 0666)
  1181  	if err != nil {
  1182  		Errorf(nil, "WriteFile %s failed: %v", name, err)
  1183  	}
  1184  	return path
  1185  }
  1186  
  1187  // archive builds a .a archive from the hostobj object files.
  1188  func (ctxt *Link) archive() {
  1189  	if ctxt.BuildMode != BuildModeCArchive {
  1190  		return
  1191  	}
  1192  
  1193  	exitIfErrors()
  1194  
  1195  	if *flagExtar == "" {
  1196  		*flagExtar = "ar"
  1197  	}
  1198  
  1199  	mayberemoveoutfile()
  1200  
  1201  	// Force the buffer to flush here so that external
  1202  	// tools will see a complete file.
  1203  	if err := ctxt.Out.Close(); err != nil {
  1204  		Exitf("error closing %v", *flagOutfile)
  1205  	}
  1206  
  1207  	argv := []string{*flagExtar, "-q", "-c", "-s"}
  1208  	if ctxt.HeadType == objabi.Haix {
  1209  		argv = append(argv, "-X64")
  1210  	}
  1211  	argv = append(argv, *flagOutfile)
  1212  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1213  	argv = append(argv, hostobjCopy()...)
  1214  
  1215  	if ctxt.Debugvlog != 0 {
  1216  		ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
  1217  	}
  1218  
  1219  	// If supported, use syscall.Exec() to invoke the archive command,
  1220  	// which should be the final remaining step needed for the link.
  1221  	// This will reduce peak RSS for the link (and speed up linking of
  1222  	// large applications), since when the archive command runs we
  1223  	// won't be holding onto all of the linker's live memory.
  1224  	if syscallExecSupported && !ownTmpDir {
  1225  		runAtExitFuncs()
  1226  		ctxt.execArchive(argv)
  1227  		panic("should not get here")
  1228  	}
  1229  
  1230  	// Otherwise invoke 'ar' in the usual way (fork + exec).
  1231  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1232  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1233  	}
  1234  }
  1235  
  1236  func (ctxt *Link) hostlink() {
  1237  	if ctxt.LinkMode != LinkExternal || nerrors > 0 {
  1238  		return
  1239  	}
  1240  	if ctxt.BuildMode == BuildModeCArchive {
  1241  		return
  1242  	}
  1243  
  1244  	var argv []string
  1245  	argv = append(argv, ctxt.extld()...)
  1246  	argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
  1247  
  1248  	if *FlagS || debug_s {
  1249  		if ctxt.HeadType == objabi.Hdarwin {
  1250  			// Recent versions of macOS print
  1251  			//	ld: warning: option -s is obsolete and being ignored
  1252  			// so do not pass any arguments.
  1253  		} else {
  1254  			argv = append(argv, "-s")
  1255  		}
  1256  	}
  1257  
  1258  	// On darwin, whether to combine DWARF into executable.
  1259  	// Only macOS supports unmapped segments such as our __DWARF segment.
  1260  	combineDwarf := ctxt.IsDarwin() && !*FlagS && !*FlagW && !debug_s && machoPlatform == PLATFORM_MACOS
  1261  
  1262  	switch ctxt.HeadType {
  1263  	case objabi.Hdarwin:
  1264  		if combineDwarf {
  1265  			// Leave room for DWARF combining.
  1266  			// -headerpad is incompatible with -fembed-bitcode.
  1267  			argv = append(argv, "-Wl,-headerpad,1144")
  1268  		}
  1269  		if ctxt.DynlinkingGo() && buildcfg.GOOS != "ios" {
  1270  			// -flat_namespace is deprecated on iOS.
  1271  			// It is useful for supporting plugins. We don't support plugins on iOS.
  1272  			// -flat_namespace may cause the dynamic linker to hang at forkExec when
  1273  			// resolving a lazy binding. See issue 38824.
  1274  			// Force eager resolution to work around.
  1275  			argv = append(argv, "-Wl,-flat_namespace", "-Wl,-bind_at_load")
  1276  		}
  1277  		if !combineDwarf {
  1278  			argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols
  1279  		}
  1280  	case objabi.Hopenbsd:
  1281  		argv = append(argv, "-Wl,-nopie")
  1282  		argv = append(argv, "-pthread")
  1283  	case objabi.Hwindows:
  1284  		if windowsgui {
  1285  			argv = append(argv, "-mwindows")
  1286  		} else {
  1287  			argv = append(argv, "-mconsole")
  1288  		}
  1289  		// Mark as having awareness of terminal services, to avoid
  1290  		// ancient compatibility hacks.
  1291  		argv = append(argv, "-Wl,--tsaware")
  1292  
  1293  		// Enable DEP
  1294  		argv = append(argv, "-Wl,--nxcompat")
  1295  
  1296  		argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
  1297  		argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
  1298  		argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
  1299  		argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
  1300  	case objabi.Haix:
  1301  		argv = append(argv, "-pthread")
  1302  		// prevent ld to reorder .text functions to keep the same
  1303  		// first/last functions for moduledata.
  1304  		argv = append(argv, "-Wl,-bnoobjreorder")
  1305  		// mcmodel=large is needed for every gcc generated files, but
  1306  		// ld still need -bbigtoc in order to allow larger TOC.
  1307  		argv = append(argv, "-mcmodel=large")
  1308  		argv = append(argv, "-Wl,-bbigtoc")
  1309  	}
  1310  
  1311  	// Enable ASLR on Windows.
  1312  	addASLRargs := func(argv []string) []string {
  1313  		// Enable ASLR.
  1314  		argv = append(argv, "-Wl,--dynamicbase")
  1315  		// enable high-entropy ASLR on 64-bit.
  1316  		if ctxt.Arch.PtrSize >= 8 {
  1317  			argv = append(argv, "-Wl,--high-entropy-va")
  1318  		}
  1319  		return argv
  1320  	}
  1321  
  1322  	switch ctxt.BuildMode {
  1323  	case BuildModeExe:
  1324  		if ctxt.HeadType == objabi.Hdarwin {
  1325  			if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() {
  1326  				argv = append(argv, "-Wl,-no_pie")
  1327  				argv = append(argv, "-Wl,-pagezero_size,4000000")
  1328  			}
  1329  		}
  1330  	case BuildModePIE:
  1331  		switch ctxt.HeadType {
  1332  		case objabi.Hdarwin, objabi.Haix:
  1333  		case objabi.Hwindows:
  1334  			argv = addASLRargs(argv)
  1335  		default:
  1336  			// ELF.
  1337  			if ctxt.UseRelro() {
  1338  				argv = append(argv, "-Wl,-z,relro")
  1339  			}
  1340  			argv = append(argv, "-pie")
  1341  		}
  1342  	case BuildModeCShared:
  1343  		if ctxt.HeadType == objabi.Hdarwin {
  1344  			argv = append(argv, "-dynamiclib")
  1345  		} else {
  1346  			if ctxt.UseRelro() {
  1347  				argv = append(argv, "-Wl,-z,relro")
  1348  			}
  1349  			argv = append(argv, "-shared")
  1350  			if ctxt.HeadType == objabi.Hwindows {
  1351  				if *flagAslr {
  1352  					argv = addASLRargs(argv)
  1353  				}
  1354  			} else {
  1355  				// Pass -z nodelete to mark the shared library as
  1356  				// non-closeable: a dlclose will do nothing.
  1357  				argv = append(argv, "-Wl,-z,nodelete")
  1358  				// Only pass Bsymbolic on non-Windows.
  1359  				argv = append(argv, "-Wl,-Bsymbolic")
  1360  			}
  1361  		}
  1362  	case BuildModeShared:
  1363  		if ctxt.UseRelro() {
  1364  			argv = append(argv, "-Wl,-z,relro")
  1365  		}
  1366  		argv = append(argv, "-shared")
  1367  	case BuildModePlugin:
  1368  		if ctxt.HeadType == objabi.Hdarwin {
  1369  			argv = append(argv, "-dynamiclib")
  1370  		} else {
  1371  			if ctxt.UseRelro() {
  1372  				argv = append(argv, "-Wl,-z,relro")
  1373  			}
  1374  			argv = append(argv, "-shared")
  1375  		}
  1376  	}
  1377  
  1378  	var altLinker string
  1379  	if ctxt.IsELF && ctxt.DynlinkingGo() {
  1380  		// We force all symbol resolution to be done at program startup
  1381  		// because lazy PLT resolution can use large amounts of stack at
  1382  		// times we cannot allow it to do so.
  1383  		argv = append(argv, "-Wl,-znow")
  1384  
  1385  		// Do not let the host linker generate COPY relocations. These
  1386  		// can move symbols out of sections that rely on stable offsets
  1387  		// from the beginning of the section (like sym.STYPE).
  1388  		argv = append(argv, "-Wl,-znocopyreloc")
  1389  
  1390  		if buildcfg.GOOS == "android" {
  1391  			// Use lld to avoid errors from default linker (issue #38838)
  1392  			altLinker = "lld"
  1393  		}
  1394  
  1395  		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && buildcfg.GOOS == "linux" {
  1396  			// On ARM, the GNU linker will generate COPY relocations
  1397  			// even with -znocopyreloc set.
  1398  			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
  1399  			//
  1400  			// On ARM64, the GNU linker will fail instead of
  1401  			// generating COPY relocations.
  1402  			//
  1403  			// In both cases, switch to gold.
  1404  			altLinker = "gold"
  1405  
  1406  			// If gold is not installed, gcc will silently switch
  1407  			// back to ld.bfd. So we parse the version information
  1408  			// and provide a useful error if gold is missing.
  1409  			name, args := flagExtld[0], flagExtld[1:]
  1410  			args = append(args, "-fuse-ld=gold", "-Wl,--version")
  1411  			cmd := exec.Command(name, args...)
  1412  			if out, err := cmd.CombinedOutput(); err == nil {
  1413  				if !bytes.Contains(out, []byte("GNU gold")) {
  1414  					log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
  1415  				}
  1416  			}
  1417  		}
  1418  	}
  1419  	if ctxt.Arch.Family == sys.ARM64 && buildcfg.GOOS == "freebsd" {
  1420  		// Switch to ld.bfd on freebsd/arm64.
  1421  		altLinker = "bfd"
  1422  
  1423  		// Provide a useful error if ld.bfd is missing.
  1424  		name, args := flagExtld[0], flagExtld[1:]
  1425  		args = append(args, "-fuse-ld=bfd", "-Wl,--version")
  1426  		cmd := exec.Command(name, args...)
  1427  		if out, err := cmd.CombinedOutput(); err == nil {
  1428  			if !bytes.Contains(out, []byte("GNU ld")) {
  1429  				log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
  1430  			}
  1431  		}
  1432  	}
  1433  	if altLinker != "" {
  1434  		argv = append(argv, "-fuse-ld="+altLinker)
  1435  	}
  1436  
  1437  	if ctxt.IsELF && len(buildinfo) > 0 {
  1438  		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
  1439  	}
  1440  
  1441  	// On Windows, given -o foo, GCC will append ".exe" to produce
  1442  	// "foo.exe".  We have decided that we want to honor the -o
  1443  	// option. To make this work, we append a '.' so that GCC
  1444  	// will decide that the file already has an extension. We
  1445  	// only want to do this when producing a Windows output file
  1446  	// on a Windows host.
  1447  	outopt := *flagOutfile
  1448  	if buildcfg.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
  1449  		outopt += "."
  1450  	}
  1451  	argv = append(argv, "-o")
  1452  	argv = append(argv, outopt)
  1453  
  1454  	if rpath.val != "" {
  1455  		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
  1456  	}
  1457  
  1458  	if *flagInterpreter != "" {
  1459  		// Many linkers support both -I and the --dynamic-linker flags
  1460  		// to set the ELF interpreter, but lld only supports
  1461  		// --dynamic-linker so prefer that (ld on very old Solaris only
  1462  		// supports -I but that seems less important).
  1463  		argv = append(argv, fmt.Sprintf("-Wl,--dynamic-linker,%s", *flagInterpreter))
  1464  	}
  1465  
  1466  	// Force global symbols to be exported for dlopen, etc.
  1467  	if ctxt.IsELF {
  1468  		argv = append(argv, "-rdynamic")
  1469  	}
  1470  	if ctxt.HeadType == objabi.Haix {
  1471  		fileName := xcoffCreateExportFile(ctxt)
  1472  		argv = append(argv, "-Wl,-bE:"+fileName)
  1473  	}
  1474  
  1475  	const unusedArguments = "-Qunused-arguments"
  1476  	if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, unusedArguments) {
  1477  		argv = append(argv, unusedArguments)
  1478  	}
  1479  
  1480  	const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
  1481  	if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
  1482  		argv = append(argv, compressDWARF)
  1483  	}
  1484  
  1485  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1486  	argv = append(argv, hostobjCopy()...)
  1487  	if ctxt.HeadType == objabi.Haix {
  1488  		// We want to have C files after Go files to remove
  1489  		// trampolines csects made by ld.
  1490  		argv = append(argv, "-nostartfiles")
  1491  		argv = append(argv, "/lib/crt0_64.o")
  1492  
  1493  		extld := ctxt.extld()
  1494  		name, args := extld[0], extld[1:]
  1495  		// Get starting files.
  1496  		getPathFile := func(file string) string {
  1497  			args := append(args, "-maix64", "--print-file-name="+file)
  1498  			out, err := exec.Command(name, args...).CombinedOutput()
  1499  			if err != nil {
  1500  				log.Fatalf("running %s failed: %v\n%s", extld, err, out)
  1501  			}
  1502  			return strings.Trim(string(out), "\n")
  1503  		}
  1504  		// Since GCC version 11, the 64-bit version of GCC starting files
  1505  		// are now suffixed by "_64". Even under "-maix64" multilib directory
  1506  		// "crtcxa.o" is 32-bit.
  1507  		crtcxa := getPathFile("crtcxa_64.o")
  1508  		if !filepath.IsAbs(crtcxa) {
  1509  			crtcxa = getPathFile("crtcxa.o")
  1510  		}
  1511  		crtdbase := getPathFile("crtdbase_64.o")
  1512  		if !filepath.IsAbs(crtdbase) {
  1513  			crtdbase = getPathFile("crtdbase.o")
  1514  		}
  1515  		argv = append(argv, crtcxa)
  1516  		argv = append(argv, crtdbase)
  1517  	}
  1518  
  1519  	if ctxt.linkShared {
  1520  		seenDirs := make(map[string]bool)
  1521  		seenLibs := make(map[string]bool)
  1522  		addshlib := func(path string) {
  1523  			dir, base := filepath.Split(path)
  1524  			if !seenDirs[dir] {
  1525  				argv = append(argv, "-L"+dir)
  1526  				if !rpath.set {
  1527  					argv = append(argv, "-Wl,-rpath="+dir)
  1528  				}
  1529  				seenDirs[dir] = true
  1530  			}
  1531  			base = strings.TrimSuffix(base, ".so")
  1532  			base = strings.TrimPrefix(base, "lib")
  1533  			if !seenLibs[base] {
  1534  				argv = append(argv, "-l"+base)
  1535  				seenLibs[base] = true
  1536  			}
  1537  		}
  1538  		for _, shlib := range ctxt.Shlibs {
  1539  			addshlib(shlib.Path)
  1540  			for _, dep := range shlib.Deps {
  1541  				if dep == "" {
  1542  					continue
  1543  				}
  1544  				libpath := findshlib(ctxt, dep)
  1545  				if libpath != "" {
  1546  					addshlib(libpath)
  1547  				}
  1548  			}
  1549  		}
  1550  	}
  1551  
  1552  	// clang, unlike GCC, passes -rdynamic to the linker
  1553  	// even when linking with -static, causing a linker
  1554  	// error when using GNU ld. So take out -rdynamic if
  1555  	// we added it. We do it in this order, rather than
  1556  	// only adding -rdynamic later, so that -extldflags
  1557  	// can override -rdynamic without using -static.
  1558  	// Similarly for -Wl,--dynamic-linker.
  1559  	checkStatic := func(arg string) {
  1560  		if ctxt.IsELF && arg == "-static" {
  1561  			for i := range argv {
  1562  				if argv[i] == "-rdynamic" || strings.HasPrefix(argv[i], "-Wl,--dynamic-linker,") {
  1563  					argv[i] = "-static"
  1564  				}
  1565  			}
  1566  		}
  1567  	}
  1568  
  1569  	for _, p := range ldflag {
  1570  		argv = append(argv, p)
  1571  		checkStatic(p)
  1572  	}
  1573  
  1574  	// When building a program with the default -buildmode=exe the
  1575  	// gc compiler generates code requires DT_TEXTREL in a
  1576  	// position independent executable (PIE). On systems where the
  1577  	// toolchain creates PIEs by default, and where DT_TEXTREL
  1578  	// does not work, the resulting programs will not run. See
  1579  	// issue #17847. To avoid this problem pass -no-pie to the
  1580  	// toolchain if it is supported.
  1581  	if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
  1582  		// GCC uses -no-pie, clang uses -nopie.
  1583  		for _, nopie := range []string{"-no-pie", "-nopie"} {
  1584  			if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
  1585  				argv = append(argv, nopie)
  1586  				break
  1587  			}
  1588  		}
  1589  	}
  1590  
  1591  	for _, p := range flagExtldflags {
  1592  		argv = append(argv, p)
  1593  		checkStatic(p)
  1594  	}
  1595  	if ctxt.HeadType == objabi.Hwindows {
  1596  		// Determine which linker we're using. Add in the extldflags in
  1597  		// case used has specified "-fuse-ld=...".
  1598  		extld := ctxt.extld()
  1599  		name, args := extld[0], extld[1:]
  1600  		args = append(args, flagExtldflags...)
  1601  		args = append(args, "-Wl,--version")
  1602  		cmd := exec.Command(name, args...)
  1603  		usingLLD := false
  1604  		if out, err := cmd.CombinedOutput(); err == nil {
  1605  			if bytes.Contains(out, []byte("LLD ")) {
  1606  				usingLLD = true
  1607  			}
  1608  		}
  1609  
  1610  		// use gcc linker script to work around gcc bug
  1611  		// (see https://golang.org/issue/20183 for details).
  1612  		if !usingLLD {
  1613  			p := writeGDBLinkerScript()
  1614  			argv = append(argv, "-Wl,-T,"+p)
  1615  		}
  1616  		// libmingw32 and libmingwex have some inter-dependencies,
  1617  		// so must use linker groups.
  1618  		argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
  1619  		argv = append(argv, peimporteddlls()...)
  1620  	}
  1621  
  1622  	if ctxt.Debugvlog != 0 {
  1623  		ctxt.Logf("host link:")
  1624  		for _, v := range argv {
  1625  			ctxt.Logf(" %q", v)
  1626  		}
  1627  		ctxt.Logf("\n")
  1628  	}
  1629  
  1630  	out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
  1631  	if err != nil {
  1632  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1633  	}
  1634  
  1635  	// Filter out useless linker warnings caused by bugs outside Go.
  1636  	// See also cmd/go/internal/work/exec.go's gccld method.
  1637  	var save [][]byte
  1638  	var skipLines int
  1639  	for _, line := range bytes.SplitAfter(out, []byte("\n")) {
  1640  		// golang.org/issue/26073 - Apple Xcode bug
  1641  		if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
  1642  			continue
  1643  		}
  1644  
  1645  		if skipLines > 0 {
  1646  			skipLines--
  1647  			continue
  1648  		}
  1649  
  1650  		// Remove TOC overflow warning on AIX.
  1651  		if bytes.Contains(line, []byte("ld: 0711-783")) {
  1652  			skipLines = 2
  1653  			continue
  1654  		}
  1655  
  1656  		save = append(save, line)
  1657  	}
  1658  	out = bytes.Join(save, nil)
  1659  
  1660  	if len(out) > 0 {
  1661  		// always print external output even if the command is successful, so that we don't
  1662  		// swallow linker warnings (see https://golang.org/issue/17935).
  1663  		ctxt.Logf("%s", out)
  1664  	}
  1665  
  1666  	if combineDwarf {
  1667  		// Find "dsymutils" and "strip" tools using CC --print-prog-name.
  1668  		var cc []string
  1669  		cc = append(cc, ctxt.extld()...)
  1670  		cc = append(cc, hostlinkArchArgs(ctxt.Arch)...)
  1671  		cc = append(cc, "--print-prog-name", "dsymutil")
  1672  		out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput()
  1673  		if err != nil {
  1674  			Exitf("%s: finding dsymutil failed: %v\n%s", os.Args[0], err, out)
  1675  		}
  1676  		dsymutilCmd := strings.TrimSuffix(string(out), "\n")
  1677  
  1678  		cc[len(cc)-1] = "strip"
  1679  		out, err = exec.Command(cc[0], cc[1:]...).CombinedOutput()
  1680  		if err != nil {
  1681  			Exitf("%s: finding strip failed: %v\n%s", os.Args[0], err, out)
  1682  		}
  1683  		stripCmd := strings.TrimSuffix(string(out), "\n")
  1684  
  1685  		dsym := filepath.Join(*flagTmpdir, "go.dwarf")
  1686  		if out, err := exec.Command(dsymutilCmd, "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
  1687  			Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
  1688  		}
  1689  		// Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil).
  1690  		// They contain temporary file paths and make the build not reproducible.
  1691  		if out, err := exec.Command(stripCmd, "-S", *flagOutfile).CombinedOutput(); err != nil {
  1692  			Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
  1693  		}
  1694  		// Skip combining if `dsymutil` didn't generate a file. See #11994.
  1695  		if _, err := os.Stat(dsym); os.IsNotExist(err) {
  1696  			return
  1697  		}
  1698  		// For os.Rename to work reliably, must be in same directory as outfile.
  1699  		combinedOutput := *flagOutfile + "~"
  1700  		exef, err := os.Open(*flagOutfile)
  1701  		if err != nil {
  1702  			Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1703  		}
  1704  		defer exef.Close()
  1705  		exem, err := macho.NewFile(exef)
  1706  		if err != nil {
  1707  			Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
  1708  		}
  1709  		if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
  1710  			Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1711  		}
  1712  		os.Remove(*flagOutfile)
  1713  		if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
  1714  			Exitf("%s: %v", os.Args[0], err)
  1715  		}
  1716  	}
  1717  	if ctxt.NeedCodeSign() {
  1718  		err := machoCodeSign(ctxt, *flagOutfile)
  1719  		if err != nil {
  1720  			Exitf("%s: code signing failed: %v", os.Args[0], err)
  1721  		}
  1722  	}
  1723  }
  1724  
  1725  var createTrivialCOnce sync.Once
  1726  
  1727  func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
  1728  	createTrivialCOnce.Do(func() {
  1729  		src := filepath.Join(*flagTmpdir, "trivial.c")
  1730  		if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
  1731  			Errorf(nil, "WriteFile trivial.c failed: %v", err)
  1732  		}
  1733  	})
  1734  
  1735  	flagsWithNextArgSkip := []string{
  1736  		"-F",
  1737  		"-l",
  1738  		"-L",
  1739  		"-framework",
  1740  		"-Wl,-framework",
  1741  		"-Wl,-rpath",
  1742  		"-Wl,-undefined",
  1743  	}
  1744  	flagsWithNextArgKeep := []string{
  1745  		"-arch",
  1746  		"-isysroot",
  1747  		"--sysroot",
  1748  		"-target",
  1749  	}
  1750  	prefixesToKeep := []string{
  1751  		"-f",
  1752  		"-m",
  1753  		"-p",
  1754  		"-Wl,",
  1755  		"-arch",
  1756  		"-isysroot",
  1757  		"--sysroot",
  1758  		"-target",
  1759  	}
  1760  
  1761  	flags := hostlinkArchArgs(arch)
  1762  	keep := false
  1763  	skip := false
  1764  	for _, f := range append(flagExtldflags, ldflag...) {
  1765  		if keep {
  1766  			flags = append(flags, f)
  1767  			keep = false
  1768  		} else if skip {
  1769  			skip = false
  1770  		} else if f == "" || f[0] != '-' {
  1771  		} else if contains(flagsWithNextArgSkip, f) {
  1772  			skip = true
  1773  		} else if contains(flagsWithNextArgKeep, f) {
  1774  			flags = append(flags, f)
  1775  			keep = true
  1776  		} else {
  1777  			for _, p := range prefixesToKeep {
  1778  				if strings.HasPrefix(f, p) {
  1779  					flags = append(flags, f)
  1780  					break
  1781  				}
  1782  			}
  1783  		}
  1784  	}
  1785  
  1786  	if altLinker != "" {
  1787  		flags = append(flags, "-fuse-ld="+altLinker)
  1788  	}
  1789  	flags = append(flags, flag, "trivial.c")
  1790  
  1791  	cmd := exec.Command(linker, flags...)
  1792  	cmd.Dir = *flagTmpdir
  1793  	cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
  1794  	out, err := cmd.CombinedOutput()
  1795  	// GCC says "unrecognized command line option ‘-no-pie’"
  1796  	// clang says "unknown argument: '-no-pie'"
  1797  	return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
  1798  }
  1799  
  1800  // hostlinkArchArgs returns arguments to pass to the external linker
  1801  // based on the architecture.
  1802  func hostlinkArchArgs(arch *sys.Arch) []string {
  1803  	switch arch.Family {
  1804  	case sys.I386:
  1805  		return []string{"-m32"}
  1806  	case sys.AMD64:
  1807  		if buildcfg.GOOS == "darwin" {
  1808  			return []string{"-arch", "x86_64", "-m64"}
  1809  		}
  1810  		return []string{"-m64"}
  1811  	case sys.S390X:
  1812  		return []string{"-m64"}
  1813  	case sys.ARM:
  1814  		return []string{"-marm"}
  1815  	case sys.ARM64:
  1816  		if buildcfg.GOOS == "darwin" {
  1817  			return []string{"-arch", "arm64"}
  1818  		}
  1819  	case sys.MIPS64:
  1820  		return []string{"-mabi=64"}
  1821  	case sys.MIPS:
  1822  		return []string{"-mabi=32"}
  1823  	case sys.PPC64:
  1824  		if buildcfg.GOOS == "aix" {
  1825  			return []string{"-maix64"}
  1826  		} else {
  1827  			return []string{"-m64"}
  1828  		}
  1829  
  1830  	}
  1831  	return nil
  1832  }
  1833  
  1834  var wantHdr = objabi.HeaderString()
  1835  
  1836  // ldobj loads an input object. If it is a host object (an object
  1837  // compiled by a non-Go compiler) it returns the Hostobj pointer. If
  1838  // it is a Go object, it returns nil.
  1839  func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
  1840  	pkg := objabi.PathToPrefix(lib.Pkg)
  1841  
  1842  	eof := f.Offset() + length
  1843  	start := f.Offset()
  1844  	c1 := bgetc(f)
  1845  	c2 := bgetc(f)
  1846  	c3 := bgetc(f)
  1847  	c4 := bgetc(f)
  1848  	f.MustSeek(start, 0)
  1849  
  1850  	unit := &sym.CompilationUnit{Lib: lib}
  1851  	lib.Units = append(lib.Units, unit)
  1852  
  1853  	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
  1854  	if magic == 0x7f454c46 { // \x7F E L F
  1855  		ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1856  			textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags)
  1857  			if err != nil {
  1858  				Errorf(nil, "%v", err)
  1859  				return
  1860  			}
  1861  			ehdr.Flags = flags
  1862  			ctxt.Textp = append(ctxt.Textp, textp...)
  1863  		}
  1864  		return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
  1865  	}
  1866  
  1867  	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
  1868  		ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1869  			textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
  1870  			if err != nil {
  1871  				Errorf(nil, "%v", err)
  1872  				return
  1873  			}
  1874  			ctxt.Textp = append(ctxt.Textp, textp...)
  1875  		}
  1876  		return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
  1877  	}
  1878  
  1879  	switch c1<<8 | c2 {
  1880  	case 0x4c01, // 386
  1881  		0x6486, // amd64
  1882  		0xc401, // arm
  1883  		0x64aa: // arm64
  1884  		ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1885  			textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
  1886  			if err != nil {
  1887  				Errorf(nil, "%v", err)
  1888  				return
  1889  			}
  1890  			if len(rsrc) != 0 {
  1891  				setpersrc(ctxt, rsrc)
  1892  			}
  1893  			ctxt.Textp = append(ctxt.Textp, textp...)
  1894  		}
  1895  		return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
  1896  	}
  1897  
  1898  	if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
  1899  		ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1900  			textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
  1901  			if err != nil {
  1902  				Errorf(nil, "%v", err)
  1903  				return
  1904  			}
  1905  			ctxt.Textp = append(ctxt.Textp, textp...)
  1906  		}
  1907  		return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
  1908  	}
  1909  
  1910  	if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' {
  1911  		// An unrecognized object is just passed to the external linker.
  1912  		// If we try to read symbols from this object, we will
  1913  		// report an error at that time.
  1914  		unknownObjFormat = true
  1915  		return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file)
  1916  	}
  1917  
  1918  	/* check the header */
  1919  	line, err := f.ReadString('\n')
  1920  	if err != nil {
  1921  		Errorf(nil, "truncated object file: %s: %v", pn, err)
  1922  		return nil
  1923  	}
  1924  
  1925  	if !strings.HasPrefix(line, "go object ") {
  1926  		if strings.HasSuffix(pn, ".go") {
  1927  			Exitf("%s: uncompiled .go source file", pn)
  1928  			return nil
  1929  		}
  1930  
  1931  		if line == ctxt.Arch.Name {
  1932  			// old header format: just $GOOS
  1933  			Errorf(nil, "%s: stale object file", pn)
  1934  			return nil
  1935  		}
  1936  
  1937  		Errorf(nil, "%s: not an object file: @%d %q", pn, start, line)
  1938  		return nil
  1939  	}
  1940  
  1941  	// First, check that the basic GOOS, GOARCH, and Version match.
  1942  	if line != wantHdr {
  1943  		Errorf(nil, "%s: linked object header mismatch:\nhave %q\nwant %q\n", pn, line, wantHdr)
  1944  	}
  1945  
  1946  	// Skip over exports and other info -- ends with \n!\n.
  1947  	//
  1948  	// Note: It's possible for "\n!\n" to appear within the binary
  1949  	// package export data format. To avoid truncating the package
  1950  	// definition prematurely (issue 21703), we keep track of
  1951  	// how many "$$" delimiters we've seen.
  1952  
  1953  	import0 := f.Offset()
  1954  
  1955  	c1 = '\n' // the last line ended in \n
  1956  	c2 = bgetc(f)
  1957  	c3 = bgetc(f)
  1958  	markers := 0
  1959  	for {
  1960  		if c1 == '\n' {
  1961  			if markers%2 == 0 && c2 == '!' && c3 == '\n' {
  1962  				break
  1963  			}
  1964  			if c2 == '$' && c3 == '$' {
  1965  				markers++
  1966  			}
  1967  		}
  1968  
  1969  		c1 = c2
  1970  		c2 = c3
  1971  		c3 = bgetc(f)
  1972  		if c3 == -1 {
  1973  			Errorf(nil, "truncated object file: %s", pn)
  1974  			return nil
  1975  		}
  1976  	}
  1977  
  1978  	import1 := f.Offset()
  1979  
  1980  	f.MustSeek(import0, 0)
  1981  	ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
  1982  	f.MustSeek(import1, 0)
  1983  
  1984  	fingerprint := ctxt.loader.Preload(ctxt.IncVersion(), f, lib, unit, eof-f.Offset())
  1985  	if !fingerprint.IsZero() { // Assembly objects don't have fingerprints. Ignore them.
  1986  		// Check fingerprint, to ensure the importing and imported packages
  1987  		// have consistent view of symbol indices.
  1988  		// Normally the go command should ensure this. But in case something
  1989  		// goes wrong, it could lead to obscure bugs like run-time crash.
  1990  		// Check it here to be sure.
  1991  		if lib.Fingerprint.IsZero() { // Not yet imported. Update its fingerprint.
  1992  			lib.Fingerprint = fingerprint
  1993  		}
  1994  		checkFingerprint(lib, fingerprint, lib.Srcref, lib.Fingerprint)
  1995  	}
  1996  
  1997  	addImports(ctxt, lib, pn)
  1998  	return nil
  1999  }
  2000  
  2001  func checkFingerprint(lib *sym.Library, libfp goobj.FingerprintType, src string, srcfp goobj.FingerprintType) {
  2002  	if libfp != srcfp {
  2003  		Exitf("fingerprint mismatch: %s has %x, import from %s expecting %x", lib, libfp, src, srcfp)
  2004  	}
  2005  }
  2006  
  2007  func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
  2008  	data := make([]byte, sym.Size)
  2009  	sect := f.Sections[sym.Section]
  2010  	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  2011  		Errorf(nil, "reading %s from non-data section", sym.Name)
  2012  	}
  2013  	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  2014  	if uint64(n) != sym.Size {
  2015  		Errorf(nil, "reading contents of %s: %v", sym.Name, err)
  2016  	}
  2017  	return data
  2018  }
  2019  
  2020  func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  2021  	data := make([]byte, Rnd(int64(sz), 4))
  2022  	_, err := io.ReadFull(r, data)
  2023  	if err != nil {
  2024  		return nil, err
  2025  	}
  2026  	data = data[:sz]
  2027  	return data, nil
  2028  }
  2029  
  2030  func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  2031  	for _, sect := range f.Sections {
  2032  		if sect.Type != elf.SHT_NOTE {
  2033  			continue
  2034  		}
  2035  		r := sect.Open()
  2036  		for {
  2037  			var namesize, descsize, noteType int32
  2038  			err := binary.Read(r, f.ByteOrder, &namesize)
  2039  			if err != nil {
  2040  				if err == io.EOF {
  2041  					break
  2042  				}
  2043  				return nil, fmt.Errorf("read namesize failed: %v", err)
  2044  			}
  2045  			err = binary.Read(r, f.ByteOrder, &descsize)
  2046  			if err != nil {
  2047  				return nil, fmt.Errorf("read descsize failed: %v", err)
  2048  			}
  2049  			err = binary.Read(r, f.ByteOrder, &noteType)
  2050  			if err != nil {
  2051  				return nil, fmt.Errorf("read type failed: %v", err)
  2052  			}
  2053  			noteName, err := readwithpad(r, namesize)
  2054  			if err != nil {
  2055  				return nil, fmt.Errorf("read name failed: %v", err)
  2056  			}
  2057  			desc, err := readwithpad(r, descsize)
  2058  			if err != nil {
  2059  				return nil, fmt.Errorf("read desc failed: %v", err)
  2060  			}
  2061  			if string(name) == string(noteName) && typ == noteType {
  2062  				return desc, nil
  2063  			}
  2064  		}
  2065  	}
  2066  	return nil, nil
  2067  }
  2068  
  2069  func findshlib(ctxt *Link, shlib string) string {
  2070  	if filepath.IsAbs(shlib) {
  2071  		return shlib
  2072  	}
  2073  	for _, libdir := range ctxt.Libdir {
  2074  		libpath := filepath.Join(libdir, shlib)
  2075  		if _, err := os.Stat(libpath); err == nil {
  2076  			return libpath
  2077  		}
  2078  	}
  2079  	Errorf(nil, "cannot find shared library: %s", shlib)
  2080  	return ""
  2081  }
  2082  
  2083  func ldshlibsyms(ctxt *Link, shlib string) {
  2084  	var libpath string
  2085  	if filepath.IsAbs(shlib) {
  2086  		libpath = shlib
  2087  		shlib = filepath.Base(shlib)
  2088  	} else {
  2089  		libpath = findshlib(ctxt, shlib)
  2090  		if libpath == "" {
  2091  			return
  2092  		}
  2093  	}
  2094  	for _, processedlib := range ctxt.Shlibs {
  2095  		if processedlib.Path == libpath {
  2096  			return
  2097  		}
  2098  	}
  2099  	if ctxt.Debugvlog > 1 {
  2100  		ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
  2101  	}
  2102  
  2103  	f, err := elf.Open(libpath)
  2104  	if err != nil {
  2105  		Errorf(nil, "cannot open shared library: %s", libpath)
  2106  		return
  2107  	}
  2108  	// Keep the file open as decodetypeGcprog needs to read from it.
  2109  	// TODO: fix. Maybe mmap the file.
  2110  	//defer f.Close()
  2111  
  2112  	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  2113  	if err != nil {
  2114  		Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
  2115  		return
  2116  	}
  2117  
  2118  	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  2119  	if err != nil {
  2120  		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
  2121  		return
  2122  	}
  2123  	var deps []string
  2124  	for _, dep := range strings.Split(string(depsbytes), "\n") {
  2125  		if dep == "" {
  2126  			continue
  2127  		}
  2128  		if !filepath.IsAbs(dep) {
  2129  			// If the dep can be interpreted as a path relative to the shlib
  2130  			// in which it was found, do that. Otherwise, we will leave it
  2131  			// to be resolved by libdir lookup.
  2132  			abs := filepath.Join(filepath.Dir(libpath), dep)
  2133  			if _, err := os.Stat(abs); err == nil {
  2134  				dep = abs
  2135  			}
  2136  		}
  2137  		deps = append(deps, dep)
  2138  	}
  2139  
  2140  	syms, err := f.DynamicSymbols()
  2141  	if err != nil {
  2142  		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
  2143  		return
  2144  	}
  2145  
  2146  	for _, elfsym := range syms {
  2147  		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  2148  			continue
  2149  		}
  2150  
  2151  		// Symbols whose names start with "type." are compiler
  2152  		// generated, so make functions with that prefix internal.
  2153  		ver := 0
  2154  		symname := elfsym.Name // (unmangled) symbol name
  2155  		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
  2156  			ver = abiInternalVer
  2157  		} else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
  2158  			// Demangle the ABI name. Keep in sync with symtab.go:mangleABIName.
  2159  			if strings.HasSuffix(elfsym.Name, ".abiinternal") {
  2160  				ver = sym.SymVerABIInternal
  2161  				symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
  2162  			} else if strings.HasSuffix(elfsym.Name, ".abi0") {
  2163  				ver = 0
  2164  				symname = strings.TrimSuffix(elfsym.Name, ".abi0")
  2165  			}
  2166  		}
  2167  
  2168  		l := ctxt.loader
  2169  		s := l.LookupOrCreateSym(symname, ver)
  2170  
  2171  		// Because loadlib above loads all .a files before loading
  2172  		// any shared libraries, any non-dynimport symbols we find
  2173  		// that duplicate symbols already loaded should be ignored
  2174  		// (the symbols from the .a files "win").
  2175  		if l.SymType(s) != 0 && l.SymType(s) != sym.SDYNIMPORT {
  2176  			continue
  2177  		}
  2178  		su := l.MakeSymbolUpdater(s)
  2179  		su.SetType(sym.SDYNIMPORT)
  2180  		l.SetSymElfType(s, elf.ST_TYPE(elfsym.Info))
  2181  		su.SetSize(int64(elfsym.Size))
  2182  		if elfsym.Section != elf.SHN_UNDEF {
  2183  			// Set .File for the library that actually defines the symbol.
  2184  			l.SetSymPkg(s, libpath)
  2185  
  2186  			// The decodetype_* functions in decodetype.go need access to
  2187  			// the type data.
  2188  			sname := l.SymName(s)
  2189  			if strings.HasPrefix(sname, "type.") && !strings.HasPrefix(sname, "type..") {
  2190  				su.SetData(readelfsymboldata(ctxt, f, &elfsym))
  2191  			}
  2192  		}
  2193  
  2194  		if symname != elfsym.Name {
  2195  			l.SetSymExtname(s, elfsym.Name)
  2196  		}
  2197  	}
  2198  	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f})
  2199  }
  2200  
  2201  func addsection(ldr *loader.Loader, arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
  2202  	sect := ldr.NewSection()
  2203  	sect.Rwx = uint8(rwx)
  2204  	sect.Name = name
  2205  	sect.Seg = seg
  2206  	sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
  2207  	seg.Sections = append(seg.Sections, sect)
  2208  	return sect
  2209  }
  2210  
  2211  type chain struct {
  2212  	sym   loader.Sym
  2213  	up    *chain
  2214  	limit int // limit on entry to sym
  2215  }
  2216  
  2217  func haslinkregister(ctxt *Link) bool {
  2218  	return ctxt.FixedFrameSize() != 0
  2219  }
  2220  
  2221  func callsize(ctxt *Link) int {
  2222  	if haslinkregister(ctxt) {
  2223  		return 0
  2224  	}
  2225  	return ctxt.Arch.RegSize
  2226  }
  2227  
  2228  type stkChk struct {
  2229  	ldr       *loader.Loader
  2230  	ctxt      *Link
  2231  	morestack loader.Sym
  2232  	done      loader.Bitmap
  2233  }
  2234  
  2235  // Walk the call tree and check that there is always enough stack space
  2236  // for the call frames, especially for a chain of nosplit functions.
  2237  func (ctxt *Link) dostkcheck() {
  2238  	ldr := ctxt.loader
  2239  	sc := stkChk{
  2240  		ldr:       ldr,
  2241  		ctxt:      ctxt,
  2242  		morestack: ldr.Lookup("runtime.morestack", 0),
  2243  		done:      loader.MakeBitmap(ldr.NSym()),
  2244  	}
  2245  
  2246  	// Every splitting function ensures that there are at least StackLimit
  2247  	// bytes available below SP when the splitting prologue finishes.
  2248  	// If the splitting function calls F, then F begins execution with
  2249  	// at least StackLimit - callsize() bytes available.
  2250  	// Check that every function behaves correctly with this amount
  2251  	// of stack, following direct calls in order to piece together chains
  2252  	// of non-splitting functions.
  2253  	var ch chain
  2254  	ch.limit = objabi.StackLimit - callsize(ctxt)
  2255  	if buildcfg.GOARCH == "arm64" {
  2256  		// need extra 8 bytes below SP to save FP
  2257  		ch.limit -= 8
  2258  	}
  2259  
  2260  	// Check every function, but do the nosplit functions in a first pass,
  2261  	// to make the printed failure chains as short as possible.
  2262  	for _, s := range ctxt.Textp {
  2263  		if ldr.IsNoSplit(s) {
  2264  			ch.sym = s
  2265  			sc.check(&ch, 0)
  2266  		}
  2267  	}
  2268  
  2269  	for _, s := range ctxt.Textp {
  2270  		if !ldr.IsNoSplit(s) {
  2271  			ch.sym = s
  2272  			sc.check(&ch, 0)
  2273  		}
  2274  	}
  2275  }
  2276  
  2277  func (sc *stkChk) check(up *chain, depth int) int {
  2278  	limit := up.limit
  2279  	s := up.sym
  2280  	ldr := sc.ldr
  2281  	ctxt := sc.ctxt
  2282  
  2283  	// Don't duplicate work: only need to consider each
  2284  	// function at top of safe zone once.
  2285  	top := limit == objabi.StackLimit-callsize(ctxt)
  2286  	if top {
  2287  		if sc.done.Has(s) {
  2288  			return 0
  2289  		}
  2290  		sc.done.Set(s)
  2291  	}
  2292  
  2293  	if depth > 500 {
  2294  		sc.ctxt.Errorf(s, "nosplit stack check too deep")
  2295  		sc.broke(up, 0)
  2296  		return -1
  2297  	}
  2298  
  2299  	if ldr.AttrExternal(s) {
  2300  		// external function.
  2301  		// should never be called directly.
  2302  		// onlyctxt.Diagnose the direct caller.
  2303  		// TODO(mwhudson): actually think about this.
  2304  		// TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack.
  2305  		// See the trampolines in src/runtime/sys_darwin_$ARCH.go.
  2306  		//if depth == 1 && ldr.SymType(s) != sym.SXREF && !ctxt.DynlinkingGo() &&
  2307  		//	ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
  2308  		//	Errorf(s, "call to external function")
  2309  		//}
  2310  		return -1
  2311  	}
  2312  	info := ldr.FuncInfo(s)
  2313  	if !info.Valid() { // external function. see above.
  2314  		return -1
  2315  	}
  2316  
  2317  	if limit < 0 {
  2318  		sc.broke(up, limit)
  2319  		return -1
  2320  	}
  2321  
  2322  	// morestack looks like it calls functions,
  2323  	// but it switches the stack pointer first.
  2324  	if s == sc.morestack {
  2325  		return 0
  2326  	}
  2327  
  2328  	var ch chain
  2329  	ch.up = up
  2330  
  2331  	if !ldr.IsNoSplit(s) {
  2332  		// Ensure we have enough stack to call morestack.
  2333  		ch.limit = limit - callsize(ctxt)
  2334  		ch.sym = sc.morestack
  2335  		if sc.check(&ch, depth+1) < 0 {
  2336  			return -1
  2337  		}
  2338  		if !top {
  2339  			return 0
  2340  		}
  2341  		// Raise limit to allow frame.
  2342  		locals := info.Locals()
  2343  		limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize())
  2344  	}
  2345  
  2346  	// Walk through sp adjustments in function, consuming relocs.
  2347  	relocs := ldr.Relocs(s)
  2348  	var ch1 chain
  2349  	pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
  2350  	ri := 0
  2351  	for pcsp.Init(ldr.Data(ldr.Pcsp(s))); !pcsp.Done; pcsp.Next() {
  2352  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  2353  
  2354  		// Check stack size in effect for this span.
  2355  		if int32(limit)-pcsp.Value < 0 {
  2356  			sc.broke(up, int(int32(limit)-pcsp.Value))
  2357  			return -1
  2358  		}
  2359  
  2360  		// Process calls in this span.
  2361  		for ; ri < relocs.Count(); ri++ {
  2362  			r := relocs.At(ri)
  2363  			if uint32(r.Off()) >= pcsp.NextPC {
  2364  				break
  2365  			}
  2366  			t := r.Type()
  2367  			switch {
  2368  			case t.IsDirectCall():
  2369  				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
  2370  				ch.sym = r.Sym()
  2371  				if sc.check(&ch, depth+1) < 0 {
  2372  					return -1
  2373  				}
  2374  
  2375  			// Indirect call. Assume it is a call to a splitting function,
  2376  			// so we have to make sure it can call morestack.
  2377  			// Arrange the data structures to report both calls, so that
  2378  			// if there is an error, stkprint shows all the steps involved.
  2379  			case t == objabi.R_CALLIND:
  2380  				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
  2381  				ch.sym = 0
  2382  				ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
  2383  				ch1.up = &ch
  2384  				ch1.sym = sc.morestack
  2385  				if sc.check(&ch1, depth+2) < 0 {
  2386  					return -1
  2387  				}
  2388  			}
  2389  		}
  2390  	}
  2391  
  2392  	return 0
  2393  }
  2394  
  2395  func (sc *stkChk) broke(ch *chain, limit int) {
  2396  	sc.ctxt.Errorf(ch.sym, "nosplit stack overflow")
  2397  	sc.print(ch, limit)
  2398  }
  2399  
  2400  func (sc *stkChk) print(ch *chain, limit int) {
  2401  	ldr := sc.ldr
  2402  	ctxt := sc.ctxt
  2403  	var name string
  2404  	if ch.sym != 0 {
  2405  		name = fmt.Sprintf("%s<%d>", ldr.SymName(ch.sym), ldr.SymVersion(ch.sym))
  2406  		if ldr.IsNoSplit(ch.sym) {
  2407  			name += " (nosplit)"
  2408  		}
  2409  	} else {
  2410  		name = "function pointer"
  2411  	}
  2412  
  2413  	if ch.up == nil {
  2414  		// top of chain. ch.sym != 0.
  2415  		if ldr.IsNoSplit(ch.sym) {
  2416  			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  2417  		} else {
  2418  			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  2419  		}
  2420  	} else {
  2421  		sc.print(ch.up, ch.limit+callsize(ctxt))
  2422  		if !haslinkregister(ctxt) {
  2423  			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  2424  		}
  2425  	}
  2426  
  2427  	if ch.limit != limit {
  2428  		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  2429  	}
  2430  }
  2431  
  2432  func usage() {
  2433  	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  2434  	objabi.Flagprint(os.Stderr)
  2435  	Exit(2)
  2436  }
  2437  
  2438  type SymbolType int8 // TODO: after genasmsym is gone, maybe rename to plan9typeChar or something
  2439  
  2440  const (
  2441  	// see also https://9p.io/magic/man2html/1/nm
  2442  	TextSym      SymbolType = 'T'
  2443  	DataSym      SymbolType = 'D'
  2444  	BSSSym       SymbolType = 'B'
  2445  	UndefinedSym SymbolType = 'U'
  2446  	TLSSym       SymbolType = 't'
  2447  	FrameSym     SymbolType = 'm'
  2448  	ParamSym     SymbolType = 'p'
  2449  	AutoSym      SymbolType = 'a'
  2450  
  2451  	// Deleted auto (not a real sym, just placeholder for type)
  2452  	DeletedAutoSym = 'x'
  2453  )
  2454  
  2455  // defineInternal defines a symbol used internally by the go runtime.
  2456  func (ctxt *Link) defineInternal(p string, t sym.SymKind) loader.Sym {
  2457  	s := ctxt.loader.CreateSymForUpdate(p, 0)
  2458  	s.SetType(t)
  2459  	s.SetSpecial(true)
  2460  	s.SetLocal(true)
  2461  	return s.Sym()
  2462  }
  2463  
  2464  func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) loader.Sym {
  2465  	s := ctxt.defineInternal(p, t)
  2466  	ctxt.loader.SetSymValue(s, v)
  2467  	return s
  2468  }
  2469  
  2470  func datoff(ldr *loader.Loader, s loader.Sym, addr int64) int64 {
  2471  	if uint64(addr) >= Segdata.Vaddr {
  2472  		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2473  	}
  2474  	if uint64(addr) >= Segtext.Vaddr {
  2475  		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2476  	}
  2477  	ldr.Errorf(s, "invalid datoff %#x", addr)
  2478  	return 0
  2479  }
  2480  
  2481  func Entryvalue(ctxt *Link) int64 {
  2482  	a := *flagEntrySymbol
  2483  	if a[0] >= '0' && a[0] <= '9' {
  2484  		return atolwhex(a)
  2485  	}
  2486  	ldr := ctxt.loader
  2487  	s := ldr.Lookup(a, 0)
  2488  	st := ldr.SymType(s)
  2489  	if st == 0 {
  2490  		return *FlagTextAddr
  2491  	}
  2492  	if !ctxt.IsAIX() && st != sym.STEXT {
  2493  		ldr.Errorf(s, "entry not text")
  2494  	}
  2495  	return ldr.SymValue(s)
  2496  }
  2497  
  2498  func (ctxt *Link) callgraph() {
  2499  	if !*FlagC {
  2500  		return
  2501  	}
  2502  
  2503  	ldr := ctxt.loader
  2504  	for _, s := range ctxt.Textp {
  2505  		relocs := ldr.Relocs(s)
  2506  		for i := 0; i < relocs.Count(); i++ {
  2507  			r := relocs.At(i)
  2508  			rs := r.Sym()
  2509  			if rs == 0 {
  2510  				continue
  2511  			}
  2512  			if r.Type().IsDirectCall() && ldr.SymType(rs) == sym.STEXT {
  2513  				ctxt.Logf("%s calls %s\n", ldr.SymName(s), ldr.SymName(rs))
  2514  			}
  2515  		}
  2516  	}
  2517  }
  2518  
  2519  func Rnd(v int64, r int64) int64 {
  2520  	if r <= 0 {
  2521  		return v
  2522  	}
  2523  	v += r - 1
  2524  	c := v % r
  2525  	if c < 0 {
  2526  		c += r
  2527  	}
  2528  	v -= c
  2529  	return v
  2530  }
  2531  
  2532  func bgetc(r *bio.Reader) int {
  2533  	c, err := r.ReadByte()
  2534  	if err != nil {
  2535  		if err != io.EOF {
  2536  			log.Fatalf("reading input: %v", err)
  2537  		}
  2538  		return -1
  2539  	}
  2540  	return int(c)
  2541  }
  2542  
  2543  type markKind uint8 // for postorder traversal
  2544  const (
  2545  	_ markKind = iota
  2546  	visiting
  2547  	visited
  2548  )
  2549  
  2550  func postorder(libs []*sym.Library) []*sym.Library {
  2551  	order := make([]*sym.Library, 0, len(libs)) // hold the result
  2552  	mark := make(map[*sym.Library]markKind, len(libs))
  2553  	for _, lib := range libs {
  2554  		dfs(lib, mark, &order)
  2555  	}
  2556  	return order
  2557  }
  2558  
  2559  func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
  2560  	if mark[lib] == visited {
  2561  		return
  2562  	}
  2563  	if mark[lib] == visiting {
  2564  		panic("found import cycle while visiting " + lib.Pkg)
  2565  	}
  2566  	mark[lib] = visiting
  2567  	for _, i := range lib.Imports {
  2568  		dfs(i, mark, order)
  2569  	}
  2570  	mark[lib] = visited
  2571  	*order = append(*order, lib)
  2572  }
  2573  
  2574  func ElfSymForReloc(ctxt *Link, s loader.Sym) int32 {
  2575  	// If putelfsym created a local version of this symbol, use that in all
  2576  	// relocations.
  2577  	les := ctxt.loader.SymLocalElfSym(s)
  2578  	if les != 0 {
  2579  		return les
  2580  	} else {
  2581  		return ctxt.loader.SymElfSym(s)
  2582  	}
  2583  }
  2584  
  2585  func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, elfRelocTyp uint32) {
  2586  	if ldr.SymGot(s) >= 0 {
  2587  		return
  2588  	}
  2589  
  2590  	Adddynsym(ldr, target, syms, s)
  2591  	got := ldr.MakeSymbolUpdater(syms.GOT)
  2592  	ldr.SetGot(s, int32(got.Size()))
  2593  	got.AddUint(target.Arch, 0)
  2594  
  2595  	if target.IsElf() {
  2596  		if target.Arch.PtrSize == 8 {
  2597  			rela := ldr.MakeSymbolUpdater(syms.Rela)
  2598  			rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
  2599  			rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
  2600  			rela.AddUint64(target.Arch, 0)
  2601  		} else {
  2602  			rel := ldr.MakeSymbolUpdater(syms.Rel)
  2603  			rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
  2604  			rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp))
  2605  		}
  2606  	} else if target.IsDarwin() {
  2607  		leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
  2608  		leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
  2609  		if target.IsPIE() && target.IsInternal() {
  2610  			// Mach-O relocations are a royal pain to lay out.
  2611  			// They use a compact stateful bytecode representation.
  2612  			// Here we record what are needed and encode them later.
  2613  			MachoAddBind(int64(ldr.SymGot(s)), s)
  2614  		}
  2615  	} else {
  2616  		ldr.Errorf(s, "addgotsym: unsupported binary format")
  2617  	}
  2618  }
  2619  

View as plain text