github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/cmd/link/internal/ld/lib.go (about)

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