github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/link/internal/ld/lib.go (about)

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