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