github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/cmd/link/internal/ld/lib.go (about)

     1  // Inferno utils/8l/asm.c
     2  // https://bitbucket.org/inferno-os/inferno-os/src/default/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  	"bufio"
    35  	"bytes"
    36  	"cmd/internal/bio"
    37  	"cmd/internal/objabi"
    38  	"cmd/internal/sys"
    39  	"crypto/sha1"
    40  	"debug/elf"
    41  	"encoding/binary"
    42  	"encoding/hex"
    43  	"fmt"
    44  	"io"
    45  	"io/ioutil"
    46  	"log"
    47  	"os"
    48  	"os/exec"
    49  	"path/filepath"
    50  	"runtime"
    51  	"strings"
    52  	"sync"
    53  )
    54  
    55  // Data layout and relocation.
    56  
    57  // Derived from Inferno utils/6l/l.h
    58  // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
    59  //
    60  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
    61  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
    62  //	Portions Copyright © 1997-1999 Vita Nuova Limited
    63  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
    64  //	Portions Copyright © 2004,2006 Bruce Ellis
    65  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    66  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    67  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    68  //
    69  // Permission is hereby granted, free of charge, to any person obtaining a copy
    70  // of this software and associated documentation files (the "Software"), to deal
    71  // in the Software without restriction, including without limitation the rights
    72  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    73  // copies of the Software, and to permit persons to whom the Software is
    74  // furnished to do so, subject to the following conditions:
    75  //
    76  // The above copyright notice and this permission notice shall be included in
    77  // all copies or substantial portions of the Software.
    78  //
    79  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    80  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    81  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    82  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    83  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    84  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    85  // THE SOFTWARE.
    86  
    87  type Arch struct {
    88  	Funcalign        int
    89  	Maxalign         int
    90  	Minalign         int
    91  	Dwarfregsp       int
    92  	Dwarfreglr       int
    93  	Linuxdynld       string
    94  	Freebsddynld     string
    95  	Netbsddynld      string
    96  	Openbsddynld     string
    97  	Dragonflydynld   string
    98  	Solarisdynld     string
    99  	Adddynrel        func(*Link, *Symbol, *Reloc) bool
   100  	Archinit         func(*Link)
   101  	Archreloc        func(*Link, *Reloc, *Symbol, *int64) int
   102  	Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64
   103  	Trampoline       func(*Link, *Reloc, *Symbol)
   104  	Asmb             func(*Link)
   105  	Elfreloc1        func(*Link, *Reloc, int64) int
   106  	Elfsetupplt      func(*Link)
   107  	Gentext          func(*Link)
   108  	Machoreloc1      func(*Symbol, *Reloc, int64) int
   109  	PEreloc1         func(*Symbol, *Reloc, int64) bool
   110  	Wput             func(uint16)
   111  	Lput             func(uint32)
   112  	Vput             func(uint64)
   113  	Append16         func(b []byte, v uint16) []byte
   114  	Append32         func(b []byte, v uint32) []byte
   115  	Append64         func(b []byte, v uint64) []byte
   116  
   117  	// TLSIEtoLE converts a TLS Initial Executable relocation to
   118  	// a TLS Local Executable relocation.
   119  	//
   120  	// This is possible when a TLS IE relocation refers to a local
   121  	// symbol in an executable, which is typical when internally
   122  	// linking PIE binaries.
   123  	TLSIEtoLE func(s *Symbol, off, size int)
   124  }
   125  
   126  var (
   127  	Thearch Arch
   128  	Lcsize  int32
   129  	rpath   Rpath
   130  	Spsize  int32
   131  	Symsize int32
   132  )
   133  
   134  // Terrible but standard terminology.
   135  // A segment describes a block of file to load into memory.
   136  // A section further describes the pieces of that block for
   137  // use in debuggers and such.
   138  
   139  const (
   140  	MINFUNC = 16 // minimum size for a function
   141  )
   142  
   143  type Segment struct {
   144  	Rwx      uint8  // permission as usual unix bits (5 = r-x etc)
   145  	Vaddr    uint64 // virtual address
   146  	Length   uint64 // length in memory
   147  	Fileoff  uint64 // file offset
   148  	Filelen  uint64 // length on disk
   149  	Sections []*Section
   150  }
   151  
   152  type Section struct {
   153  	Rwx     uint8
   154  	Extnum  int16
   155  	Align   int32
   156  	Name    string
   157  	Vaddr   uint64
   158  	Length  uint64
   159  	Seg     *Segment
   160  	Elfsect *ElfShdr
   161  	Reloff  uint64
   162  	Rellen  uint64
   163  }
   164  
   165  // DynlinkingGo returns whether we are producing Go code that can live
   166  // in separate shared libraries linked together at runtime.
   167  func (ctxt *Link) DynlinkingGo() bool {
   168  	if !ctxt.Loaded {
   169  		panic("DynlinkingGo called before all symbols loaded")
   170  	}
   171  	canUsePlugins := ctxt.Syms.ROLookup("plugin.Open", 0) != nil
   172  	return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || canUsePlugins
   173  }
   174  
   175  // UseRelro returns whether to make use of "read only relocations" aka
   176  // relro.
   177  func UseRelro() bool {
   178  	switch Buildmode {
   179  	case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePIE, BuildmodePlugin:
   180  		return Iself
   181  	default:
   182  		return *FlagLinkshared
   183  	}
   184  }
   185  
   186  var (
   187  	SysArch         *sys.Arch
   188  	dynexp          []*Symbol
   189  	dynlib          []string
   190  	ldflag          []string
   191  	havedynamic     int
   192  	Funcalign       int
   193  	iscgo           bool
   194  	elfglobalsymndx int
   195  	interpreter     string
   196  
   197  	debug_s  bool // backup old value of debug['s']
   198  	HEADR    int32
   199  	Headtype objabi.HeadType
   200  
   201  	nerrors  int
   202  	liveness int64
   203  )
   204  
   205  var (
   206  	Segtext      Segment
   207  	Segrodata    Segment
   208  	Segrelrodata Segment
   209  	Segdata      Segment
   210  	Segdwarf     Segment
   211  )
   212  
   213  /* whence for ldpkg */
   214  const (
   215  	FileObj = 0 + iota
   216  	ArchiveObj
   217  	Pkgdef
   218  )
   219  
   220  // TODO(dfc) outBuf duplicates bio.Writer
   221  type outBuf struct {
   222  	w   *bufio.Writer
   223  	f   *os.File
   224  	off int64
   225  }
   226  
   227  func (w *outBuf) Write(p []byte) (n int, err error) {
   228  	n, err = w.w.Write(p)
   229  	w.off += int64(n)
   230  	return n, err
   231  }
   232  
   233  func (w *outBuf) WriteString(s string) (n int, err error) {
   234  	n, err = coutbuf.w.WriteString(s)
   235  	w.off += int64(n)
   236  	return n, err
   237  }
   238  
   239  func (w *outBuf) Offset() int64 {
   240  	return w.off
   241  }
   242  
   243  var coutbuf outBuf
   244  
   245  const pkgname = "__.PKGDEF"
   246  
   247  var (
   248  	// Set if we see an object compiled by the host compiler that is not
   249  	// from a package that is known to support internal linking mode.
   250  	externalobj = false
   251  	theline     string
   252  )
   253  
   254  func Lflag(ctxt *Link, arg string) {
   255  	ctxt.Libdir = append(ctxt.Libdir, arg)
   256  }
   257  
   258  /*
   259   * Unix doesn't like it when we write to a running (or, sometimes,
   260   * recently run) binary, so remove the output file before writing it.
   261   * On Windows 7, remove() can force a subsequent create() to fail.
   262   * S_ISREG() does not exist on Plan 9.
   263   */
   264  func mayberemoveoutfile() {
   265  	if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
   266  		return
   267  	}
   268  	os.Remove(*flagOutfile)
   269  }
   270  
   271  func libinit(ctxt *Link) {
   272  	Funcalign = Thearch.Funcalign
   273  
   274  	// add goroot to the end of the libdir list.
   275  	suffix := ""
   276  
   277  	suffixsep := ""
   278  	if *flagInstallSuffix != "" {
   279  		suffixsep = "_"
   280  		suffix = *flagInstallSuffix
   281  	} else if *flagRace {
   282  		suffixsep = "_"
   283  		suffix = "race"
   284  	} else if *flagMsan {
   285  		suffixsep = "_"
   286  		suffix = "msan"
   287  	}
   288  
   289  	Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
   290  
   291  	mayberemoveoutfile()
   292  	f, err := os.OpenFile(*flagOutfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
   293  	if err != nil {
   294  		Exitf("cannot create %s: %v", *flagOutfile, err)
   295  	}
   296  
   297  	coutbuf.w = bufio.NewWriter(f)
   298  	coutbuf.f = f
   299  
   300  	if *flagEntrySymbol == "" {
   301  		switch Buildmode {
   302  		case BuildmodeCShared, BuildmodeCArchive:
   303  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
   304  		case BuildmodeExe, BuildmodePIE:
   305  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
   306  		case BuildmodeShared, BuildmodePlugin:
   307  			// No *flagEntrySymbol for -buildmode=shared and plugin
   308  		default:
   309  			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", Buildmode)
   310  		}
   311  	}
   312  }
   313  
   314  func errorexit() {
   315  	if coutbuf.f != nil {
   316  		if nerrors != 0 {
   317  			Cflush()
   318  		}
   319  		// For rmtemp run at atexit time on Windows.
   320  		if err := coutbuf.f.Close(); err != nil {
   321  			Exitf("close: %v", err)
   322  		}
   323  	}
   324  
   325  	if nerrors != 0 {
   326  		if coutbuf.f != nil {
   327  			mayberemoveoutfile()
   328  		}
   329  		Exit(2)
   330  	}
   331  
   332  	Exit(0)
   333  }
   334  
   335  func loadinternal(ctxt *Link, name string) *Library {
   336  	for i := 0; i < len(ctxt.Libdir); i++ {
   337  		if *FlagLinkshared {
   338  			shlibname := filepath.Join(ctxt.Libdir[i], name+".shlibname")
   339  			if ctxt.Debugvlog != 0 {
   340  				ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
   341  			}
   342  			if _, err := os.Stat(shlibname); err == nil {
   343  				return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
   344  			}
   345  		}
   346  		pname := filepath.Join(ctxt.Libdir[i], name+".a")
   347  		if ctxt.Debugvlog != 0 {
   348  			ctxt.Logf("searching for %s.a in %s\n", name, pname)
   349  		}
   350  		if _, err := os.Stat(pname); err == nil {
   351  			return addlibpath(ctxt, "internal", "internal", pname, name, "")
   352  		}
   353  	}
   354  
   355  	ctxt.Logf("warning: unable to find %s.a\n", name)
   356  	return nil
   357  }
   358  
   359  // findLibPathCmd uses cmd command to find gcc library libname.
   360  // It returns library full path if found, or "none" if not found.
   361  func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
   362  	if *flagExtld == "" {
   363  		*flagExtld = "gcc"
   364  	}
   365  	args := hostlinkArchArgs()
   366  	args = append(args, cmd)
   367  	if ctxt.Debugvlog != 0 {
   368  		ctxt.Logf("%s %v\n", *flagExtld, args)
   369  	}
   370  	out, err := exec.Command(*flagExtld, args...).Output()
   371  	if err != nil {
   372  		if ctxt.Debugvlog != 0 {
   373  			ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
   374  		}
   375  		return "none"
   376  	}
   377  	return strings.TrimSpace(string(out))
   378  }
   379  
   380  // findLibPath searches for library libname.
   381  // It returns library full path if found, or "none" if not found.
   382  func (ctxt *Link) findLibPath(libname string) string {
   383  	return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
   384  }
   385  
   386  func (ctxt *Link) loadlib() {
   387  	switch Buildmode {
   388  	case BuildmodeCShared, BuildmodePlugin:
   389  		s := ctxt.Syms.Lookup("runtime.islibrary", 0)
   390  		s.Attr |= AttrDuplicateOK
   391  		Adduint8(ctxt, s, 1)
   392  	case BuildmodeCArchive:
   393  		s := ctxt.Syms.Lookup("runtime.isarchive", 0)
   394  		s.Attr |= AttrDuplicateOK
   395  		Adduint8(ctxt, s, 1)
   396  	}
   397  
   398  	loadinternal(ctxt, "runtime")
   399  	if SysArch.Family == sys.ARM {
   400  		loadinternal(ctxt, "math")
   401  	}
   402  	if *flagRace {
   403  		loadinternal(ctxt, "runtime/race")
   404  	}
   405  	if *flagMsan {
   406  		loadinternal(ctxt, "runtime/msan")
   407  	}
   408  
   409  	var i int
   410  	for i = 0; i < len(ctxt.Library); i++ {
   411  		iscgo = iscgo || ctxt.Library[i].Pkg == "runtime/cgo"
   412  		if ctxt.Library[i].Shlib == "" {
   413  			if ctxt.Debugvlog > 1 {
   414  				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].File, ctxt.Library[i].Objref)
   415  			}
   416  			objfile(ctxt, ctxt.Library[i])
   417  		}
   418  	}
   419  
   420  	for i = 0; i < len(ctxt.Library); i++ {
   421  		if ctxt.Library[i].Shlib != "" {
   422  			if ctxt.Debugvlog > 1 {
   423  				ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].Shlib, ctxt.Library[i].Objref)
   424  			}
   425  			ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
   426  		}
   427  	}
   428  
   429  	// We now have enough information to determine the link mode.
   430  	determineLinkMode(ctxt)
   431  
   432  	// Recalculate pe parameters now that we have Linkmode set.
   433  	if Headtype == objabi.Hwindows {
   434  		Peinit(ctxt)
   435  	}
   436  
   437  	if Headtype == objabi.Hdarwin && Linkmode == LinkExternal {
   438  		*FlagTextAddr = 0
   439  	}
   440  
   441  	if Linkmode == LinkExternal && SysArch.Family == sys.PPC64 {
   442  		toc := ctxt.Syms.Lookup(".TOC.", 0)
   443  		toc.Type = SDYNIMPORT
   444  	}
   445  
   446  	if Linkmode == LinkExternal && !iscgo {
   447  		// This indicates a user requested -linkmode=external.
   448  		// The startup code uses an import of runtime/cgo to decide
   449  		// whether to initialize the TLS.  So give it one. This could
   450  		// be handled differently but it's an unusual case.
   451  		loadinternal(ctxt, "runtime/cgo")
   452  
   453  		if i < len(ctxt.Library) {
   454  			if ctxt.Library[i].Shlib != "" {
   455  				ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
   456  			} else {
   457  				if Buildmode == BuildmodeShared || *FlagLinkshared {
   458  					Exitf("cannot implicitly include runtime/cgo in a shared library")
   459  				}
   460  				objfile(ctxt, ctxt.Library[i])
   461  			}
   462  		}
   463  	}
   464  
   465  	if Linkmode == LinkInternal {
   466  		// Drop all the cgo_import_static declarations.
   467  		// Turns out we won't be needing them.
   468  		for _, s := range ctxt.Syms.Allsym {
   469  			if s.Type == SHOSTOBJ {
   470  				// If a symbol was marked both
   471  				// cgo_import_static and cgo_import_dynamic,
   472  				// then we want to make it cgo_import_dynamic
   473  				// now.
   474  				if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
   475  					s.Type = SDYNIMPORT
   476  				} else {
   477  					s.Type = 0
   478  				}
   479  			}
   480  		}
   481  	}
   482  
   483  	tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0)
   484  
   485  	// runtime.tlsg is used for external linking on platforms that do not define
   486  	// a variable to hold g in assembly (currently only intel).
   487  	if tlsg.Type == 0 {
   488  		tlsg.Type = STLSBSS
   489  		tlsg.Size = int64(SysArch.PtrSize)
   490  	} else if tlsg.Type != SDYNIMPORT {
   491  		Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
   492  	}
   493  	tlsg.Attr |= AttrReachable
   494  	ctxt.Tlsg = tlsg
   495  
   496  	var moduledata *Symbol
   497  	if Buildmode == BuildmodePlugin {
   498  		moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
   499  		moduledata.Attr |= AttrLocal
   500  	} else {
   501  		moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
   502  	}
   503  	if moduledata.Type != 0 && moduledata.Type != SDYNIMPORT {
   504  		// If the module (toolchain-speak for "executable or shared
   505  		// library") we are linking contains the runtime package, it
   506  		// will define the runtime.firstmoduledata symbol and we
   507  		// truncate it back to 0 bytes so we can define its entire
   508  		// contents in symtab.go:symtab().
   509  		moduledata.Size = 0
   510  
   511  		// In addition, on ARM, the runtime depends on the linker
   512  		// recording the value of GOARM.
   513  		if SysArch.Family == sys.ARM {
   514  			s := ctxt.Syms.Lookup("runtime.goarm", 0)
   515  			s.Type = SRODATA
   516  			s.Size = 0
   517  			Adduint8(ctxt, s, uint8(objabi.GOARM))
   518  		}
   519  
   520  		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
   521  			s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
   522  			s.Type = SRODATA
   523  			s.Size = 0
   524  			Adduint8(ctxt, s, 1)
   525  		}
   526  	} else {
   527  		// If OTOH the module does not contain the runtime package,
   528  		// create a local symbol for the moduledata.
   529  		moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
   530  		moduledata.Attr |= AttrLocal
   531  	}
   532  	// In all cases way we mark the moduledata as noptrdata to hide it from
   533  	// the GC.
   534  	moduledata.Type = SNOPTRDATA
   535  	moduledata.Attr |= AttrReachable
   536  	ctxt.Moduledata = moduledata
   537  
   538  	// Now that we know the link mode, trim the dynexp list.
   539  	x := AttrCgoExportDynamic
   540  
   541  	if Linkmode == LinkExternal {
   542  		x = AttrCgoExportStatic
   543  	}
   544  	w := 0
   545  	for i := 0; i < len(dynexp); i++ {
   546  		if dynexp[i].Attr&x != 0 {
   547  			dynexp[w] = dynexp[i]
   548  			w++
   549  		}
   550  	}
   551  	dynexp = dynexp[:w]
   552  
   553  	// In internal link mode, read the host object files.
   554  	if Linkmode == LinkInternal {
   555  		hostobjs(ctxt)
   556  
   557  		// If we have any undefined symbols in external
   558  		// objects, try to read them from the libgcc file.
   559  		any := false
   560  		for _, s := range ctxt.Syms.Allsym {
   561  			for _, r := range s.R {
   562  				if r.Sym != nil && r.Sym.Type&SMASK == SXREF && r.Sym.Name != ".got" {
   563  					any = true
   564  					break
   565  				}
   566  			}
   567  		}
   568  		if any {
   569  			if *flagLibGCC == "" {
   570  				*flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
   571  			}
   572  			if *flagLibGCC != "none" {
   573  				hostArchive(ctxt, *flagLibGCC)
   574  			}
   575  			if Headtype == objabi.Hwindows {
   576  				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
   577  					hostArchive(ctxt, p)
   578  				}
   579  				if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
   580  					hostArchive(ctxt, p)
   581  				}
   582  				// TODO: maybe do something similar to peimporteddlls to collect all lib names
   583  				// and try link them all to final exe just like libmingwex.a and libmingw32.a:
   584  				/*
   585  					for:
   586  					#cgo windows LDFLAGS: -lmsvcrt -lm
   587  					import:
   588  					libmsvcrt.a libm.a
   589  				*/
   590  			}
   591  		}
   592  	} else {
   593  		hostlinksetup()
   594  	}
   595  
   596  	// We've loaded all the code now.
   597  	ctxt.Loaded = true
   598  
   599  	// If there are no dynamic libraries needed, gcc disables dynamic linking.
   600  	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   601  	// assumes that a dynamic binary always refers to at least one dynamic library.
   602  	// Rather than be a source of test cases for glibc, disable dynamic linking
   603  	// the same way that gcc would.
   604  	//
   605  	// Exception: on OS X, programs such as Shark only work with dynamic
   606  	// binaries, so leave it enabled on OS X (Mach-O) binaries.
   607  	// Also leave it enabled on Solaris which doesn't support
   608  	// statically linked binaries.
   609  	if Buildmode == BuildmodeExe {
   610  		if havedynamic == 0 && Headtype != objabi.Hdarwin && Headtype != objabi.Hsolaris {
   611  			*FlagD = true
   612  		}
   613  	}
   614  
   615  	// If package versioning is required, generate a hash of the
   616  	// the packages used in the link.
   617  	if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
   618  		for i = 0; i < len(ctxt.Library); i++ {
   619  			if ctxt.Library[i].Shlib == "" {
   620  				genhash(ctxt, ctxt.Library[i])
   621  			}
   622  		}
   623  	}
   624  
   625  	if SysArch == sys.Arch386 {
   626  		if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
   627  			got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
   628  			got.Type = SDYNIMPORT
   629  			got.Attr |= AttrReachable
   630  		}
   631  	}
   632  
   633  	importcycles()
   634  
   635  	// put symbols into Textp
   636  	// do it in postorder so that packages are laid down in dependency order
   637  	// internal first, then everything else
   638  	ctxt.Library = postorder(ctxt.Library)
   639  	for _, doInternal := range [2]bool{true, false} {
   640  		for _, lib := range ctxt.Library {
   641  			if isRuntimeDepPkg(lib.Pkg) != doInternal {
   642  				continue
   643  			}
   644  			ctxt.Textp = append(ctxt.Textp, lib.textp...)
   645  			for _, s := range lib.dupTextSyms {
   646  				if !s.Attr.OnList() {
   647  					ctxt.Textp = append(ctxt.Textp, s)
   648  					s.Attr |= AttrOnList
   649  					// dupok symbols may be defined in multiple packages. its
   650  					// associated package is chosen sort of arbitrarily (the
   651  					// first containing package that the linker loads). canonicalize
   652  					// it here to the package with which it will be laid down
   653  					// in text.
   654  					s.File = objabi.PathToPrefix(lib.Pkg)
   655  				}
   656  			}
   657  		}
   658  	}
   659  
   660  	if len(ctxt.Shlibs) > 0 {
   661  		// We might have overwritten some functions above (this tends to happen for the
   662  		// autogenerated type equality/hashing functions) and we don't want to generated
   663  		// pcln table entries for these any more so remove them from Textp.
   664  		textp := make([]*Symbol, 0, len(ctxt.Textp))
   665  		for _, s := range ctxt.Textp {
   666  			if s.Type != SDYNIMPORT {
   667  				textp = append(textp, s)
   668  			}
   669  		}
   670  		ctxt.Textp = textp
   671  	}
   672  }
   673  
   674  /*
   675   * look for the next file in an archive.
   676   * adapted from libmach.
   677   */
   678  func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
   679  	if off&1 != 0 {
   680  		off++
   681  	}
   682  	bp.Seek(off, 0)
   683  	var buf [SAR_HDR]byte
   684  	if n, err := io.ReadFull(bp, buf[:]); err != nil {
   685  		if n == 0 && err != io.EOF {
   686  			return -1
   687  		}
   688  		return 0
   689  	}
   690  
   691  	a.name = artrim(buf[0:16])
   692  	a.date = artrim(buf[16:28])
   693  	a.uid = artrim(buf[28:34])
   694  	a.gid = artrim(buf[34:40])
   695  	a.mode = artrim(buf[40:48])
   696  	a.size = artrim(buf[48:58])
   697  	a.fmag = artrim(buf[58:60])
   698  
   699  	arsize := atolwhex(a.size)
   700  	if arsize&1 != 0 {
   701  		arsize++
   702  	}
   703  	return arsize + SAR_HDR
   704  }
   705  
   706  func genhash(ctxt *Link, lib *Library) {
   707  	f, err := bio.Open(lib.File)
   708  	if err != nil {
   709  		Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
   710  		return
   711  	}
   712  	defer f.Close()
   713  
   714  	var arhdr ArHdr
   715  	l := nextar(f, int64(len(ARMAG)), &arhdr)
   716  	if l <= 0 {
   717  		Errorf(nil, "%s: short read on archive file symbol header", lib.File)
   718  		return
   719  	}
   720  
   721  	h := sha1.New()
   722  
   723  	// To compute the hash of a package, we hash the first line of
   724  	// __.PKGDEF (which contains the toolchain version and any
   725  	// GOEXPERIMENT flags) and the export data (which is between
   726  	// the first two occurences of "\n$$").
   727  
   728  	pkgDefBytes := make([]byte, atolwhex(arhdr.size))
   729  	_, err = io.ReadFull(f, pkgDefBytes)
   730  	if err != nil {
   731  		Errorf(nil, "%s: error reading package data: %v", lib.File, err)
   732  		return
   733  	}
   734  	firstEOL := bytes.Index(pkgDefBytes, []byte("\n"))
   735  	if firstEOL < 0 {
   736  		Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
   737  		return
   738  	}
   739  	firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$"))
   740  	if firstDoubleDollar < 0 {
   741  		Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File)
   742  		return
   743  	}
   744  	secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$"))
   745  	if secondDoubleDollar < 0 {
   746  		Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File)
   747  		return
   748  	}
   749  	h.Write(pkgDefBytes[0:firstEOL])
   750  	h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
   751  	lib.hash = hex.EncodeToString(h.Sum(nil))
   752  }
   753  
   754  func objfile(ctxt *Link, lib *Library) {
   755  	pkg := objabi.PathToPrefix(lib.Pkg)
   756  
   757  	if ctxt.Debugvlog > 1 {
   758  		ctxt.Logf("%5.2f ldobj: %s (%s)\n", Cputime(), lib.File, pkg)
   759  	}
   760  	f, err := bio.Open(lib.File)
   761  	if err != nil {
   762  		Exitf("cannot open file %s: %v", lib.File, err)
   763  	}
   764  
   765  	for i := 0; i < len(ARMAG); i++ {
   766  		if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
   767  			continue
   768  		}
   769  
   770  		/* load it as a regular file */
   771  		l := f.Seek(0, 2)
   772  
   773  		f.Seek(0, 0)
   774  		ldobj(ctxt, f, lib, l, lib.File, lib.File, FileObj)
   775  		f.Close()
   776  
   777  		return
   778  	}
   779  
   780  	/* process __.PKGDEF */
   781  	off := f.Offset()
   782  
   783  	var arhdr ArHdr
   784  	l := nextar(f, off, &arhdr)
   785  	var pname string
   786  	if l <= 0 {
   787  		Errorf(nil, "%s: short read on archive file symbol header", lib.File)
   788  		goto out
   789  	}
   790  
   791  	if !strings.HasPrefix(arhdr.name, pkgname) {
   792  		Errorf(nil, "%s: cannot find package header", lib.File)
   793  		goto out
   794  	}
   795  
   796  	off += l
   797  
   798  	ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
   799  
   800  	/*
   801  	 * load all the object files from the archive now.
   802  	 * this gives us sequential file access and keeps us
   803  	 * from needing to come back later to pick up more
   804  	 * objects.  it breaks the usual C archive model, but
   805  	 * this is Go, not C.  the common case in Go is that
   806  	 * we need to load all the objects, and then we throw away
   807  	 * the individual symbols that are unused.
   808  	 *
   809  	 * loading every object will also make it possible to
   810  	 * load foreign objects not referenced by __.PKGDEF.
   811  	 */
   812  	for {
   813  		l = nextar(f, off, &arhdr)
   814  		if l == 0 {
   815  			break
   816  		}
   817  		if l < 0 {
   818  			Exitf("%s: malformed archive", lib.File)
   819  		}
   820  
   821  		off += l
   822  
   823  		pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
   824  		l = atolwhex(arhdr.size)
   825  		ldobj(ctxt, f, lib, l, pname, lib.File, ArchiveObj)
   826  	}
   827  
   828  out:
   829  	f.Close()
   830  }
   831  
   832  type Hostobj struct {
   833  	ld     func(*Link, *bio.Reader, string, int64, string)
   834  	pkg    string
   835  	pn     string
   836  	file   string
   837  	off    int64
   838  	length int64
   839  }
   840  
   841  var hostobj []Hostobj
   842  
   843  // These packages can use internal linking mode.
   844  // Others trigger external mode.
   845  var internalpkg = []string{
   846  	"crypto/x509",
   847  	"net",
   848  	"os/user",
   849  	"runtime/cgo",
   850  	"runtime/race",
   851  	"runtime/msan",
   852  }
   853  
   854  func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
   855  	isinternal := false
   856  	for i := 0; i < len(internalpkg); i++ {
   857  		if pkg == internalpkg[i] {
   858  			isinternal = true
   859  			break
   860  		}
   861  	}
   862  
   863  	// DragonFly declares errno with __thread, which results in a symbol
   864  	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
   865  	// currently know how to handle TLS relocations, hence we have to
   866  	// force external linking for any libraries that link in code that
   867  	// uses errno. This can be removed if the Go linker ever supports
   868  	// these relocation types.
   869  	if Headtype == objabi.Hdragonfly {
   870  		if pkg == "net" || pkg == "os/user" {
   871  			isinternal = false
   872  		}
   873  	}
   874  
   875  	if !isinternal {
   876  		externalobj = true
   877  	}
   878  
   879  	hostobj = append(hostobj, Hostobj{})
   880  	h := &hostobj[len(hostobj)-1]
   881  	h.ld = ld
   882  	h.pkg = pkg
   883  	h.pn = pn
   884  	h.file = file
   885  	h.off = f.Offset()
   886  	h.length = length
   887  	return h
   888  }
   889  
   890  func hostobjs(ctxt *Link) {
   891  	var h *Hostobj
   892  
   893  	for i := 0; i < len(hostobj); i++ {
   894  		h = &hostobj[i]
   895  		f, err := bio.Open(h.file)
   896  		if err != nil {
   897  			Exitf("cannot reopen %s: %v", h.pn, err)
   898  		}
   899  
   900  		f.Seek(h.off, 0)
   901  		h.ld(ctxt, f, h.pkg, h.length, h.pn)
   902  		f.Close()
   903  	}
   904  }
   905  
   906  // provided by lib9
   907  
   908  func rmtemp() {
   909  	os.RemoveAll(*flagTmpdir)
   910  }
   911  
   912  func hostlinksetup() {
   913  	if Linkmode != LinkExternal {
   914  		return
   915  	}
   916  
   917  	// For external link, record that we need to tell the external linker -s,
   918  	// and turn off -s internally: the external linker needs the symbol
   919  	// information for its final link.
   920  	debug_s = *FlagS
   921  	*FlagS = false
   922  
   923  	// create temporary directory and arrange cleanup
   924  	if *flagTmpdir == "" {
   925  		dir, err := ioutil.TempDir("", "go-link-")
   926  		if err != nil {
   927  			log.Fatal(err)
   928  		}
   929  		*flagTmpdir = dir
   930  		AtExit(rmtemp)
   931  	}
   932  
   933  	// change our output to temporary object file
   934  	coutbuf.f.Close()
   935  	mayberemoveoutfile()
   936  
   937  	p := filepath.Join(*flagTmpdir, "go.o")
   938  	var err error
   939  	f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
   940  	if err != nil {
   941  		Exitf("cannot create %s: %v", p, err)
   942  	}
   943  
   944  	coutbuf.w = bufio.NewWriter(f)
   945  	coutbuf.f = f
   946  }
   947  
   948  // hostobjCopy creates a copy of the object files in hostobj in a
   949  // temporary directory.
   950  func hostobjCopy() (paths []string) {
   951  	var wg sync.WaitGroup
   952  	sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
   953  	for i, h := range hostobj {
   954  		h := h
   955  		dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
   956  		paths = append(paths, dst)
   957  
   958  		wg.Add(1)
   959  		go func() {
   960  			sema <- struct{}{}
   961  			defer func() {
   962  				<-sema
   963  				wg.Done()
   964  			}()
   965  			f, err := os.Open(h.file)
   966  			if err != nil {
   967  				Exitf("cannot reopen %s: %v", h.pn, err)
   968  			}
   969  			if _, err := f.Seek(h.off, 0); err != nil {
   970  				Exitf("cannot seek %s: %v", h.pn, err)
   971  			}
   972  
   973  			w, err := os.Create(dst)
   974  			if err != nil {
   975  				Exitf("cannot create %s: %v", dst, err)
   976  			}
   977  			if _, err := io.CopyN(w, f, h.length); err != nil {
   978  				Exitf("cannot write %s: %v", dst, err)
   979  			}
   980  			if err := w.Close(); err != nil {
   981  				Exitf("cannot close %s: %v", dst, err)
   982  			}
   983  		}()
   984  	}
   985  	wg.Wait()
   986  	return paths
   987  }
   988  
   989  // archive builds a .a archive from the hostobj object files.
   990  func (ctxt *Link) archive() {
   991  	if Buildmode != BuildmodeCArchive {
   992  		return
   993  	}
   994  
   995  	if *flagExtar == "" {
   996  		*flagExtar = "ar"
   997  	}
   998  
   999  	mayberemoveoutfile()
  1000  
  1001  	// Force the buffer to flush here so that external
  1002  	// tools will see a complete file.
  1003  	Cflush()
  1004  	if err := coutbuf.f.Close(); err != nil {
  1005  		Exitf("close: %v", err)
  1006  	}
  1007  	coutbuf.f = nil
  1008  
  1009  	argv := []string{*flagExtar, "-q", "-c", "-s", *flagOutfile}
  1010  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1011  	argv = append(argv, hostobjCopy()...)
  1012  
  1013  	if ctxt.Debugvlog != 0 {
  1014  		ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
  1015  	}
  1016  
  1017  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1018  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1019  	}
  1020  }
  1021  
  1022  func (l *Link) hostlink() {
  1023  	if Linkmode != LinkExternal || nerrors > 0 {
  1024  		return
  1025  	}
  1026  	if Buildmode == BuildmodeCArchive {
  1027  		return
  1028  	}
  1029  
  1030  	if *flagExtld == "" {
  1031  		*flagExtld = "gcc"
  1032  	}
  1033  
  1034  	var argv []string
  1035  	argv = append(argv, *flagExtld)
  1036  	argv = append(argv, hostlinkArchArgs()...)
  1037  
  1038  	if !*FlagS && !debug_s {
  1039  		argv = append(argv, "-gdwarf-2")
  1040  	} else if Headtype == objabi.Hdarwin {
  1041  		// Recent versions of macOS print
  1042  		//	ld: warning: option -s is obsolete and being ignored
  1043  		// so do not pass any arguments.
  1044  	} else {
  1045  		argv = append(argv, "-s")
  1046  	}
  1047  
  1048  	switch Headtype {
  1049  	case objabi.Hdarwin:
  1050  		argv = append(argv, "-Wl,-headerpad,1144")
  1051  		if l.DynlinkingGo() {
  1052  			argv = append(argv, "-Wl,-flat_namespace")
  1053  		} else {
  1054  			argv = append(argv, "-Wl,-no_pie")
  1055  		}
  1056  	case objabi.Hopenbsd:
  1057  		argv = append(argv, "-Wl,-nopie")
  1058  	case objabi.Hwindows:
  1059  		if windowsgui {
  1060  			argv = append(argv, "-mwindows")
  1061  		} else {
  1062  			argv = append(argv, "-mconsole")
  1063  		}
  1064  	}
  1065  
  1066  	switch Buildmode {
  1067  	case BuildmodeExe:
  1068  		if Headtype == objabi.Hdarwin {
  1069  			argv = append(argv, "-Wl,-pagezero_size,4000000")
  1070  		}
  1071  	case BuildmodePIE:
  1072  		if UseRelro() {
  1073  			argv = append(argv, "-Wl,-z,relro")
  1074  		}
  1075  		argv = append(argv, "-pie")
  1076  	case BuildmodeCShared:
  1077  		if Headtype == objabi.Hdarwin {
  1078  			argv = append(argv, "-dynamiclib", "-Wl,-read_only_relocs,suppress")
  1079  		} else {
  1080  			// ELF.
  1081  			argv = append(argv, "-Wl,-Bsymbolic")
  1082  			if UseRelro() {
  1083  				argv = append(argv, "-Wl,-z,relro")
  1084  			}
  1085  			// Pass -z nodelete to mark the shared library as
  1086  			// non-closeable: a dlclose will do nothing.
  1087  			argv = append(argv, "-shared", "-Wl,-z,nodelete")
  1088  		}
  1089  	case BuildmodeShared:
  1090  		if UseRelro() {
  1091  			argv = append(argv, "-Wl,-z,relro")
  1092  		}
  1093  		argv = append(argv, "-shared")
  1094  	case BuildmodePlugin:
  1095  		if Headtype == objabi.Hdarwin {
  1096  			argv = append(argv, "-dynamiclib")
  1097  		} else {
  1098  			if UseRelro() {
  1099  				argv = append(argv, "-Wl,-z,relro")
  1100  			}
  1101  			argv = append(argv, "-shared")
  1102  		}
  1103  	}
  1104  
  1105  	if Iself && l.DynlinkingGo() {
  1106  		// We force all symbol resolution to be done at program startup
  1107  		// because lazy PLT resolution can use large amounts of stack at
  1108  		// times we cannot allow it to do so.
  1109  		argv = append(argv, "-Wl,-znow")
  1110  
  1111  		// Do not let the host linker generate COPY relocations. These
  1112  		// can move symbols out of sections that rely on stable offsets
  1113  		// from the beginning of the section (like STYPE).
  1114  		argv = append(argv, "-Wl,-znocopyreloc")
  1115  
  1116  		if SysArch.InFamily(sys.ARM, sys.ARM64) {
  1117  			// On ARM, the GNU linker will generate COPY relocations
  1118  			// even with -znocopyreloc set.
  1119  			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
  1120  			//
  1121  			// On ARM64, the GNU linker will fail instead of
  1122  			// generating COPY relocations.
  1123  			//
  1124  			// In both cases, switch to gold.
  1125  			argv = append(argv, "-fuse-ld=gold")
  1126  
  1127  			// If gold is not installed, gcc will silently switch
  1128  			// back to ld.bfd. So we parse the version information
  1129  			// and provide a useful error if gold is missing.
  1130  			cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version")
  1131  			if out, err := cmd.CombinedOutput(); err == nil {
  1132  				if !bytes.Contains(out, []byte("GNU gold")) {
  1133  					log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
  1134  				}
  1135  			}
  1136  		}
  1137  	}
  1138  
  1139  	if Iself && len(buildinfo) > 0 {
  1140  		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
  1141  	}
  1142  
  1143  	// On Windows, given -o foo, GCC will append ".exe" to produce
  1144  	// "foo.exe".  We have decided that we want to honor the -o
  1145  	// option. To make this work, we append a '.' so that GCC
  1146  	// will decide that the file already has an extension. We
  1147  	// only want to do this when producing a Windows output file
  1148  	// on a Windows host.
  1149  	outopt := *flagOutfile
  1150  	if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
  1151  		outopt += "."
  1152  	}
  1153  	argv = append(argv, "-o")
  1154  	argv = append(argv, outopt)
  1155  
  1156  	if rpath.val != "" {
  1157  		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
  1158  	}
  1159  
  1160  	// Force global symbols to be exported for dlopen, etc.
  1161  	if Iself {
  1162  		argv = append(argv, "-rdynamic")
  1163  	}
  1164  
  1165  	if strings.Contains(argv[0], "clang") {
  1166  		argv = append(argv, "-Qunused-arguments")
  1167  	}
  1168  
  1169  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1170  	argv = append(argv, hostobjCopy()...)
  1171  
  1172  	if *FlagLinkshared {
  1173  		seenDirs := make(map[string]bool)
  1174  		seenLibs := make(map[string]bool)
  1175  		addshlib := func(path string) {
  1176  			dir, base := filepath.Split(path)
  1177  			if !seenDirs[dir] {
  1178  				argv = append(argv, "-L"+dir)
  1179  				if !rpath.set {
  1180  					argv = append(argv, "-Wl,-rpath="+dir)
  1181  				}
  1182  				seenDirs[dir] = true
  1183  			}
  1184  			base = strings.TrimSuffix(base, ".so")
  1185  			base = strings.TrimPrefix(base, "lib")
  1186  			if !seenLibs[base] {
  1187  				argv = append(argv, "-l"+base)
  1188  				seenLibs[base] = true
  1189  			}
  1190  		}
  1191  		for _, shlib := range l.Shlibs {
  1192  			addshlib(shlib.Path)
  1193  			for _, dep := range shlib.Deps {
  1194  				if dep == "" {
  1195  					continue
  1196  				}
  1197  				libpath := findshlib(l, dep)
  1198  				if libpath != "" {
  1199  					addshlib(libpath)
  1200  				}
  1201  			}
  1202  		}
  1203  	}
  1204  
  1205  	argv = append(argv, ldflag...)
  1206  
  1207  	// When building a program with the default -buildmode=exe the
  1208  	// gc compiler generates code requires DT_TEXTREL in a
  1209  	// position independent executable (PIE). On systems where the
  1210  	// toolchain creates PIEs by default, and where DT_TEXTREL
  1211  	// does not work, the resulting programs will not run. See
  1212  	// issue #17847. To avoid this problem pass -no-pie to the
  1213  	// toolchain if it is supported.
  1214  	if Buildmode == BuildmodeExe {
  1215  		src := filepath.Join(*flagTmpdir, "trivial.c")
  1216  		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
  1217  			Errorf(nil, "WriteFile trivial.c failed: %v", err)
  1218  		}
  1219  		cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c")
  1220  		cmd.Dir = *flagTmpdir
  1221  		cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
  1222  		out, err := cmd.CombinedOutput()
  1223  		supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
  1224  		if supported {
  1225  			argv = append(argv, "-no-pie")
  1226  		}
  1227  	}
  1228  
  1229  	for _, p := range strings.Fields(*flagExtldflags) {
  1230  		argv = append(argv, p)
  1231  
  1232  		// clang, unlike GCC, passes -rdynamic to the linker
  1233  		// even when linking with -static, causing a linker
  1234  		// error when using GNU ld. So take out -rdynamic if
  1235  		// we added it. We do it in this order, rather than
  1236  		// only adding -rdynamic later, so that -*extldflags
  1237  		// can override -rdynamic without using -static.
  1238  		if Iself && p == "-static" {
  1239  			for i := range argv {
  1240  				if argv[i] == "-rdynamic" {
  1241  					argv[i] = "-static"
  1242  				}
  1243  			}
  1244  		}
  1245  	}
  1246  	if Headtype == objabi.Hwindows {
  1247  		// libmingw32 and libmingwex have some inter-dependencies,
  1248  		// so must use linker groups.
  1249  		argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
  1250  		argv = append(argv, peimporteddlls()...)
  1251  	}
  1252  
  1253  	if l.Debugvlog != 0 {
  1254  		l.Logf("%5.2f host link:", Cputime())
  1255  		for _, v := range argv {
  1256  			l.Logf(" %q", v)
  1257  		}
  1258  		l.Logf("\n")
  1259  	}
  1260  
  1261  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1262  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1263  	} else if l.Debugvlog != 0 && len(out) > 0 {
  1264  		l.Logf("%s", out)
  1265  	}
  1266  
  1267  	if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin {
  1268  		// Skip combining dwarf on arm.
  1269  		if !SysArch.InFamily(sys.ARM, sys.ARM64) {
  1270  			dsym := filepath.Join(*flagTmpdir, "go.dwarf")
  1271  			if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
  1272  				Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
  1273  			}
  1274  			// Skip combining if `dsymutil` didn't generate a file. See #11994.
  1275  			if _, err := os.Stat(dsym); os.IsNotExist(err) {
  1276  				return
  1277  			}
  1278  			// For os.Rename to work reliably, must be in same directory as outfile.
  1279  			combinedOutput := *flagOutfile + "~"
  1280  			if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil {
  1281  				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1282  			}
  1283  			os.Remove(*flagOutfile)
  1284  			if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
  1285  				Exitf("%s: %v", os.Args[0], err)
  1286  			}
  1287  		}
  1288  	}
  1289  }
  1290  
  1291  // hostlinkArchArgs returns arguments to pass to the external linker
  1292  // based on the architecture.
  1293  func hostlinkArchArgs() []string {
  1294  	switch SysArch.Family {
  1295  	case sys.I386:
  1296  		return []string{"-m32"}
  1297  	case sys.AMD64, sys.PPC64, sys.S390X:
  1298  		return []string{"-m64"}
  1299  	case sys.ARM:
  1300  		return []string{"-marm"}
  1301  	case sys.ARM64:
  1302  		// nothing needed
  1303  	case sys.MIPS64:
  1304  		return []string{"-mabi=64"}
  1305  	case sys.MIPS:
  1306  		return []string{"-mabi=32"}
  1307  	}
  1308  	return nil
  1309  }
  1310  
  1311  // ldobj loads an input object. If it is a host object (an object
  1312  // compiled by a non-Go compiler) it returns the Hostobj pointer. If
  1313  // it is a Go object, it returns nil.
  1314  func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj {
  1315  	pkg := objabi.PathToPrefix(lib.Pkg)
  1316  
  1317  	eof := f.Offset() + length
  1318  	start := f.Offset()
  1319  	c1 := bgetc(f)
  1320  	c2 := bgetc(f)
  1321  	c3 := bgetc(f)
  1322  	c4 := bgetc(f)
  1323  	f.Seek(start, 0)
  1324  
  1325  	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
  1326  	if magic == 0x7f454c46 { // \x7F E L F
  1327  		return ldhostobj(ldelf, f, pkg, length, pn, file)
  1328  	}
  1329  
  1330  	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
  1331  		return ldhostobj(ldmacho, f, pkg, length, pn, file)
  1332  	}
  1333  
  1334  	if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
  1335  		return ldhostobj(ldpe, f, pkg, length, pn, file)
  1336  	}
  1337  
  1338  	/* check the header */
  1339  	line, err := f.ReadString('\n')
  1340  	if err != nil {
  1341  		Errorf(nil, "truncated object file: %s: %v", pn, err)
  1342  		return nil
  1343  	}
  1344  
  1345  	if !strings.HasPrefix(line, "go object ") {
  1346  		if strings.HasSuffix(pn, ".go") {
  1347  			Exitf("%s: uncompiled .go source file", pn)
  1348  			return nil
  1349  		}
  1350  
  1351  		if line == SysArch.Name {
  1352  			// old header format: just $GOOS
  1353  			Errorf(nil, "%s: stale object file", pn)
  1354  			return nil
  1355  		}
  1356  
  1357  		Errorf(nil, "%s: not an object file", pn)
  1358  		return nil
  1359  	}
  1360  
  1361  	// First, check that the basic GOOS, GOARCH, and Version match.
  1362  	t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
  1363  
  1364  	line = strings.TrimRight(line, "\n")
  1365  	if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
  1366  		Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
  1367  		return nil
  1368  	}
  1369  
  1370  	// Second, check that longer lines match each other exactly,
  1371  	// so that the Go compiler and write additional information
  1372  	// that must be the same from run to run.
  1373  	if len(line) >= len(t)+10 {
  1374  		if theline == "" {
  1375  			theline = line[10:]
  1376  		} else if theline != line[10:] {
  1377  			Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
  1378  			return nil
  1379  		}
  1380  	}
  1381  
  1382  	/* skip over exports and other info -- ends with \n!\n */
  1383  	import0 := f.Offset()
  1384  
  1385  	c1 = '\n' // the last line ended in \n
  1386  	c2 = bgetc(f)
  1387  	c3 = bgetc(f)
  1388  	for c1 != '\n' || c2 != '!' || c3 != '\n' {
  1389  		c1 = c2
  1390  		c2 = c3
  1391  		c3 = bgetc(f)
  1392  		if c3 == -1 {
  1393  			Errorf(nil, "truncated object file: %s", pn)
  1394  			return nil
  1395  		}
  1396  	}
  1397  
  1398  	import1 := f.Offset()
  1399  
  1400  	f.Seek(import0, 0)
  1401  	ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n
  1402  	f.Seek(import1, 0)
  1403  
  1404  	LoadObjFile(ctxt, f, lib, eof-f.Offset(), pn)
  1405  	return nil
  1406  }
  1407  
  1408  func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
  1409  	data := make([]byte, sym.Size)
  1410  	sect := f.Sections[sym.Section]
  1411  	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  1412  		Errorf(nil, "reading %s from non-data section", sym.Name)
  1413  	}
  1414  	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  1415  	if uint64(n) != sym.Size {
  1416  		Errorf(nil, "reading contents of %s: %v", sym.Name, err)
  1417  	}
  1418  	return data
  1419  }
  1420  
  1421  func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  1422  	data := make([]byte, Rnd(int64(sz), 4))
  1423  	_, err := io.ReadFull(r, data)
  1424  	if err != nil {
  1425  		return nil, err
  1426  	}
  1427  	data = data[:sz]
  1428  	return data, nil
  1429  }
  1430  
  1431  func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  1432  	for _, sect := range f.Sections {
  1433  		if sect.Type != elf.SHT_NOTE {
  1434  			continue
  1435  		}
  1436  		r := sect.Open()
  1437  		for {
  1438  			var namesize, descsize, noteType int32
  1439  			err := binary.Read(r, f.ByteOrder, &namesize)
  1440  			if err != nil {
  1441  				if err == io.EOF {
  1442  					break
  1443  				}
  1444  				return nil, fmt.Errorf("read namesize failed: %v", err)
  1445  			}
  1446  			err = binary.Read(r, f.ByteOrder, &descsize)
  1447  			if err != nil {
  1448  				return nil, fmt.Errorf("read descsize failed: %v", err)
  1449  			}
  1450  			err = binary.Read(r, f.ByteOrder, &noteType)
  1451  			if err != nil {
  1452  				return nil, fmt.Errorf("read type failed: %v", err)
  1453  			}
  1454  			noteName, err := readwithpad(r, namesize)
  1455  			if err != nil {
  1456  				return nil, fmt.Errorf("read name failed: %v", err)
  1457  			}
  1458  			desc, err := readwithpad(r, descsize)
  1459  			if err != nil {
  1460  				return nil, fmt.Errorf("read desc failed: %v", err)
  1461  			}
  1462  			if string(name) == string(noteName) && typ == noteType {
  1463  				return desc, nil
  1464  			}
  1465  		}
  1466  	}
  1467  	return nil, nil
  1468  }
  1469  
  1470  func findshlib(ctxt *Link, shlib string) string {
  1471  	for _, libdir := range ctxt.Libdir {
  1472  		libpath := filepath.Join(libdir, shlib)
  1473  		if _, err := os.Stat(libpath); err == nil {
  1474  			return libpath
  1475  		}
  1476  	}
  1477  	Errorf(nil, "cannot find shared library: %s", shlib)
  1478  	return ""
  1479  }
  1480  
  1481  func ldshlibsyms(ctxt *Link, shlib string) {
  1482  	libpath := findshlib(ctxt, shlib)
  1483  	if libpath == "" {
  1484  		return
  1485  	}
  1486  	for _, processedlib := range ctxt.Shlibs {
  1487  		if processedlib.Path == libpath {
  1488  			return
  1489  		}
  1490  	}
  1491  	if ctxt.Debugvlog > 1 {
  1492  		ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath)
  1493  	}
  1494  
  1495  	f, err := elf.Open(libpath)
  1496  	if err != nil {
  1497  		Errorf(nil, "cannot open shared library: %s", libpath)
  1498  		return
  1499  	}
  1500  
  1501  	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  1502  	if err != nil {
  1503  		Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
  1504  		return
  1505  	}
  1506  
  1507  	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  1508  	if err != nil {
  1509  		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
  1510  		return
  1511  	}
  1512  	deps := strings.Split(string(depsbytes), "\n")
  1513  
  1514  	syms, err := f.DynamicSymbols()
  1515  	if err != nil {
  1516  		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
  1517  		return
  1518  	}
  1519  	gcdataLocations := make(map[uint64]*Symbol)
  1520  	for _, elfsym := range syms {
  1521  		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  1522  			continue
  1523  		}
  1524  		lsym := ctxt.Syms.Lookup(elfsym.Name, 0)
  1525  		// Because loadlib above loads all .a files before loading any shared
  1526  		// libraries, any non-dynimport symbols we find that duplicate symbols
  1527  		// already loaded should be ignored (the symbols from the .a files
  1528  		// "win").
  1529  		if lsym.Type != 0 && lsym.Type != SDYNIMPORT {
  1530  			continue
  1531  		}
  1532  		lsym.Type = SDYNIMPORT
  1533  		lsym.ElfType = elf.ST_TYPE(elfsym.Info)
  1534  		lsym.Size = int64(elfsym.Size)
  1535  		if elfsym.Section != elf.SHN_UNDEF {
  1536  			// Set .File for the library that actually defines the symbol.
  1537  			lsym.File = libpath
  1538  			// The decodetype_* functions in decodetype.go need access to
  1539  			// the type data.
  1540  			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
  1541  				lsym.P = readelfsymboldata(ctxt, f, &elfsym)
  1542  				gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
  1543  			}
  1544  		}
  1545  	}
  1546  	gcdataAddresses := make(map[*Symbol]uint64)
  1547  	if SysArch.Family == sys.ARM64 {
  1548  		for _, sect := range f.Sections {
  1549  			if sect.Type == elf.SHT_RELA {
  1550  				var rela elf.Rela64
  1551  				rdr := sect.Open()
  1552  				for {
  1553  					err := binary.Read(rdr, f.ByteOrder, &rela)
  1554  					if err == io.EOF {
  1555  						break
  1556  					} else if err != nil {
  1557  						Errorf(nil, "reading relocation failed %v", err)
  1558  						return
  1559  					}
  1560  					t := elf.R_AARCH64(rela.Info & 0xffff)
  1561  					if t != elf.R_AARCH64_RELATIVE {
  1562  						continue
  1563  					}
  1564  					if lsym, ok := gcdataLocations[rela.Off]; ok {
  1565  						gcdataAddresses[lsym] = uint64(rela.Addend)
  1566  					}
  1567  				}
  1568  			}
  1569  		}
  1570  	}
  1571  
  1572  	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
  1573  }
  1574  
  1575  func addsection(seg *Segment, name string, rwx int) *Section {
  1576  	sect := new(Section)
  1577  	sect.Rwx = uint8(rwx)
  1578  	sect.Name = name
  1579  	sect.Seg = seg
  1580  	sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
  1581  	seg.Sections = append(seg.Sections, sect)
  1582  	return sect
  1583  }
  1584  
  1585  func Le16(b []byte) uint16 {
  1586  	return uint16(b[0]) | uint16(b[1])<<8
  1587  }
  1588  
  1589  func Le32(b []byte) uint32 {
  1590  	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  1591  }
  1592  
  1593  func Le64(b []byte) uint64 {
  1594  	return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32
  1595  }
  1596  
  1597  func Be16(b []byte) uint16 {
  1598  	return uint16(b[0])<<8 | uint16(b[1])
  1599  }
  1600  
  1601  func Be32(b []byte) uint32 {
  1602  	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  1603  }
  1604  
  1605  type chain struct {
  1606  	sym   *Symbol
  1607  	up    *chain
  1608  	limit int // limit on entry to sym
  1609  }
  1610  
  1611  var morestack *Symbol
  1612  
  1613  // TODO: Record enough information in new object files to
  1614  // allow stack checks here.
  1615  
  1616  func haslinkregister(ctxt *Link) bool {
  1617  	return ctxt.FixedFrameSize() != 0
  1618  }
  1619  
  1620  func callsize(ctxt *Link) int {
  1621  	if haslinkregister(ctxt) {
  1622  		return 0
  1623  	}
  1624  	return SysArch.RegSize
  1625  }
  1626  
  1627  func (ctxt *Link) dostkcheck() {
  1628  	var ch chain
  1629  
  1630  	morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
  1631  
  1632  	// Every splitting function ensures that there are at least StackLimit
  1633  	// bytes available below SP when the splitting prologue finishes.
  1634  	// If the splitting function calls F, then F begins execution with
  1635  	// at least StackLimit - callsize() bytes available.
  1636  	// Check that every function behaves correctly with this amount
  1637  	// of stack, following direct calls in order to piece together chains
  1638  	// of non-splitting functions.
  1639  	ch.up = nil
  1640  
  1641  	ch.limit = objabi.StackLimit - callsize(ctxt)
  1642  
  1643  	// Check every function, but do the nosplit functions in a first pass,
  1644  	// to make the printed failure chains as short as possible.
  1645  	for _, s := range ctxt.Textp {
  1646  		// runtime.racesymbolizethunk is called from gcc-compiled C
  1647  		// code running on the operating system thread stack.
  1648  		// It uses more than the usual amount of stack but that's okay.
  1649  		if s.Name == "runtime.racesymbolizethunk" {
  1650  			continue
  1651  		}
  1652  
  1653  		if s.Attr.NoSplit() {
  1654  			ch.sym = s
  1655  			stkcheck(ctxt, &ch, 0)
  1656  		}
  1657  	}
  1658  
  1659  	for _, s := range ctxt.Textp {
  1660  		if !s.Attr.NoSplit() {
  1661  			ch.sym = s
  1662  			stkcheck(ctxt, &ch, 0)
  1663  		}
  1664  	}
  1665  }
  1666  
  1667  func stkcheck(ctxt *Link, up *chain, depth int) int {
  1668  	limit := up.limit
  1669  	s := up.sym
  1670  
  1671  	// Don't duplicate work: only need to consider each
  1672  	// function at top of safe zone once.
  1673  	top := limit == objabi.StackLimit-callsize(ctxt)
  1674  	if top {
  1675  		if s.Attr.StackCheck() {
  1676  			return 0
  1677  		}
  1678  		s.Attr |= AttrStackCheck
  1679  	}
  1680  
  1681  	if depth > 100 {
  1682  		Errorf(s, "nosplit stack check too deep")
  1683  		stkbroke(ctxt, up, 0)
  1684  		return -1
  1685  	}
  1686  
  1687  	if s.Attr.External() || s.FuncInfo == nil {
  1688  		// external function.
  1689  		// should never be called directly.
  1690  		// onlyctxt.Diagnose the direct caller.
  1691  		// TODO(mwhudson): actually think about this.
  1692  		if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() &&
  1693  			Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
  1694  
  1695  			Errorf(s, "call to external function")
  1696  		}
  1697  		return -1
  1698  	}
  1699  
  1700  	if limit < 0 {
  1701  		stkbroke(ctxt, up, limit)
  1702  		return -1
  1703  	}
  1704  
  1705  	// morestack looks like it calls functions,
  1706  	// but it switches the stack pointer first.
  1707  	if s == morestack {
  1708  		return 0
  1709  	}
  1710  
  1711  	var ch chain
  1712  	ch.up = up
  1713  
  1714  	if !s.Attr.NoSplit() {
  1715  		// Ensure we have enough stack to call morestack.
  1716  		ch.limit = limit - callsize(ctxt)
  1717  		ch.sym = morestack
  1718  		if stkcheck(ctxt, &ch, depth+1) < 0 {
  1719  			return -1
  1720  		}
  1721  		if !top {
  1722  			return 0
  1723  		}
  1724  		// Raise limit to allow frame.
  1725  		locals := int32(0)
  1726  		if s.FuncInfo != nil {
  1727  			locals = s.FuncInfo.Locals
  1728  		}
  1729  		limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize())
  1730  	}
  1731  
  1732  	// Walk through sp adjustments in function, consuming relocs.
  1733  	ri := 0
  1734  
  1735  	endr := len(s.R)
  1736  	var ch1 chain
  1737  	var pcsp Pciter
  1738  	var r *Reloc
  1739  	for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1740  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  1741  
  1742  		// Check stack size in effect for this span.
  1743  		if int32(limit)-pcsp.value < 0 {
  1744  			stkbroke(ctxt, up, int(int32(limit)-pcsp.value))
  1745  			return -1
  1746  		}
  1747  
  1748  		// Process calls in this span.
  1749  		for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
  1750  			r = &s.R[ri]
  1751  			switch r.Type {
  1752  			// Direct call.
  1753  			case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS:
  1754  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  1755  				ch.sym = r.Sym
  1756  				if stkcheck(ctxt, &ch, depth+1) < 0 {
  1757  					return -1
  1758  				}
  1759  
  1760  			// Indirect call. Assume it is a call to a splitting function,
  1761  			// so we have to make sure it can call morestack.
  1762  			// Arrange the data structures to report both calls, so that
  1763  			// if there is an error, stkprint shows all the steps involved.
  1764  			case objabi.R_CALLIND:
  1765  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  1766  
  1767  				ch.sym = nil
  1768  				ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
  1769  				ch1.up = &ch
  1770  				ch1.sym = morestack
  1771  				if stkcheck(ctxt, &ch1, depth+2) < 0 {
  1772  					return -1
  1773  				}
  1774  			}
  1775  		}
  1776  	}
  1777  
  1778  	return 0
  1779  }
  1780  
  1781  func stkbroke(ctxt *Link, ch *chain, limit int) {
  1782  	Errorf(ch.sym, "nosplit stack overflow")
  1783  	stkprint(ctxt, ch, limit)
  1784  }
  1785  
  1786  func stkprint(ctxt *Link, ch *chain, limit int) {
  1787  	var name string
  1788  
  1789  	if ch.sym != nil {
  1790  		name = ch.sym.Name
  1791  		if ch.sym.Attr.NoSplit() {
  1792  			name += " (nosplit)"
  1793  		}
  1794  	} else {
  1795  		name = "function pointer"
  1796  	}
  1797  
  1798  	if ch.up == nil {
  1799  		// top of chain.  ch->sym != nil.
  1800  		if ch.sym.Attr.NoSplit() {
  1801  			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  1802  		} else {
  1803  			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  1804  		}
  1805  	} else {
  1806  		stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
  1807  		if !haslinkregister(ctxt) {
  1808  			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  1809  		}
  1810  	}
  1811  
  1812  	if ch.limit != limit {
  1813  		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  1814  	}
  1815  }
  1816  
  1817  func Cflush() {
  1818  	if err := coutbuf.w.Flush(); err != nil {
  1819  		Exitf("flushing %s: %v", coutbuf.f.Name(), err)
  1820  	}
  1821  }
  1822  
  1823  func Cseek(p int64) {
  1824  	if p == coutbuf.off {
  1825  		return
  1826  	}
  1827  	Cflush()
  1828  	if _, err := coutbuf.f.Seek(p, 0); err != nil {
  1829  		Exitf("seeking in output [0, 1]: %v", err)
  1830  	}
  1831  	coutbuf.off = p
  1832  }
  1833  
  1834  func Cwritestring(s string) {
  1835  	coutbuf.WriteString(s)
  1836  }
  1837  
  1838  func Cwrite(p []byte) {
  1839  	coutbuf.Write(p)
  1840  }
  1841  
  1842  func Cput(c uint8) {
  1843  	coutbuf.w.WriteByte(c)
  1844  	coutbuf.off++
  1845  }
  1846  
  1847  func usage() {
  1848  	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  1849  	objabi.Flagprint(2)
  1850  	Exit(2)
  1851  }
  1852  
  1853  func doversion() {
  1854  	Exitf("version %s", objabi.Version)
  1855  }
  1856  
  1857  type SymbolType int8
  1858  
  1859  const (
  1860  	TextSym      SymbolType = 'T'
  1861  	DataSym                 = 'D'
  1862  	BSSSym                  = 'B'
  1863  	UndefinedSym            = 'U'
  1864  	TLSSym                  = 't'
  1865  	FileSym                 = 'f'
  1866  	FrameSym                = 'm'
  1867  	ParamSym                = 'p'
  1868  	AutoSym                 = 'a'
  1869  )
  1870  
  1871  func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) {
  1872  	// These symbols won't show up in the first loop below because we
  1873  	// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
  1874  	s := ctxt.Syms.Lookup("runtime.text", 0)
  1875  	if s.Type == STEXT {
  1876  		put(ctxt, s, s.Name, TextSym, s.Value, nil)
  1877  	}
  1878  
  1879  	n := 0
  1880  
  1881  	// Generate base addresses for all text sections if there are multiple
  1882  	for _, sect := range Segtext.Sections {
  1883  		if n == 0 {
  1884  			n++
  1885  			continue
  1886  		}
  1887  		if sect.Name != ".text" {
  1888  			break
  1889  		}
  1890  		s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
  1891  		if s == nil {
  1892  			break
  1893  		}
  1894  		if s.Type == STEXT {
  1895  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  1896  		}
  1897  		n++
  1898  	}
  1899  
  1900  	s = ctxt.Syms.Lookup("runtime.etext", 0)
  1901  	if s.Type == STEXT {
  1902  		put(ctxt, s, s.Name, TextSym, s.Value, nil)
  1903  	}
  1904  
  1905  	for _, s := range ctxt.Syms.Allsym {
  1906  		if s.Attr.Hidden() {
  1907  			continue
  1908  		}
  1909  		if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
  1910  			continue
  1911  		}
  1912  		switch s.Type & SMASK {
  1913  		case SCONST,
  1914  			SRODATA,
  1915  			SSYMTAB,
  1916  			SPCLNTAB,
  1917  			SINITARR,
  1918  			SDATA,
  1919  			SNOPTRDATA,
  1920  			SELFROSECT,
  1921  			SMACHOGOT,
  1922  			STYPE,
  1923  			SSTRING,
  1924  			SGOSTRING,
  1925  			SGOFUNC,
  1926  			SGCBITS,
  1927  			STYPERELRO,
  1928  			SSTRINGRELRO,
  1929  			SGOSTRINGRELRO,
  1930  			SGOFUNCRELRO,
  1931  			SGCBITSRELRO,
  1932  			SRODATARELRO,
  1933  			STYPELINK,
  1934  			SITABLINK,
  1935  			SWINDOWS:
  1936  			if !s.Attr.Reachable() {
  1937  				continue
  1938  			}
  1939  			put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
  1940  
  1941  		case SBSS, SNOPTRBSS:
  1942  			if !s.Attr.Reachable() {
  1943  				continue
  1944  			}
  1945  			if len(s.P) > 0 {
  1946  				Errorf(s, "should not be bss (size=%d type=%d special=%v)", len(s.P), s.Type, s.Attr.Special())
  1947  			}
  1948  			put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
  1949  
  1950  		case SFILE:
  1951  			put(ctxt, nil, s.Name, FileSym, s.Value, nil)
  1952  
  1953  		case SHOSTOBJ:
  1954  			if Headtype == objabi.Hwindows || Iself {
  1955  				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
  1956  			}
  1957  
  1958  		case SDYNIMPORT:
  1959  			if !s.Attr.Reachable() {
  1960  				continue
  1961  			}
  1962  			put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
  1963  
  1964  		case STLSBSS:
  1965  			if Linkmode == LinkExternal {
  1966  				put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
  1967  			}
  1968  		}
  1969  	}
  1970  
  1971  	var off int32
  1972  	for _, s := range ctxt.Textp {
  1973  		put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
  1974  
  1975  		locals := int32(0)
  1976  		if s.FuncInfo != nil {
  1977  			locals = s.FuncInfo.Locals
  1978  		}
  1979  		// NOTE(ality): acid can't produce a stack trace without .frame symbols
  1980  		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil)
  1981  
  1982  		if s.FuncInfo == nil {
  1983  			continue
  1984  		}
  1985  		for _, a := range s.FuncInfo.Autom {
  1986  			// Emit a or p according to actual offset, even if label is wrong.
  1987  			// This avoids negative offsets, which cannot be encoded.
  1988  			if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM {
  1989  				continue
  1990  			}
  1991  
  1992  			// compute offset relative to FP
  1993  			if a.Name == objabi.A_PARAM {
  1994  				off = a.Aoffset
  1995  			} else {
  1996  				off = a.Aoffset - int32(SysArch.PtrSize)
  1997  			}
  1998  
  1999  			// FP
  2000  			if off >= 0 {
  2001  				put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype)
  2002  				continue
  2003  			}
  2004  
  2005  			// SP
  2006  			if off <= int32(-SysArch.PtrSize) {
  2007  				put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype)
  2008  				continue
  2009  			}
  2010  			// Otherwise, off is addressing the saved program counter.
  2011  			// Something underhanded is going on. Say nothing.
  2012  		}
  2013  	}
  2014  
  2015  	if ctxt.Debugvlog != 0 || *flagN {
  2016  		ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize))
  2017  	}
  2018  }
  2019  
  2020  func Symaddr(s *Symbol) int64 {
  2021  	if !s.Attr.Reachable() {
  2022  		Errorf(s, "unreachable symbol in symaddr")
  2023  	}
  2024  	return s.Value
  2025  }
  2026  
  2027  func (ctxt *Link) xdefine(p string, t SymKind, v int64) {
  2028  	s := ctxt.Syms.Lookup(p, 0)
  2029  	s.Type = t
  2030  	s.Value = v
  2031  	s.Attr |= AttrReachable
  2032  	s.Attr |= AttrSpecial
  2033  	s.Attr |= AttrLocal
  2034  }
  2035  
  2036  func datoff(s *Symbol, addr int64) int64 {
  2037  	if uint64(addr) >= Segdata.Vaddr {
  2038  		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2039  	}
  2040  	if uint64(addr) >= Segtext.Vaddr {
  2041  		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2042  	}
  2043  	Errorf(s, "invalid datoff %#x", addr)
  2044  	return 0
  2045  }
  2046  
  2047  func Entryvalue(ctxt *Link) int64 {
  2048  	a := *flagEntrySymbol
  2049  	if a[0] >= '0' && a[0] <= '9' {
  2050  		return atolwhex(a)
  2051  	}
  2052  	s := ctxt.Syms.Lookup(a, 0)
  2053  	if s.Type == 0 {
  2054  		return *FlagTextAddr
  2055  	}
  2056  	if s.Type != STEXT {
  2057  		Errorf(s, "entry not text")
  2058  	}
  2059  	return s.Value
  2060  }
  2061  
  2062  func undefsym(ctxt *Link, s *Symbol) {
  2063  	var r *Reloc
  2064  
  2065  	for i := 0; i < len(s.R); i++ {
  2066  		r = &s.R[i]
  2067  		if r.Sym == nil { // happens for some external ARM relocs
  2068  			continue
  2069  		}
  2070  		if r.Sym.Type == Sxxx || r.Sym.Type == SXREF {
  2071  			Errorf(s, "undefined: %q", r.Sym.Name)
  2072  		}
  2073  		if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
  2074  			Errorf(s, "relocation target %q", r.Sym.Name)
  2075  		}
  2076  	}
  2077  }
  2078  
  2079  func (ctxt *Link) undef() {
  2080  	for _, s := range ctxt.Textp {
  2081  		undefsym(ctxt, s)
  2082  	}
  2083  	for _, s := range datap {
  2084  		undefsym(ctxt, s)
  2085  	}
  2086  	if nerrors > 0 {
  2087  		errorexit()
  2088  	}
  2089  }
  2090  
  2091  func (ctxt *Link) callgraph() {
  2092  	if !*FlagC {
  2093  		return
  2094  	}
  2095  
  2096  	var i int
  2097  	var r *Reloc
  2098  	for _, s := range ctxt.Textp {
  2099  		for i = 0; i < len(s.R); i++ {
  2100  			r = &s.R[i]
  2101  			if r.Sym == nil {
  2102  				continue
  2103  			}
  2104  			if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == STEXT {
  2105  				ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
  2106  			}
  2107  		}
  2108  	}
  2109  }
  2110  
  2111  func Rnd(v int64, r int64) int64 {
  2112  	if r <= 0 {
  2113  		return v
  2114  	}
  2115  	v += r - 1
  2116  	c := v % r
  2117  	if c < 0 {
  2118  		c += r
  2119  	}
  2120  	v -= c
  2121  	return v
  2122  }
  2123  
  2124  func bgetc(r *bio.Reader) int {
  2125  	c, err := r.ReadByte()
  2126  	if err != nil {
  2127  		if err != io.EOF {
  2128  			log.Fatalf("reading input: %v", err)
  2129  		}
  2130  		return -1
  2131  	}
  2132  	return int(c)
  2133  }
  2134  
  2135  type markKind uint8 // for postorder traversal
  2136  const (
  2137  	unvisited markKind = iota
  2138  	visiting
  2139  	visited
  2140  )
  2141  
  2142  func postorder(libs []*Library) []*Library {
  2143  	order := make([]*Library, 0, len(libs)) // hold the result
  2144  	mark := make(map[*Library]markKind, len(libs))
  2145  	for _, lib := range libs {
  2146  		dfs(lib, mark, &order)
  2147  	}
  2148  	return order
  2149  }
  2150  
  2151  func dfs(lib *Library, mark map[*Library]markKind, order *[]*Library) {
  2152  	if mark[lib] == visited {
  2153  		return
  2154  	}
  2155  	if mark[lib] == visiting {
  2156  		panic("found import cycle while visiting " + lib.Pkg)
  2157  	}
  2158  	mark[lib] = visiting
  2159  	for _, i := range lib.imports {
  2160  		dfs(i, mark, order)
  2161  	}
  2162  	mark[lib] = visited
  2163  	*order = append(*order, lib)
  2164  }