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