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