github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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.SRODATA
   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.SRODATA
   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 {
  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  	import0 := f.Offset()
  1479  
  1480  	c1 = '\n' // the last line ended in \n
  1481  	c2 = bgetc(f)
  1482  	c3 = bgetc(f)
  1483  	for c1 != '\n' || c2 != '!' || c3 != '\n' {
  1484  		c1 = c2
  1485  		c2 = c3
  1486  		c3 = bgetc(f)
  1487  		if c3 == -1 {
  1488  			Errorf(nil, "truncated object file: %s", pn)
  1489  			return nil
  1490  		}
  1491  	}
  1492  
  1493  	import1 := f.Offset()
  1494  
  1495  	f.Seek(import0, 0)
  1496  	ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n
  1497  	f.Seek(import1, 0)
  1498  
  1499  	objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, eof-f.Offset(), pn)
  1500  	addImports(ctxt, lib, pn)
  1501  	return nil
  1502  }
  1503  
  1504  func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
  1505  	data := make([]byte, sym.Size)
  1506  	sect := f.Sections[sym.Section]
  1507  	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  1508  		Errorf(nil, "reading %s from non-data section", sym.Name)
  1509  	}
  1510  	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  1511  	if uint64(n) != sym.Size {
  1512  		Errorf(nil, "reading contents of %s: %v", sym.Name, err)
  1513  	}
  1514  	return data
  1515  }
  1516  
  1517  func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  1518  	data := make([]byte, Rnd(int64(sz), 4))
  1519  	_, err := io.ReadFull(r, data)
  1520  	if err != nil {
  1521  		return nil, err
  1522  	}
  1523  	data = data[:sz]
  1524  	return data, nil
  1525  }
  1526  
  1527  func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  1528  	for _, sect := range f.Sections {
  1529  		if sect.Type != elf.SHT_NOTE {
  1530  			continue
  1531  		}
  1532  		r := sect.Open()
  1533  		for {
  1534  			var namesize, descsize, noteType int32
  1535  			err := binary.Read(r, f.ByteOrder, &namesize)
  1536  			if err != nil {
  1537  				if err == io.EOF {
  1538  					break
  1539  				}
  1540  				return nil, fmt.Errorf("read namesize failed: %v", err)
  1541  			}
  1542  			err = binary.Read(r, f.ByteOrder, &descsize)
  1543  			if err != nil {
  1544  				return nil, fmt.Errorf("read descsize failed: %v", err)
  1545  			}
  1546  			err = binary.Read(r, f.ByteOrder, &noteType)
  1547  			if err != nil {
  1548  				return nil, fmt.Errorf("read type failed: %v", err)
  1549  			}
  1550  			noteName, err := readwithpad(r, namesize)
  1551  			if err != nil {
  1552  				return nil, fmt.Errorf("read name failed: %v", err)
  1553  			}
  1554  			desc, err := readwithpad(r, descsize)
  1555  			if err != nil {
  1556  				return nil, fmt.Errorf("read desc failed: %v", err)
  1557  			}
  1558  			if string(name) == string(noteName) && typ == noteType {
  1559  				return desc, nil
  1560  			}
  1561  		}
  1562  	}
  1563  	return nil, nil
  1564  }
  1565  
  1566  func findshlib(ctxt *Link, shlib string) string {
  1567  	if filepath.IsAbs(shlib) {
  1568  		return shlib
  1569  	}
  1570  	for _, libdir := range ctxt.Libdir {
  1571  		libpath := filepath.Join(libdir, shlib)
  1572  		if _, err := os.Stat(libpath); err == nil {
  1573  			return libpath
  1574  		}
  1575  	}
  1576  	Errorf(nil, "cannot find shared library: %s", shlib)
  1577  	return ""
  1578  }
  1579  
  1580  func ldshlibsyms(ctxt *Link, shlib string) {
  1581  	var libpath string
  1582  	if filepath.IsAbs(shlib) {
  1583  		libpath = shlib
  1584  		shlib = filepath.Base(shlib)
  1585  	} else {
  1586  		libpath = findshlib(ctxt, shlib)
  1587  		if libpath == "" {
  1588  			return
  1589  		}
  1590  	}
  1591  	for _, processedlib := range ctxt.Shlibs {
  1592  		if processedlib.Path == libpath {
  1593  			return
  1594  		}
  1595  	}
  1596  	if ctxt.Debugvlog > 1 {
  1597  		ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath)
  1598  	}
  1599  
  1600  	f, err := elf.Open(libpath)
  1601  	if err != nil {
  1602  		Errorf(nil, "cannot open shared library: %s", libpath)
  1603  		return
  1604  	}
  1605  	defer f.Close()
  1606  
  1607  	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  1608  	if err != nil {
  1609  		Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
  1610  		return
  1611  	}
  1612  
  1613  	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  1614  	if err != nil {
  1615  		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
  1616  		return
  1617  	}
  1618  	var deps []string
  1619  	for _, dep := range strings.Split(string(depsbytes), "\n") {
  1620  		if dep == "" {
  1621  			continue
  1622  		}
  1623  		if !filepath.IsAbs(dep) {
  1624  			// If the dep can be interpreted as a path relative to the shlib
  1625  			// in which it was found, do that. Otherwise, we will leave it
  1626  			// to be resolved by libdir lookup.
  1627  			abs := filepath.Join(filepath.Dir(libpath), dep)
  1628  			if _, err := os.Stat(abs); err == nil {
  1629  				dep = abs
  1630  			}
  1631  		}
  1632  		deps = append(deps, dep)
  1633  	}
  1634  
  1635  	syms, err := f.DynamicSymbols()
  1636  	if err != nil {
  1637  		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
  1638  		return
  1639  	}
  1640  	gcdataLocations := make(map[uint64]*sym.Symbol)
  1641  	for _, elfsym := range syms {
  1642  		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  1643  			continue
  1644  		}
  1645  		lsym := ctxt.Syms.Lookup(elfsym.Name, 0)
  1646  		// Because loadlib above loads all .a files before loading any shared
  1647  		// libraries, any non-dynimport symbols we find that duplicate symbols
  1648  		// already loaded should be ignored (the symbols from the .a files
  1649  		// "win").
  1650  		if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
  1651  			continue
  1652  		}
  1653  		lsym.Type = sym.SDYNIMPORT
  1654  		lsym.ElfType = elf.ST_TYPE(elfsym.Info)
  1655  		lsym.Size = int64(elfsym.Size)
  1656  		if elfsym.Section != elf.SHN_UNDEF {
  1657  			// Set .File for the library that actually defines the symbol.
  1658  			lsym.File = libpath
  1659  			// The decodetype_* functions in decodetype.go need access to
  1660  			// the type data.
  1661  			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
  1662  				lsym.P = readelfsymboldata(ctxt, f, &elfsym)
  1663  				gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
  1664  			}
  1665  		}
  1666  	}
  1667  	gcdataAddresses := make(map[*sym.Symbol]uint64)
  1668  	if ctxt.Arch.Family == sys.ARM64 {
  1669  		for _, sect := range f.Sections {
  1670  			if sect.Type == elf.SHT_RELA {
  1671  				var rela elf.Rela64
  1672  				rdr := sect.Open()
  1673  				for {
  1674  					err := binary.Read(rdr, f.ByteOrder, &rela)
  1675  					if err == io.EOF {
  1676  						break
  1677  					} else if err != nil {
  1678  						Errorf(nil, "reading relocation failed %v", err)
  1679  						return
  1680  					}
  1681  					t := elf.R_AARCH64(rela.Info & 0xffff)
  1682  					if t != elf.R_AARCH64_RELATIVE {
  1683  						continue
  1684  					}
  1685  					if lsym, ok := gcdataLocations[rela.Off]; ok {
  1686  						gcdataAddresses[lsym] = uint64(rela.Addend)
  1687  					}
  1688  				}
  1689  			}
  1690  		}
  1691  	}
  1692  
  1693  	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
  1694  }
  1695  
  1696  func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
  1697  	sect := new(sym.Section)
  1698  	sect.Rwx = uint8(rwx)
  1699  	sect.Name = name
  1700  	sect.Seg = seg
  1701  	sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
  1702  	seg.Sections = append(seg.Sections, sect)
  1703  	return sect
  1704  }
  1705  
  1706  func Le16(b []byte) uint16 {
  1707  	return uint16(b[0]) | uint16(b[1])<<8
  1708  }
  1709  
  1710  func Le32(b []byte) uint32 {
  1711  	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  1712  }
  1713  
  1714  func Le64(b []byte) uint64 {
  1715  	return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32
  1716  }
  1717  
  1718  func Be16(b []byte) uint16 {
  1719  	return uint16(b[0])<<8 | uint16(b[1])
  1720  }
  1721  
  1722  func Be32(b []byte) uint32 {
  1723  	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  1724  }
  1725  
  1726  type chain struct {
  1727  	sym   *sym.Symbol
  1728  	up    *chain
  1729  	limit int // limit on entry to sym
  1730  }
  1731  
  1732  var morestack *sym.Symbol
  1733  
  1734  // TODO: Record enough information in new object files to
  1735  // allow stack checks here.
  1736  
  1737  func haslinkregister(ctxt *Link) bool {
  1738  	return ctxt.FixedFrameSize() != 0
  1739  }
  1740  
  1741  func callsize(ctxt *Link) int {
  1742  	if haslinkregister(ctxt) {
  1743  		return 0
  1744  	}
  1745  	return ctxt.Arch.RegSize
  1746  }
  1747  
  1748  func (ctxt *Link) dostkcheck() {
  1749  	var ch chain
  1750  
  1751  	morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
  1752  
  1753  	// Every splitting function ensures that there are at least StackLimit
  1754  	// bytes available below SP when the splitting prologue finishes.
  1755  	// If the splitting function calls F, then F begins execution with
  1756  	// at least StackLimit - callsize() bytes available.
  1757  	// Check that every function behaves correctly with this amount
  1758  	// of stack, following direct calls in order to piece together chains
  1759  	// of non-splitting functions.
  1760  	ch.up = nil
  1761  
  1762  	ch.limit = objabi.StackLimit - callsize(ctxt)
  1763  
  1764  	// Check every function, but do the nosplit functions in a first pass,
  1765  	// to make the printed failure chains as short as possible.
  1766  	for _, s := range ctxt.Textp {
  1767  		// runtime.racesymbolizethunk is called from gcc-compiled C
  1768  		// code running on the operating system thread stack.
  1769  		// It uses more than the usual amount of stack but that's okay.
  1770  		if s.Name == "runtime.racesymbolizethunk" {
  1771  			continue
  1772  		}
  1773  
  1774  		if s.Attr.NoSplit() {
  1775  			ch.sym = s
  1776  			stkcheck(ctxt, &ch, 0)
  1777  		}
  1778  	}
  1779  
  1780  	for _, s := range ctxt.Textp {
  1781  		if !s.Attr.NoSplit() {
  1782  			ch.sym = s
  1783  			stkcheck(ctxt, &ch, 0)
  1784  		}
  1785  	}
  1786  }
  1787  
  1788  func stkcheck(ctxt *Link, up *chain, depth int) int {
  1789  	limit := up.limit
  1790  	s := up.sym
  1791  
  1792  	// Don't duplicate work: only need to consider each
  1793  	// function at top of safe zone once.
  1794  	top := limit == objabi.StackLimit-callsize(ctxt)
  1795  	if top {
  1796  		if s.Attr.StackCheck() {
  1797  			return 0
  1798  		}
  1799  		s.Attr |= sym.AttrStackCheck
  1800  	}
  1801  
  1802  	if depth > 100 {
  1803  		Errorf(s, "nosplit stack check too deep")
  1804  		stkbroke(ctxt, up, 0)
  1805  		return -1
  1806  	}
  1807  
  1808  	if s.Attr.External() || s.FuncInfo == nil {
  1809  		// external function.
  1810  		// should never be called directly.
  1811  		// onlyctxt.Diagnose the direct caller.
  1812  		// TODO(mwhudson): actually think about this.
  1813  		if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
  1814  			ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
  1815  
  1816  			Errorf(s, "call to external function")
  1817  		}
  1818  		return -1
  1819  	}
  1820  
  1821  	if limit < 0 {
  1822  		stkbroke(ctxt, up, limit)
  1823  		return -1
  1824  	}
  1825  
  1826  	// morestack looks like it calls functions,
  1827  	// but it switches the stack pointer first.
  1828  	if s == morestack {
  1829  		return 0
  1830  	}
  1831  
  1832  	var ch chain
  1833  	ch.up = up
  1834  
  1835  	if !s.Attr.NoSplit() {
  1836  		// Ensure we have enough stack to call morestack.
  1837  		ch.limit = limit - callsize(ctxt)
  1838  		ch.sym = morestack
  1839  		if stkcheck(ctxt, &ch, depth+1) < 0 {
  1840  			return -1
  1841  		}
  1842  		if !top {
  1843  			return 0
  1844  		}
  1845  		// Raise limit to allow frame.
  1846  		locals := int32(0)
  1847  		if s.FuncInfo != nil {
  1848  			locals = s.FuncInfo.Locals
  1849  		}
  1850  		limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize())
  1851  	}
  1852  
  1853  	// Walk through sp adjustments in function, consuming relocs.
  1854  	ri := 0
  1855  
  1856  	endr := len(s.R)
  1857  	var ch1 chain
  1858  	var pcsp Pciter
  1859  	var r *sym.Reloc
  1860  	for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1861  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  1862  
  1863  		// Check stack size in effect for this span.
  1864  		if int32(limit)-pcsp.value < 0 {
  1865  			stkbroke(ctxt, up, int(int32(limit)-pcsp.value))
  1866  			return -1
  1867  		}
  1868  
  1869  		// Process calls in this span.
  1870  		for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
  1871  			r = &s.R[ri]
  1872  			switch r.Type {
  1873  			// Direct call.
  1874  			case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS:
  1875  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  1876  				ch.sym = r.Sym
  1877  				if stkcheck(ctxt, &ch, depth+1) < 0 {
  1878  					return -1
  1879  				}
  1880  
  1881  			// Indirect call. Assume it is a call to a splitting function,
  1882  			// so we have to make sure it can call morestack.
  1883  			// Arrange the data structures to report both calls, so that
  1884  			// if there is an error, stkprint shows all the steps involved.
  1885  			case objabi.R_CALLIND:
  1886  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  1887  
  1888  				ch.sym = nil
  1889  				ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
  1890  				ch1.up = &ch
  1891  				ch1.sym = morestack
  1892  				if stkcheck(ctxt, &ch1, depth+2) < 0 {
  1893  					return -1
  1894  				}
  1895  			}
  1896  		}
  1897  	}
  1898  
  1899  	return 0
  1900  }
  1901  
  1902  func stkbroke(ctxt *Link, ch *chain, limit int) {
  1903  	Errorf(ch.sym, "nosplit stack overflow")
  1904  	stkprint(ctxt, ch, limit)
  1905  }
  1906  
  1907  func stkprint(ctxt *Link, ch *chain, limit int) {
  1908  	var name string
  1909  
  1910  	if ch.sym != nil {
  1911  		name = ch.sym.Name
  1912  		if ch.sym.Attr.NoSplit() {
  1913  			name += " (nosplit)"
  1914  		}
  1915  	} else {
  1916  		name = "function pointer"
  1917  	}
  1918  
  1919  	if ch.up == nil {
  1920  		// top of chain.  ch->sym != nil.
  1921  		if ch.sym.Attr.NoSplit() {
  1922  			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  1923  		} else {
  1924  			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  1925  		}
  1926  	} else {
  1927  		stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
  1928  		if !haslinkregister(ctxt) {
  1929  			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  1930  		}
  1931  	}
  1932  
  1933  	if ch.limit != limit {
  1934  		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  1935  	}
  1936  }
  1937  
  1938  func usage() {
  1939  	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  1940  	objabi.Flagprint(2)
  1941  	Exit(2)
  1942  }
  1943  
  1944  func doversion() {
  1945  	Exitf("version %s", objabi.Version)
  1946  }
  1947  
  1948  type SymbolType int8
  1949  
  1950  const (
  1951  	TextSym      SymbolType = 'T'
  1952  	DataSym                 = 'D'
  1953  	BSSSym                  = 'B'
  1954  	UndefinedSym            = 'U'
  1955  	TLSSym                  = 't'
  1956  	FrameSym                = 'm'
  1957  	ParamSym                = 'p'
  1958  	AutoSym                 = 'a'
  1959  )
  1960  
  1961  func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
  1962  	// These symbols won't show up in the first loop below because we
  1963  	// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
  1964  	s := ctxt.Syms.Lookup("runtime.text", 0)
  1965  	if s.Type == sym.STEXT {
  1966  		// We've already included this symbol in ctxt.Textp
  1967  		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin.
  1968  		// See data.go:/textaddress
  1969  		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) {
  1970  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  1971  		}
  1972  	}
  1973  
  1974  	n := 0
  1975  
  1976  	// Generate base addresses for all text sections if there are multiple
  1977  	for _, sect := range Segtext.Sections {
  1978  		if n == 0 {
  1979  			n++
  1980  			continue
  1981  		}
  1982  		if sect.Name != ".text" {
  1983  			break
  1984  		}
  1985  		s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
  1986  		if s == nil {
  1987  			break
  1988  		}
  1989  		if s.Type == sym.STEXT {
  1990  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  1991  		}
  1992  		n++
  1993  	}
  1994  
  1995  	s = ctxt.Syms.Lookup("runtime.etext", 0)
  1996  	if s.Type == sym.STEXT {
  1997  		// We've already included this symbol in ctxt.Textp
  1998  		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin.
  1999  		// See data.go:/textaddress
  2000  		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) {
  2001  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2002  		}
  2003  	}
  2004  
  2005  	for _, s := range ctxt.Syms.Allsym {
  2006  		if s.Attr.NotInSymbolTable() {
  2007  			continue
  2008  		}
  2009  		if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
  2010  			continue
  2011  		}
  2012  		switch s.Type {
  2013  		case sym.SCONST,
  2014  			sym.SRODATA,
  2015  			sym.SSYMTAB,
  2016  			sym.SPCLNTAB,
  2017  			sym.SINITARR,
  2018  			sym.SDATA,
  2019  			sym.SNOPTRDATA,
  2020  			sym.SELFROSECT,
  2021  			sym.SMACHOGOT,
  2022  			sym.STYPE,
  2023  			sym.SSTRING,
  2024  			sym.SGOSTRING,
  2025  			sym.SGOFUNC,
  2026  			sym.SGCBITS,
  2027  			sym.STYPERELRO,
  2028  			sym.SSTRINGRELRO,
  2029  			sym.SGOSTRINGRELRO,
  2030  			sym.SGOFUNCRELRO,
  2031  			sym.SGCBITSRELRO,
  2032  			sym.SRODATARELRO,
  2033  			sym.STYPELINK,
  2034  			sym.SITABLINK,
  2035  			sym.SWINDOWS:
  2036  			if !s.Attr.Reachable() {
  2037  				continue
  2038  			}
  2039  			put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
  2040  
  2041  		case sym.SBSS, sym.SNOPTRBSS:
  2042  			if !s.Attr.Reachable() {
  2043  				continue
  2044  			}
  2045  			if len(s.P) > 0 {
  2046  				Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
  2047  			}
  2048  			put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
  2049  
  2050  		case sym.SHOSTOBJ:
  2051  			if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
  2052  				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
  2053  			}
  2054  
  2055  		case sym.SDYNIMPORT:
  2056  			if !s.Attr.Reachable() {
  2057  				continue
  2058  			}
  2059  			put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
  2060  
  2061  		case sym.STLSBSS:
  2062  			if ctxt.LinkMode == LinkExternal {
  2063  				put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
  2064  			}
  2065  		}
  2066  	}
  2067  
  2068  	var off int32
  2069  	for _, s := range ctxt.Textp {
  2070  		put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
  2071  
  2072  		locals := int32(0)
  2073  		if s.FuncInfo != nil {
  2074  			locals = s.FuncInfo.Locals
  2075  		}
  2076  		// NOTE(ality): acid can't produce a stack trace without .frame symbols
  2077  		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
  2078  
  2079  		if s.FuncInfo == nil {
  2080  			continue
  2081  		}
  2082  		for _, a := range s.FuncInfo.Autom {
  2083  			// Emit a or p according to actual offset, even if label is wrong.
  2084  			// This avoids negative offsets, which cannot be encoded.
  2085  			if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM {
  2086  				continue
  2087  			}
  2088  
  2089  			// compute offset relative to FP
  2090  			if a.Name == objabi.A_PARAM {
  2091  				off = a.Aoffset
  2092  			} else {
  2093  				off = a.Aoffset - int32(ctxt.Arch.PtrSize)
  2094  			}
  2095  
  2096  			// FP
  2097  			if off >= 0 {
  2098  				put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype)
  2099  				continue
  2100  			}
  2101  
  2102  			// SP
  2103  			if off <= int32(-ctxt.Arch.PtrSize) {
  2104  				put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(ctxt.Arch.PtrSize)), a.Gotype)
  2105  				continue
  2106  			}
  2107  			// Otherwise, off is addressing the saved program counter.
  2108  			// Something underhanded is going on. Say nothing.
  2109  		}
  2110  	}
  2111  
  2112  	if ctxt.Debugvlog != 0 || *flagN {
  2113  		ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize))
  2114  	}
  2115  }
  2116  
  2117  func Symaddr(s *sym.Symbol) int64 {
  2118  	if !s.Attr.Reachable() {
  2119  		Errorf(s, "unreachable symbol in symaddr")
  2120  	}
  2121  	return s.Value
  2122  }
  2123  
  2124  func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
  2125  	s := ctxt.Syms.Lookup(p, 0)
  2126  	s.Type = t
  2127  	s.Value = v
  2128  	s.Attr |= sym.AttrReachable
  2129  	s.Attr |= sym.AttrSpecial
  2130  	s.Attr |= sym.AttrLocal
  2131  }
  2132  
  2133  func datoff(s *sym.Symbol, addr int64) int64 {
  2134  	if uint64(addr) >= Segdata.Vaddr {
  2135  		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2136  	}
  2137  	if uint64(addr) >= Segtext.Vaddr {
  2138  		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2139  	}
  2140  	Errorf(s, "invalid datoff %#x", addr)
  2141  	return 0
  2142  }
  2143  
  2144  func Entryvalue(ctxt *Link) int64 {
  2145  	a := *flagEntrySymbol
  2146  	if a[0] >= '0' && a[0] <= '9' {
  2147  		return atolwhex(a)
  2148  	}
  2149  	s := ctxt.Syms.Lookup(a, 0)
  2150  	if s.Type == 0 {
  2151  		return *FlagTextAddr
  2152  	}
  2153  	if s.Type != sym.STEXT {
  2154  		Errorf(s, "entry not text")
  2155  	}
  2156  	return s.Value
  2157  }
  2158  
  2159  func undefsym(ctxt *Link, s *sym.Symbol) {
  2160  	var r *sym.Reloc
  2161  
  2162  	for i := 0; i < len(s.R); i++ {
  2163  		r = &s.R[i]
  2164  		if r.Sym == nil { // happens for some external ARM relocs
  2165  			continue
  2166  		}
  2167  		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
  2168  		// sense and should be removed when someone has thought about it properly.
  2169  		if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
  2170  			Errorf(s, "undefined: %q", r.Sym.Name)
  2171  		}
  2172  		if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
  2173  			Errorf(s, "relocation target %q", r.Sym.Name)
  2174  		}
  2175  	}
  2176  }
  2177  
  2178  func (ctxt *Link) undef() {
  2179  	for _, s := range ctxt.Textp {
  2180  		undefsym(ctxt, s)
  2181  	}
  2182  	for _, s := range datap {
  2183  		undefsym(ctxt, s)
  2184  	}
  2185  	if nerrors > 0 {
  2186  		errorexit()
  2187  	}
  2188  }
  2189  
  2190  func (ctxt *Link) callgraph() {
  2191  	if !*FlagC {
  2192  		return
  2193  	}
  2194  
  2195  	var i int
  2196  	var r *sym.Reloc
  2197  	for _, s := range ctxt.Textp {
  2198  		for i = 0; i < len(s.R); i++ {
  2199  			r = &s.R[i]
  2200  			if r.Sym == nil {
  2201  				continue
  2202  			}
  2203  			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 {
  2204  				ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
  2205  			}
  2206  		}
  2207  	}
  2208  }
  2209  
  2210  func Rnd(v int64, r int64) int64 {
  2211  	if r <= 0 {
  2212  		return v
  2213  	}
  2214  	v += r - 1
  2215  	c := v % r
  2216  	if c < 0 {
  2217  		c += r
  2218  	}
  2219  	v -= c
  2220  	return v
  2221  }
  2222  
  2223  func bgetc(r *bio.Reader) int {
  2224  	c, err := r.ReadByte()
  2225  	if err != nil {
  2226  		if err != io.EOF {
  2227  			log.Fatalf("reading input: %v", err)
  2228  		}
  2229  		return -1
  2230  	}
  2231  	return int(c)
  2232  }
  2233  
  2234  type markKind uint8 // for postorder traversal
  2235  const (
  2236  	unvisited markKind = iota
  2237  	visiting
  2238  	visited
  2239  )
  2240  
  2241  func postorder(libs []*sym.Library) []*sym.Library {
  2242  	order := make([]*sym.Library, 0, len(libs)) // hold the result
  2243  	mark := make(map[*sym.Library]markKind, len(libs))
  2244  	for _, lib := range libs {
  2245  		dfs(lib, mark, &order)
  2246  	}
  2247  	return order
  2248  }
  2249  
  2250  func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
  2251  	if mark[lib] == visited {
  2252  		return
  2253  	}
  2254  	if mark[lib] == visiting {
  2255  		panic("found import cycle while visiting " + lib.Pkg)
  2256  	}
  2257  	mark[lib] = visiting
  2258  	for _, i := range lib.Imports {
  2259  		dfs(i, mark, order)
  2260  	}
  2261  	mark[lib] = visited
  2262  	*order = append(*order, lib)
  2263  }