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

View as plain text