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