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