Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: cmd/link/internal/ld

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

View as plain text