github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/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  	"github.com/gagliardetto/golang-go/cmd/internal/bio"
    37  	"github.com/gagliardetto/golang-go/cmd/internal/obj"
    38  	"github.com/gagliardetto/golang-go/cmd/internal/objabi"
    39  	"github.com/gagliardetto/golang-go/cmd/internal/sys"
    40  	"github.com/gagliardetto/golang-go/cmd/link/internal/loadelf"
    41  	"github.com/gagliardetto/golang-go/cmd/link/internal/loader"
    42  	"github.com/gagliardetto/golang-go/cmd/link/internal/loadmacho"
    43  	"github.com/gagliardetto/golang-go/cmd/link/internal/loadpe"
    44  	"github.com/gagliardetto/golang-go/cmd/link/internal/loadxcoff"
    45  	"github.com/gagliardetto/golang-go/cmd/link/internal/objfile"
    46  	"github.com/gagliardetto/golang-go/cmd/link/internal/sym"
    47  	"crypto/sha1"
    48  	"debug/elf"
    49  	"debug/macho"
    50  	"encoding/base64"
    51  	"encoding/binary"
    52  	"encoding/hex"
    53  	"fmt"
    54  	"io"
    55  	"io/ioutil"
    56  	"log"
    57  	"os"
    58  	"os/exec"
    59  	"path/filepath"
    60  	"runtime"
    61  	"sort"
    62  	"strings"
    63  	"sync"
    64  )
    65  
    66  // Data layout and relocation.
    67  
    68  // Derived from Inferno utils/6l/l.h
    69  // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
    70  //
    71  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
    72  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
    73  //	Portions Copyright © 1997-1999 Vita Nuova Limited
    74  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
    75  //	Portions Copyright © 2004,2006 Bruce Ellis
    76  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    77  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    78  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    79  //
    80  // Permission is hereby granted, free of charge, to any person obtaining a copy
    81  // of this software and associated documentation files (the "Software"), to deal
    82  // in the Software without restriction, including without limitation the rights
    83  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    84  // copies of the Software, and to permit persons to whom the Software is
    85  // furnished to do so, subject to the following conditions:
    86  //
    87  // The above copyright notice and this permission notice shall be included in
    88  // all copies or substantial portions of the Software.
    89  //
    90  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    91  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    92  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    93  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    94  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    95  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    96  // THE SOFTWARE.
    97  
    98  type Arch struct {
    99  	Funcalign      int
   100  	Maxalign       int
   101  	Minalign       int
   102  	Dwarfregsp     int
   103  	Dwarfreglr     int
   104  	Linuxdynld     string
   105  	Freebsddynld   string
   106  	Netbsddynld    string
   107  	Openbsddynld   string
   108  	Dragonflydynld string
   109  	Solarisdynld   string
   110  	Adddynrel      func(*Link, *sym.Symbol, *sym.Reloc) bool
   111  	Archinit       func(*Link)
   112  	// Archreloc is an arch-specific hook that assists in
   113  	// relocation processing (invoked by 'relocsym'); it handles
   114  	// target-specific relocation tasks. Here "rel" is the current
   115  	// relocation being examined, "sym" is the symbol containing the
   116  	// chunk of data to which the relocation applies, and "off" is the
   117  	// contents of the to-be-relocated data item (from sym.P). Return
   118  	// value is the appropriately relocated value (to be written back
   119  	// to the same spot in sym.P) and a boolean indicating
   120  	// success/failure (a failing value indicates a fatal error).
   121  	Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
   122  		offset int64) (relocatedOffset int64, success bool)
   123  	// Archrelocvariant is a second arch-specific hook used for
   124  	// relocation processing; it handles relocations where r.Type is
   125  	// insufficient to describe the relocation (r.Variant !=
   126  	// sym.RV_NONE). Here "rel" is the relocation being applied, "sym"
   127  	// is the symbol containing the chunk of data to which the
   128  	// relocation applies, and "off" is the contents of the
   129  	// to-be-relocated data item (from sym.P). Return is an updated
   130  	// offset value.
   131  	Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
   132  		offset int64) (relocatedOffset int64)
   133  	Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
   134  
   135  	// Asmb and Asmb2 are arch-specific routines that write the output
   136  	// file. Typically, Asmb writes most of the content (sections and
   137  	// segments), for which we have computed the size and offset. Asmb2
   138  	// writes the rest.
   139  	Asmb  func(*Link)
   140  	Asmb2 func(*Link)
   141  
   142  	Elfreloc1   func(*Link, *sym.Reloc, int64) bool
   143  	Elfsetupplt func(*Link)
   144  	Gentext     func(*Link)
   145  	Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   146  	PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   147  	Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   148  
   149  	// TLSIEtoLE converts a TLS Initial Executable relocation to
   150  	// a TLS Local Executable relocation.
   151  	//
   152  	// This is possible when a TLS IE relocation refers to a local
   153  	// symbol in an executable, which is typical when internally
   154  	// linking PIE binaries.
   155  	TLSIEtoLE func(s *sym.Symbol, off, size int)
   156  
   157  	// optional override for assignAddress
   158  	AssignAddress func(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64)
   159  }
   160  
   161  var (
   162  	thearch Arch
   163  	Lcsize  int32
   164  	rpath   Rpath
   165  	Spsize  int32
   166  	Symsize int32
   167  )
   168  
   169  const (
   170  	MINFUNC = 16 // minimum size for a function
   171  )
   172  
   173  // DynlinkingGo reports whether we are producing Go code that can live
   174  // in separate shared libraries linked together at runtime.
   175  func (ctxt *Link) DynlinkingGo() bool {
   176  	if !ctxt.Loaded {
   177  		panic("DynlinkingGo called before all symbols loaded")
   178  	}
   179  	return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins
   180  }
   181  
   182  // CanUsePlugins reports whether a plugins can be used
   183  func (ctxt *Link) CanUsePlugins() bool {
   184  	if !ctxt.Loaded {
   185  		panic("CanUsePlugins called before all symbols loaded")
   186  	}
   187  	return ctxt.canUsePlugins
   188  }
   189  
   190  // UseRelro reports whether to make use of "read only relocations" aka
   191  // relro.
   192  func (ctxt *Link) UseRelro() bool {
   193  	switch ctxt.BuildMode {
   194  	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
   195  		return ctxt.IsELF || ctxt.HeadType == objabi.Haix
   196  	default:
   197  		return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal)
   198  	}
   199  }
   200  
   201  var (
   202  	dynexp          []*sym.Symbol
   203  	dynlib          []string
   204  	ldflag          []string
   205  	havedynamic     int
   206  	Funcalign       int
   207  	iscgo           bool
   208  	elfglobalsymndx int
   209  	interpreter     string
   210  
   211  	debug_s bool // backup old value of debug['s']
   212  	HEADR   int32
   213  
   214  	nerrors  int
   215  	liveness int64
   216  
   217  	// See -strictdups command line flag.
   218  	checkStrictDups   int // 0=off 1=warning 2=error
   219  	strictDupMsgCount int
   220  )
   221  
   222  var (
   223  	Segtext      sym.Segment
   224  	Segrodata    sym.Segment
   225  	Segrelrodata sym.Segment
   226  	Segdata      sym.Segment
   227  	Segdwarf     sym.Segment
   228  )
   229  
   230  const pkgdef = "__.PKGDEF"
   231  
   232  var (
   233  	// Set if we see an object compiled by the host compiler that is not
   234  	// from a package that is known to support internal linking mode.
   235  	externalobj = false
   236  	theline     string
   237  )
   238  
   239  func Lflag(ctxt *Link, arg string) {
   240  	ctxt.Libdir = append(ctxt.Libdir, arg)
   241  }
   242  
   243  /*
   244   * Unix doesn't like it when we write to a running (or, sometimes,
   245   * recently run) binary, so remove the output file before writing it.
   246   * On Windows 7, remove() can force a subsequent create() to fail.
   247   * S_ISREG() does not exist on Plan 9.
   248   */
   249  func mayberemoveoutfile() {
   250  	if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
   251  		return
   252  	}
   253  	os.Remove(*flagOutfile)
   254  }
   255  
   256  func libinit(ctxt *Link) {
   257  	Funcalign = thearch.Funcalign
   258  
   259  	// add goroot to the end of the libdir list.
   260  	suffix := ""
   261  
   262  	suffixsep := ""
   263  	if *flagInstallSuffix != "" {
   264  		suffixsep = "_"
   265  		suffix = *flagInstallSuffix
   266  	} else if *flagRace {
   267  		suffixsep = "_"
   268  		suffix = "race"
   269  	} else if *flagMsan {
   270  		suffixsep = "_"
   271  		suffix = "msan"
   272  	}
   273  
   274  	Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
   275  
   276  	mayberemoveoutfile()
   277  	f, err := os.OpenFile(*flagOutfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
   278  	if err != nil {
   279  		Exitf("cannot create %s: %v", *flagOutfile, err)
   280  	}
   281  
   282  	ctxt.Out.w = bufio.NewWriter(f)
   283  	ctxt.Out.f = f
   284  
   285  	if *flagEntrySymbol == "" {
   286  		switch ctxt.BuildMode {
   287  		case BuildModeCShared, BuildModeCArchive:
   288  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
   289  		case BuildModeExe, BuildModePIE:
   290  			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
   291  		case BuildModeShared, BuildModePlugin:
   292  			// No *flagEntrySymbol for -buildmode=shared and plugin
   293  		default:
   294  			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
   295  		}
   296  	}
   297  }
   298  
   299  func exitIfErrors() {
   300  	if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 {
   301  		mayberemoveoutfile()
   302  		Exit(2)
   303  	}
   304  
   305  }
   306  
   307  func errorexit() {
   308  	exitIfErrors()
   309  	Exit(0)
   310  }
   311  
   312  func loadinternal(ctxt *Link, name string) *sym.Library {
   313  	if ctxt.linkShared && ctxt.PackageShlib != nil {
   314  		if shlib := ctxt.PackageShlib[name]; shlib != "" {
   315  			return addlibpath(ctxt, "internal", "internal", "", name, shlib)
   316  		}
   317  	}
   318  	if ctxt.PackageFile != nil {
   319  		if pname := ctxt.PackageFile[name]; pname != "" {
   320  			return addlibpath(ctxt, "internal", "internal", pname, name, "")
   321  		}
   322  		ctxt.Logf("loadinternal: cannot find %s\n", name)
   323  		return nil
   324  	}
   325  
   326  	for _, libdir := range ctxt.Libdir {
   327  		if ctxt.linkShared {
   328  			shlibname := filepath.Join(libdir, name+".shlibname")
   329  			if ctxt.Debugvlog != 0 {
   330  				ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
   331  			}
   332  			if _, err := os.Stat(shlibname); err == nil {
   333  				return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
   334  			}
   335  		}
   336  		pname := filepath.Join(libdir, name+".a")
   337  		if ctxt.Debugvlog != 0 {
   338  			ctxt.Logf("searching for %s.a in %s\n", name, pname)
   339  		}
   340  		if _, err := os.Stat(pname); err == nil {
   341  			return addlibpath(ctxt, "internal", "internal", pname, name, "")
   342  		}
   343  	}
   344  
   345  	ctxt.Logf("warning: unable to find %s.a\n", name)
   346  	return nil
   347  }
   348  
   349  // extld returns the current external linker.
   350  func (ctxt *Link) extld() string {
   351  	if *flagExtld == "" {
   352  		*flagExtld = "gcc"
   353  	}
   354  	return *flagExtld
   355  }
   356  
   357  // findLibPathCmd uses cmd command to find gcc library libname.
   358  // It returns library full path if found, or "none" if not found.
   359  func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
   360  	extld := ctxt.extld()
   361  	args := hostlinkArchArgs(ctxt.Arch)
   362  	args = append(args, cmd)
   363  	if ctxt.Debugvlog != 0 {
   364  		ctxt.Logf("%s %v\n", extld, args)
   365  	}
   366  	out, err := exec.Command(extld, args...).Output()
   367  	if err != nil {
   368  		if ctxt.Debugvlog != 0 {
   369  			ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
   370  		}
   371  		return "none"
   372  	}
   373  	return strings.TrimSpace(string(out))
   374  }
   375  
   376  // findLibPath searches for library libname.
   377  // It returns library full path if found, or "none" if not found.
   378  func (ctxt *Link) findLibPath(libname string) string {
   379  	return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
   380  }
   381  
   382  func (ctxt *Link) loadlib() {
   383  	if *flagNewobj {
   384  		var flags uint32
   385  		switch *FlagStrictDups {
   386  		case 0:
   387  			// nothing to do
   388  		case 1, 2:
   389  			flags = loader.FlagStrictDups
   390  		default:
   391  			log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
   392  		}
   393  		ctxt.loader = loader.NewLoader(flags)
   394  	}
   395  
   396  	ctxt.cgo_export_static = make(map[string]bool)
   397  	ctxt.cgo_export_dynamic = make(map[string]bool)
   398  
   399  	// ctxt.Library grows during the loop, so not a range loop.
   400  	i := 0
   401  	for ; i < len(ctxt.Library); i++ {
   402  		lib := ctxt.Library[i]
   403  		if lib.Shlib == "" {
   404  			if ctxt.Debugvlog > 1 {
   405  				ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
   406  			}
   407  			loadobjfile(ctxt, lib)
   408  		}
   409  	}
   410  
   411  	// load internal packages, if not already
   412  	if ctxt.Arch.Family == sys.ARM {
   413  		loadinternal(ctxt, "math")
   414  	}
   415  	if *flagRace {
   416  		loadinternal(ctxt, "runtime/race")
   417  	}
   418  	if *flagMsan {
   419  		loadinternal(ctxt, "runtime/msan")
   420  	}
   421  	loadinternal(ctxt, "runtime")
   422  	for ; i < len(ctxt.Library); i++ {
   423  		lib := ctxt.Library[i]
   424  		if lib.Shlib == "" {
   425  			loadobjfile(ctxt, lib)
   426  		}
   427  	}
   428  
   429  	if *flagNewobj {
   430  		iscgo = ctxt.loader.Lookup("x_cgo_init", 0) != 0
   431  		ctxt.canUsePlugins = ctxt.loader.Lookup("plugin.Open", sym.SymVerABIInternal) != 0
   432  	} else {
   433  		iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
   434  		ctxt.canUsePlugins = ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil
   435  	}
   436  
   437  	// We now have enough information to determine the link mode.
   438  	determineLinkMode(ctxt)
   439  
   440  	if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil && !(objabi.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && (ctxt.Arch.Family == sys.AMD64 || ctxt.Arch.Family == sys.I386)) {
   441  		// This indicates a user requested -linkmode=external.
   442  		// The startup code uses an import of runtime/cgo to decide
   443  		// whether to initialize the TLS.  So give it one. This could
   444  		// be handled differently but it's an unusual case.
   445  		if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil {
   446  			if lib.Shlib != "" {
   447  				ldshlibsyms(ctxt, lib.Shlib)
   448  			} else {
   449  				if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
   450  					Exitf("cannot implicitly include runtime/cgo in a shared library")
   451  				}
   452  				loadobjfile(ctxt, lib)
   453  			}
   454  		}
   455  	}
   456  
   457  	for _, lib := range ctxt.Library {
   458  		if lib.Shlib != "" {
   459  			if ctxt.Debugvlog > 1 {
   460  				ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref)
   461  			}
   462  			ldshlibsyms(ctxt, lib.Shlib)
   463  		}
   464  	}
   465  
   466  	if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
   467  		if *flagNewobj {
   468  			// In newobj mode, we typically create sym.Symbols later therefore
   469  			// also set cgo attributes later. However, for internal cgo linking,
   470  			// the host object loaders still work with sym.Symbols (for now),
   471  			// and they need cgo attributes set to work properly. So process
   472  			// them now.
   473  			lookup := func(name string, ver int) *sym.Symbol { return ctxt.loader.LookupOrCreate(name, ver, ctxt.Syms) }
   474  			for _, d := range ctxt.cgodata {
   475  				setCgoAttr(ctxt, lookup, d.file, d.pkg, d.directives)
   476  			}
   477  			ctxt.cgodata = nil
   478  		}
   479  
   480  		// Drop all the cgo_import_static declarations.
   481  		// Turns out we won't be needing them.
   482  		for _, s := range ctxt.Syms.Allsym {
   483  			if s.Type == sym.SHOSTOBJ {
   484  				// If a symbol was marked both
   485  				// cgo_import_static and cgo_import_dynamic,
   486  				// then we want to make it cgo_import_dynamic
   487  				// now.
   488  				if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
   489  					s.Type = sym.SDYNIMPORT
   490  				} else {
   491  					s.Type = 0
   492  				}
   493  			}
   494  		}
   495  	}
   496  
   497  	// Conditionally load host objects, or setup for external linking.
   498  	hostobjs(ctxt)
   499  	hostlinksetup(ctxt)
   500  
   501  	if *flagNewobj {
   502  		// Add references of externally defined symbols.
   503  		ctxt.loader.LoadRefs(ctxt.Arch, ctxt.Syms)
   504  	}
   505  
   506  	// Now that we know the link mode, set the dynexp list.
   507  	if !*flagNewobj { // set this later in newobj mode
   508  		setupdynexp(ctxt)
   509  	}
   510  
   511  	if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
   512  		// If we have any undefined symbols in external
   513  		// objects, try to read them from the libgcc file.
   514  		any := false
   515  		for _, s := range ctxt.Syms.Allsym {
   516  			for i := range s.R {
   517  				r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
   518  				if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
   519  					any = true
   520  					break
   521  				}
   522  			}
   523  		}
   524  		if any {
   525  			if *flagLibGCC == "" {
   526  				*flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
   527  			}
   528  			if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" {
   529  				// On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a".
   530  				// In this case we fail to load libgcc.a and can encounter link
   531  				// errors - see if we can find libcompiler_rt.a instead.
   532  				*flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
   533  			}
   534  			if *flagLibGCC != "none" {
   535  				hostArchive(ctxt, *flagLibGCC)
   536  			}
   537  			if ctxt.HeadType == objabi.Hwindows {
   538  				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
   539  					hostArchive(ctxt, p)
   540  				}
   541  				if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
   542  					hostArchive(ctxt, p)
   543  				}
   544  				// Link libmsvcrt.a to resolve '__acrt_iob_func' symbol
   545  				// (see https://golang.org/issue/23649 for details).
   546  				if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" {
   547  					hostArchive(ctxt, p)
   548  				}
   549  				// TODO: maybe do something similar to peimporteddlls to collect all lib names
   550  				// and try link them all to final exe just like libmingwex.a and libmingw32.a:
   551  				/*
   552  					for:
   553  					#cgo windows LDFLAGS: -lmsvcrt -lm
   554  					import:
   555  					libmsvcrt.a libm.a
   556  				*/
   557  			}
   558  		}
   559  	}
   560  
   561  	// We've loaded all the code now.
   562  	ctxt.Loaded = true
   563  
   564  	importcycles()
   565  
   566  	if *flagNewobj {
   567  		strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
   568  	}
   569  }
   570  
   571  // Set up dynexp list.
   572  func setupdynexp(ctxt *Link) {
   573  	dynexpMap := ctxt.cgo_export_dynamic
   574  	if ctxt.LinkMode == LinkExternal {
   575  		dynexpMap = ctxt.cgo_export_static
   576  	}
   577  	dynexp = make([]*sym.Symbol, 0, len(dynexpMap))
   578  	for exp := range dynexpMap {
   579  		s := ctxt.Syms.Lookup(exp, 0)
   580  		dynexp = append(dynexp, s)
   581  	}
   582  	sort.Sort(byName(dynexp))
   583  
   584  	// Resolve ABI aliases in the list of cgo-exported functions.
   585  	// This is necessary because we load the ABI0 symbol for all
   586  	// cgo exports.
   587  	for i, s := range dynexp {
   588  		if s.Type != sym.SABIALIAS {
   589  			continue
   590  		}
   591  		t := resolveABIAlias(s)
   592  		t.Attr |= s.Attr
   593  		t.SetExtname(s.Extname())
   594  		dynexp[i] = t
   595  	}
   596  
   597  	ctxt.cgo_export_static = nil
   598  	ctxt.cgo_export_dynamic = nil
   599  }
   600  
   601  // Set up flags and special symbols depending on the platform build mode.
   602  func (ctxt *Link) linksetup() {
   603  	switch ctxt.BuildMode {
   604  	case BuildModeCShared, BuildModePlugin:
   605  		s := ctxt.Syms.Lookup("runtime.islibrary", 0)
   606  		s.Type = sym.SNOPTRDATA
   607  		s.Attr |= sym.AttrDuplicateOK
   608  		s.AddUint8(1)
   609  	case BuildModeCArchive:
   610  		s := ctxt.Syms.Lookup("runtime.isarchive", 0)
   611  		s.Type = sym.SNOPTRDATA
   612  		s.Attr |= sym.AttrDuplicateOK
   613  		s.AddUint8(1)
   614  	}
   615  
   616  	// Recalculate pe parameters now that we have ctxt.LinkMode set.
   617  	if ctxt.HeadType == objabi.Hwindows {
   618  		Peinit(ctxt)
   619  	}
   620  
   621  	if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
   622  		*FlagTextAddr = 0
   623  	}
   624  
   625  	// If there are no dynamic libraries needed, gcc disables dynamic linking.
   626  	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   627  	// assumes that a dynamic binary always refers to at least one dynamic library.
   628  	// Rather than be a source of test cases for glibc, disable dynamic linking
   629  	// the same way that gcc would.
   630  	//
   631  	// Exception: on OS X, programs such as Shark only work with dynamic
   632  	// binaries, so leave it enabled on OS X (Mach-O) binaries.
   633  	// Also leave it enabled on Solaris which doesn't support
   634  	// statically linked binaries.
   635  	if ctxt.BuildMode == BuildModeExe {
   636  		if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
   637  			*FlagD = true
   638  		}
   639  	}
   640  
   641  	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
   642  		toc := ctxt.Syms.Lookup(".TOC.", 0)
   643  		toc.Type = sym.SDYNIMPORT
   644  	}
   645  
   646  	// The Android Q linker started to complain about underalignment of the our TLS
   647  	// section. We don't actually use the section on android, so dont't
   648  	// generate it.
   649  	if objabi.GOOS != "android" {
   650  		tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0)
   651  
   652  		// runtime.tlsg is used for external linking on platforms that do not define
   653  		// a variable to hold g in assembly (currently only intel).
   654  		if tlsg.Type == 0 {
   655  			tlsg.Type = sym.STLSBSS
   656  			tlsg.Size = int64(ctxt.Arch.PtrSize)
   657  		} else if tlsg.Type != sym.SDYNIMPORT {
   658  			Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
   659  		}
   660  		tlsg.Attr |= sym.AttrReachable
   661  		ctxt.Tlsg = tlsg
   662  	}
   663  
   664  	var moduledata *sym.Symbol
   665  	if ctxt.BuildMode == BuildModePlugin {
   666  		moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
   667  		moduledata.Attr |= sym.AttrLocal
   668  	} else {
   669  		moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
   670  	}
   671  	if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT {
   672  		// If the module (toolchain-speak for "executable or shared
   673  		// library") we are linking contains the runtime package, it
   674  		// will define the runtime.firstmoduledata symbol and we
   675  		// truncate it back to 0 bytes so we can define its entire
   676  		// contents in symtab.go:symtab().
   677  		moduledata.Size = 0
   678  
   679  		// In addition, on ARM, the runtime depends on the linker
   680  		// recording the value of GOARM.
   681  		if ctxt.Arch.Family == sys.ARM {
   682  			s := ctxt.Syms.Lookup("runtime.goarm", 0)
   683  			s.Type = sym.SDATA
   684  			s.Size = 0
   685  			s.AddUint8(uint8(objabi.GOARM))
   686  		}
   687  
   688  		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
   689  			s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
   690  			s.Type = sym.SDATA
   691  			s.Size = 0
   692  			s.AddUint8(1)
   693  		}
   694  	} else {
   695  		// If OTOH the module does not contain the runtime package,
   696  		// create a local symbol for the moduledata.
   697  		moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
   698  		moduledata.Attr |= sym.AttrLocal
   699  	}
   700  	// In all cases way we mark the moduledata as noptrdata to hide it from
   701  	// the GC.
   702  	moduledata.Type = sym.SNOPTRDATA
   703  	moduledata.Attr |= sym.AttrReachable
   704  	ctxt.Moduledata = moduledata
   705  
   706  	// If package versioning is required, generate a hash of the
   707  	// packages used in the link.
   708  	if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
   709  		for _, lib := range ctxt.Library {
   710  			if lib.Shlib == "" {
   711  				genhash(ctxt, lib)
   712  			}
   713  		}
   714  	}
   715  
   716  	if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
   717  		if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
   718  			got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
   719  			got.Type = sym.SDYNIMPORT
   720  			got.Attr |= sym.AttrReachable
   721  		}
   722  	}
   723  }
   724  
   725  // mangleTypeSym shortens the names of symbols that represent Go types
   726  // if they are visible in the symbol table.
   727  //
   728  // As the names of these symbols are derived from the string of
   729  // the type, they can run to many kilobytes long. So we shorten
   730  // them using a SHA-1 when the name appears in the final binary.
   731  // This also removes characters that upset external linkers.
   732  //
   733  // These are the symbols that begin with the prefix 'type.' and
   734  // contain run-time type information used by the runtime and reflect
   735  // packages. All Go binaries contain these symbols, but only
   736  // those programs loaded dynamically in multiple parts need these
   737  // symbols to have entries in the symbol table.
   738  func (ctxt *Link) mangleTypeSym() {
   739  	if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() {
   740  		return
   741  	}
   742  
   743  	for _, s := range ctxt.Syms.Allsym {
   744  		newName := typeSymbolMangle(s.Name)
   745  		if newName != s.Name {
   746  			ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent)
   747  		}
   748  	}
   749  }
   750  
   751  // typeSymbolMangle mangles the given symbol name into something shorter.
   752  //
   753  // Keep the type.. prefix, which parts of the linker (like the
   754  // DWARF generator) know means the symbol is not decodable.
   755  // Leave type.runtime. symbols alone, because other parts of
   756  // the linker manipulates them.
   757  func typeSymbolMangle(name string) string {
   758  	if !strings.HasPrefix(name, "type.") {
   759  		return name
   760  	}
   761  	if strings.HasPrefix(name, "type.runtime.") {
   762  		return name
   763  	}
   764  	if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
   765  		return name
   766  	}
   767  	hash := sha1.Sum([]byte(name))
   768  	prefix := "type."
   769  	if name[5] == '.' {
   770  		prefix = "type.."
   771  	}
   772  	return prefix + base64.StdEncoding.EncodeToString(hash[:6])
   773  }
   774  
   775  /*
   776   * look for the next file in an archive.
   777   * adapted from libmach.
   778   */
   779  func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
   780  	if off&1 != 0 {
   781  		off++
   782  	}
   783  	bp.MustSeek(off, 0)
   784  	var buf [SAR_HDR]byte
   785  	if n, err := io.ReadFull(bp, buf[:]); err != nil {
   786  		if n == 0 && err != io.EOF {
   787  			return -1
   788  		}
   789  		return 0
   790  	}
   791  
   792  	a.name = artrim(buf[0:16])
   793  	a.date = artrim(buf[16:28])
   794  	a.uid = artrim(buf[28:34])
   795  	a.gid = artrim(buf[34:40])
   796  	a.mode = artrim(buf[40:48])
   797  	a.size = artrim(buf[48:58])
   798  	a.fmag = artrim(buf[58:60])
   799  
   800  	arsize := atolwhex(a.size)
   801  	if arsize&1 != 0 {
   802  		arsize++
   803  	}
   804  	return arsize + SAR_HDR
   805  }
   806  
   807  func genhash(ctxt *Link, lib *sym.Library) {
   808  	f, err := bio.Open(lib.File)
   809  	if err != nil {
   810  		Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
   811  		return
   812  	}
   813  	defer f.Close()
   814  
   815  	var magbuf [len(ARMAG)]byte
   816  	if _, err := io.ReadFull(f, magbuf[:]); err != nil {
   817  		Exitf("file %s too short", lib.File)
   818  	}
   819  
   820  	if string(magbuf[:]) != ARMAG {
   821  		Exitf("%s is not an archive file", lib.File)
   822  	}
   823  
   824  	var arhdr ArHdr
   825  	l := nextar(f, f.Offset(), &arhdr)
   826  	if l <= 0 {
   827  		Errorf(nil, "%s: short read on archive file symbol header", lib.File)
   828  		return
   829  	}
   830  	if arhdr.name != pkgdef {
   831  		Errorf(nil, "%s: missing package data entry", lib.File)
   832  		return
   833  	}
   834  
   835  	h := sha1.New()
   836  
   837  	// To compute the hash of a package, we hash the first line of
   838  	// __.PKGDEF (which contains the toolchain version and any
   839  	// GOEXPERIMENT flags) and the export data (which is between
   840  	// the first two occurrences of "\n$$").
   841  
   842  	pkgDefBytes := make([]byte, atolwhex(arhdr.size))
   843  	_, err = io.ReadFull(f, pkgDefBytes)
   844  	if err != nil {
   845  		Errorf(nil, "%s: error reading package data: %v", lib.File, err)
   846  		return
   847  	}
   848  	firstEOL := bytes.IndexByte(pkgDefBytes, '\n')
   849  	if firstEOL < 0 {
   850  		Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
   851  		return
   852  	}
   853  	firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$"))
   854  	if firstDoubleDollar < 0 {
   855  		Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File)
   856  		return
   857  	}
   858  	secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$"))
   859  	if secondDoubleDollar < 0 {
   860  		Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File)
   861  		return
   862  	}
   863  	h.Write(pkgDefBytes[0:firstEOL])
   864  	h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
   865  	lib.Hash = hex.EncodeToString(h.Sum(nil))
   866  }
   867  
   868  func loadobjfile(ctxt *Link, lib *sym.Library) {
   869  	pkg := objabi.PathToPrefix(lib.Pkg)
   870  
   871  	if ctxt.Debugvlog > 1 {
   872  		ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg)
   873  	}
   874  	f, err := bio.Open(lib.File)
   875  	if err != nil {
   876  		Exitf("cannot open file %s: %v", lib.File, err)
   877  	}
   878  	defer f.Close()
   879  	defer func() {
   880  		if pkg == "main" && !lib.Main {
   881  			Exitf("%s: not package main", lib.File)
   882  		}
   883  
   884  		// Ideally, we'd check that *all* object files within
   885  		// the archive were marked safe, but here we settle
   886  		// for *any*.
   887  		//
   888  		// Historically, cmd/link only checked the __.PKGDEF
   889  		// file, which in turn came from the first object
   890  		// file, typically produced by cmd/compile. The
   891  		// remaining object files are normally produced by
   892  		// cmd/asm, which doesn't support marking files as
   893  		// safe anyway. So at least in practice, this matches
   894  		// how safe mode has always worked.
   895  		if *flagU && !lib.Safe {
   896  			Exitf("%s: load of unsafe package %s", lib.File, pkg)
   897  		}
   898  	}()
   899  
   900  	for i := 0; i < len(ARMAG); i++ {
   901  		if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
   902  			continue
   903  		}
   904  
   905  		/* load it as a regular file */
   906  		l := f.MustSeek(0, 2)
   907  		f.MustSeek(0, 0)
   908  		ldobj(ctxt, f, lib, l, lib.File, lib.File)
   909  		return
   910  	}
   911  
   912  	/*
   913  	 * load all the object files from the archive now.
   914  	 * this gives us sequential file access and keeps us
   915  	 * from needing to come back later to pick up more
   916  	 * objects.  it breaks the usual C archive model, but
   917  	 * this is Go, not C.  the common case in Go is that
   918  	 * we need to load all the objects, and then we throw away
   919  	 * the individual symbols that are unused.
   920  	 *
   921  	 * loading every object will also make it possible to
   922  	 * load foreign objects not referenced by __.PKGDEF.
   923  	 */
   924  	var arhdr ArHdr
   925  	off := f.Offset()
   926  	for {
   927  		l := nextar(f, off, &arhdr)
   928  		if l == 0 {
   929  			break
   930  		}
   931  		if l < 0 {
   932  			Exitf("%s: malformed archive", lib.File)
   933  		}
   934  		off += l
   935  
   936  		// __.PKGDEF isn't a real Go object file, and it's
   937  		// absent in -linkobj builds anyway. Skipping it
   938  		// ensures consistency between -linkobj and normal
   939  		// build modes.
   940  		if arhdr.name == pkgdef {
   941  			continue
   942  		}
   943  
   944  		// Skip other special (non-object-file) sections that
   945  		// build tools may have added. Such sections must have
   946  		// short names so that the suffix is not truncated.
   947  		if len(arhdr.name) < 16 {
   948  			if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" {
   949  				continue
   950  			}
   951  		}
   952  
   953  		pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
   954  		l = atolwhex(arhdr.size)
   955  		ldobj(ctxt, f, lib, l, pname, lib.File)
   956  	}
   957  }
   958  
   959  type Hostobj struct {
   960  	ld     func(*Link, *bio.Reader, string, int64, string)
   961  	pkg    string
   962  	pn     string
   963  	file   string
   964  	off    int64
   965  	length int64
   966  }
   967  
   968  var hostobj []Hostobj
   969  
   970  // These packages can use internal linking mode.
   971  // Others trigger external mode.
   972  var internalpkg = []string{
   973  	"crypto/x509",
   974  	"net",
   975  	"os/user",
   976  	"runtime/cgo",
   977  	"runtime/race",
   978  	"runtime/msan",
   979  }
   980  
   981  func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
   982  	isinternal := false
   983  	for _, intpkg := range internalpkg {
   984  		if pkg == intpkg {
   985  			isinternal = true
   986  			break
   987  		}
   988  	}
   989  
   990  	// DragonFly declares errno with __thread, which results in a symbol
   991  	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
   992  	// currently know how to handle TLS relocations, hence we have to
   993  	// force external linking for any libraries that link in code that
   994  	// uses errno. This can be removed if the Go linker ever supports
   995  	// these relocation types.
   996  	if headType == objabi.Hdragonfly {
   997  		if pkg == "net" || pkg == "os/user" {
   998  			isinternal = false
   999  		}
  1000  	}
  1001  
  1002  	if !isinternal {
  1003  		externalobj = true
  1004  	}
  1005  
  1006  	hostobj = append(hostobj, Hostobj{})
  1007  	h := &hostobj[len(hostobj)-1]
  1008  	h.ld = ld
  1009  	h.pkg = pkg
  1010  	h.pn = pn
  1011  	h.file = file
  1012  	h.off = f.Offset()
  1013  	h.length = length
  1014  	return h
  1015  }
  1016  
  1017  func hostobjs(ctxt *Link) {
  1018  	if ctxt.LinkMode != LinkInternal {
  1019  		return
  1020  	}
  1021  	var h *Hostobj
  1022  
  1023  	for i := 0; i < len(hostobj); i++ {
  1024  		h = &hostobj[i]
  1025  		f, err := bio.Open(h.file)
  1026  		if err != nil {
  1027  			Exitf("cannot reopen %s: %v", h.pn, err)
  1028  		}
  1029  
  1030  		f.MustSeek(h.off, 0)
  1031  		h.ld(ctxt, f, h.pkg, h.length, h.pn)
  1032  		f.Close()
  1033  	}
  1034  }
  1035  
  1036  func hostlinksetup(ctxt *Link) {
  1037  	if ctxt.LinkMode != LinkExternal {
  1038  		return
  1039  	}
  1040  
  1041  	// For external link, record that we need to tell the external linker -s,
  1042  	// and turn off -s internally: the external linker needs the symbol
  1043  	// information for its final link.
  1044  	debug_s = *FlagS
  1045  	*FlagS = false
  1046  
  1047  	// create temporary directory and arrange cleanup
  1048  	if *flagTmpdir == "" {
  1049  		dir, err := ioutil.TempDir("", "go-link-")
  1050  		if err != nil {
  1051  			log.Fatal(err)
  1052  		}
  1053  		*flagTmpdir = dir
  1054  		ownTmpDir = true
  1055  		AtExit(func() {
  1056  			ctxt.Out.f.Close()
  1057  			os.RemoveAll(*flagTmpdir)
  1058  		})
  1059  	}
  1060  
  1061  	// change our output to temporary object file
  1062  	ctxt.Out.f.Close()
  1063  	mayberemoveoutfile()
  1064  
  1065  	p := filepath.Join(*flagTmpdir, "go.o")
  1066  	var err error
  1067  	f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
  1068  	if err != nil {
  1069  		Exitf("cannot create %s: %v", p, err)
  1070  	}
  1071  
  1072  	ctxt.Out.w = bufio.NewWriter(f)
  1073  	ctxt.Out.f = f
  1074  	ctxt.Out.off = 0
  1075  }
  1076  
  1077  // hostobjCopy creates a copy of the object files in hostobj in a
  1078  // temporary directory.
  1079  func hostobjCopy() (paths []string) {
  1080  	var wg sync.WaitGroup
  1081  	sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
  1082  	for i, h := range hostobj {
  1083  		h := h
  1084  		dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
  1085  		paths = append(paths, dst)
  1086  
  1087  		wg.Add(1)
  1088  		go func() {
  1089  			sema <- struct{}{}
  1090  			defer func() {
  1091  				<-sema
  1092  				wg.Done()
  1093  			}()
  1094  			f, err := os.Open(h.file)
  1095  			if err != nil {
  1096  				Exitf("cannot reopen %s: %v", h.pn, err)
  1097  			}
  1098  			defer f.Close()
  1099  			if _, err := f.Seek(h.off, 0); err != nil {
  1100  				Exitf("cannot seek %s: %v", h.pn, err)
  1101  			}
  1102  
  1103  			w, err := os.Create(dst)
  1104  			if err != nil {
  1105  				Exitf("cannot create %s: %v", dst, err)
  1106  			}
  1107  			if _, err := io.CopyN(w, f, h.length); err != nil {
  1108  				Exitf("cannot write %s: %v", dst, err)
  1109  			}
  1110  			if err := w.Close(); err != nil {
  1111  				Exitf("cannot close %s: %v", dst, err)
  1112  			}
  1113  		}()
  1114  	}
  1115  	wg.Wait()
  1116  	return paths
  1117  }
  1118  
  1119  // writeGDBLinkerScript creates gcc linker script file in temp
  1120  // directory. writeGDBLinkerScript returns created file path.
  1121  // The script is used to work around gcc bug
  1122  // (see https://golang.org/issue/20183 for details).
  1123  func writeGDBLinkerScript() string {
  1124  	name := "fix_debug_gdb_scripts.ld"
  1125  	path := filepath.Join(*flagTmpdir, name)
  1126  	src := `SECTIONS
  1127  {
  1128    .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
  1129    {
  1130      *(.debug_gdb_scripts)
  1131    }
  1132  }
  1133  INSERT AFTER .debug_types;
  1134  `
  1135  	err := ioutil.WriteFile(path, []byte(src), 0666)
  1136  	if err != nil {
  1137  		Errorf(nil, "WriteFile %s failed: %v", name, err)
  1138  	}
  1139  	return path
  1140  }
  1141  
  1142  // archive builds a .a archive from the hostobj object files.
  1143  func (ctxt *Link) archive() {
  1144  	if ctxt.BuildMode != BuildModeCArchive {
  1145  		return
  1146  	}
  1147  
  1148  	exitIfErrors()
  1149  
  1150  	if *flagExtar == "" {
  1151  		*flagExtar = "ar"
  1152  	}
  1153  
  1154  	mayberemoveoutfile()
  1155  
  1156  	// Force the buffer to flush here so that external
  1157  	// tools will see a complete file.
  1158  	ctxt.Out.Flush()
  1159  	if err := ctxt.Out.f.Close(); err != nil {
  1160  		Exitf("close: %v", err)
  1161  	}
  1162  	ctxt.Out.f = nil
  1163  
  1164  	argv := []string{*flagExtar, "-q", "-c", "-s"}
  1165  	if ctxt.HeadType == objabi.Haix {
  1166  		argv = append(argv, "-X64")
  1167  	}
  1168  	argv = append(argv, *flagOutfile)
  1169  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1170  	argv = append(argv, hostobjCopy()...)
  1171  
  1172  	if ctxt.Debugvlog != 0 {
  1173  		ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
  1174  	}
  1175  
  1176  	// If supported, use syscall.Exec() to invoke the archive command,
  1177  	// which should be the final remaining step needed for the link.
  1178  	// This will reduce peak RSS for the link (and speed up linking of
  1179  	// large applications), since when the archive command runs we
  1180  	// won't be holding onto all of the linker's live memory.
  1181  	if syscallExecSupported && !ownTmpDir {
  1182  		runAtExitFuncs()
  1183  		ctxt.execArchive(argv)
  1184  		panic("should not get here")
  1185  	}
  1186  
  1187  	// Otherwise invoke 'ar' in the usual way (fork + exec).
  1188  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1189  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1190  	}
  1191  }
  1192  
  1193  func (ctxt *Link) hostlink() {
  1194  	if ctxt.LinkMode != LinkExternal || nerrors > 0 {
  1195  		return
  1196  	}
  1197  	if ctxt.BuildMode == BuildModeCArchive {
  1198  		return
  1199  	}
  1200  
  1201  	var argv []string
  1202  	argv = append(argv, ctxt.extld())
  1203  	argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
  1204  
  1205  	if *FlagS || debug_s {
  1206  		if ctxt.HeadType == objabi.Hdarwin {
  1207  			// Recent versions of macOS print
  1208  			//	ld: warning: option -s is obsolete and being ignored
  1209  			// so do not pass any arguments.
  1210  		} else {
  1211  			argv = append(argv, "-s")
  1212  		}
  1213  	}
  1214  
  1215  	switch ctxt.HeadType {
  1216  	case objabi.Hdarwin:
  1217  		if machoPlatform == PLATFORM_MACOS {
  1218  			// -headerpad is incompatible with -fembed-bitcode.
  1219  			argv = append(argv, "-Wl,-headerpad,1144")
  1220  		}
  1221  		if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
  1222  			argv = append(argv, "-Wl,-flat_namespace")
  1223  		}
  1224  	case objabi.Hopenbsd:
  1225  		argv = append(argv, "-Wl,-nopie")
  1226  	case objabi.Hwindows:
  1227  		if windowsgui {
  1228  			argv = append(argv, "-mwindows")
  1229  		} else {
  1230  			argv = append(argv, "-mconsole")
  1231  		}
  1232  		// Mark as having awareness of terminal services, to avoid
  1233  		// ancient compatibility hacks.
  1234  		argv = append(argv, "-Wl,--tsaware")
  1235  
  1236  		// Enable DEP
  1237  		argv = append(argv, "-Wl,--nxcompat")
  1238  
  1239  		argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
  1240  		argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
  1241  		argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
  1242  		argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
  1243  	case objabi.Haix:
  1244  		argv = append(argv, "-pthread")
  1245  		// prevent ld to reorder .text functions to keep the same
  1246  		// first/last functions for moduledata.
  1247  		argv = append(argv, "-Wl,-bnoobjreorder")
  1248  		// mcmodel=large is needed for every gcc generated files, but
  1249  		// ld still need -bbigtoc in order to allow larger TOC.
  1250  		argv = append(argv, "-mcmodel=large")
  1251  		argv = append(argv, "-Wl,-bbigtoc")
  1252  	}
  1253  
  1254  	switch ctxt.BuildMode {
  1255  	case BuildModeExe:
  1256  		if ctxt.HeadType == objabi.Hdarwin {
  1257  			if machoPlatform == PLATFORM_MACOS {
  1258  				argv = append(argv, "-Wl,-no_pie")
  1259  				argv = append(argv, "-Wl,-pagezero_size,4000000")
  1260  			}
  1261  		}
  1262  	case BuildModePIE:
  1263  		// ELF.
  1264  		if ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix {
  1265  			if ctxt.UseRelro() {
  1266  				argv = append(argv, "-Wl,-z,relro")
  1267  			}
  1268  			argv = append(argv, "-pie")
  1269  		}
  1270  	case BuildModeCShared:
  1271  		if ctxt.HeadType == objabi.Hdarwin {
  1272  			argv = append(argv, "-dynamiclib")
  1273  			if ctxt.Arch.Family != sys.AMD64 {
  1274  				argv = append(argv, "-Wl,-read_only_relocs,suppress")
  1275  			}
  1276  		} else {
  1277  			// ELF.
  1278  			argv = append(argv, "-Wl,-Bsymbolic")
  1279  			if ctxt.UseRelro() {
  1280  				argv = append(argv, "-Wl,-z,relro")
  1281  			}
  1282  			argv = append(argv, "-shared")
  1283  			if ctxt.HeadType != objabi.Hwindows {
  1284  				// Pass -z nodelete to mark the shared library as
  1285  				// non-closeable: a dlclose will do nothing.
  1286  				argv = append(argv, "-Wl,-z,nodelete")
  1287  			}
  1288  		}
  1289  	case BuildModeShared:
  1290  		if ctxt.UseRelro() {
  1291  			argv = append(argv, "-Wl,-z,relro")
  1292  		}
  1293  		argv = append(argv, "-shared")
  1294  	case BuildModePlugin:
  1295  		if ctxt.HeadType == objabi.Hdarwin {
  1296  			argv = append(argv, "-dynamiclib")
  1297  		} else {
  1298  			if ctxt.UseRelro() {
  1299  				argv = append(argv, "-Wl,-z,relro")
  1300  			}
  1301  			argv = append(argv, "-shared")
  1302  		}
  1303  	}
  1304  
  1305  	if ctxt.IsELF && ctxt.DynlinkingGo() {
  1306  		// We force all symbol resolution to be done at program startup
  1307  		// because lazy PLT resolution can use large amounts of stack at
  1308  		// times we cannot allow it to do so.
  1309  		argv = append(argv, "-Wl,-znow")
  1310  
  1311  		// Do not let the host linker generate COPY relocations. These
  1312  		// can move symbols out of sections that rely on stable offsets
  1313  		// from the beginning of the section (like sym.STYPE).
  1314  		argv = append(argv, "-Wl,-znocopyreloc")
  1315  
  1316  		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && objabi.GOOS == "linux" {
  1317  			// On ARM, the GNU linker will generate COPY relocations
  1318  			// even with -znocopyreloc set.
  1319  			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
  1320  			//
  1321  			// On ARM64, the GNU linker will fail instead of
  1322  			// generating COPY relocations.
  1323  			//
  1324  			// In both cases, switch to gold.
  1325  			argv = append(argv, "-fuse-ld=gold")
  1326  
  1327  			// If gold is not installed, gcc will silently switch
  1328  			// back to ld.bfd. So we parse the version information
  1329  			// and provide a useful error if gold is missing.
  1330  			cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version")
  1331  			if out, err := cmd.CombinedOutput(); err == nil {
  1332  				if !bytes.Contains(out, []byte("GNU gold")) {
  1333  					log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
  1334  				}
  1335  			}
  1336  		}
  1337  	}
  1338  
  1339  	if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" {
  1340  		// Switch to ld.bfd on freebsd/arm64.
  1341  		argv = append(argv, "-fuse-ld=bfd")
  1342  
  1343  		// Provide a useful error if ld.bfd is missing.
  1344  		cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version")
  1345  		if out, err := cmd.CombinedOutput(); err == nil {
  1346  			if !bytes.Contains(out, []byte("GNU ld")) {
  1347  				log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
  1348  			}
  1349  		}
  1350  	}
  1351  
  1352  	if ctxt.IsELF && len(buildinfo) > 0 {
  1353  		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
  1354  	}
  1355  
  1356  	// On Windows, given -o foo, GCC will append ".exe" to produce
  1357  	// "foo.exe".  We have decided that we want to honor the -o
  1358  	// option. To make this work, we append a '.' so that GCC
  1359  	// will decide that the file already has an extension. We
  1360  	// only want to do this when producing a Windows output file
  1361  	// on a Windows host.
  1362  	outopt := *flagOutfile
  1363  	if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
  1364  		outopt += "."
  1365  	}
  1366  	argv = append(argv, "-o")
  1367  	argv = append(argv, outopt)
  1368  
  1369  	if rpath.val != "" {
  1370  		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
  1371  	}
  1372  
  1373  	// Force global symbols to be exported for dlopen, etc.
  1374  	if ctxt.IsELF {
  1375  		argv = append(argv, "-rdynamic")
  1376  	}
  1377  	if ctxt.HeadType == objabi.Haix {
  1378  		fileName := xcoffCreateExportFile(ctxt)
  1379  		argv = append(argv, "-Wl,-bE:"+fileName)
  1380  	}
  1381  
  1382  	if strings.Contains(argv[0], "clang") {
  1383  		argv = append(argv, "-Qunused-arguments")
  1384  	}
  1385  
  1386  	const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
  1387  	if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) {
  1388  		argv = append(argv, compressDWARF)
  1389  	}
  1390  
  1391  	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1392  	argv = append(argv, hostobjCopy()...)
  1393  	if ctxt.HeadType == objabi.Haix {
  1394  		// We want to have C files after Go files to remove
  1395  		// trampolines csects made by ld.
  1396  		argv = append(argv, "-nostartfiles")
  1397  		argv = append(argv, "/lib/crt0_64.o")
  1398  
  1399  		extld := ctxt.extld()
  1400  		// Get starting files.
  1401  		getPathFile := func(file string) string {
  1402  			args := []string{"-maix64", "--print-file-name=" + file}
  1403  			out, err := exec.Command(extld, args...).CombinedOutput()
  1404  			if err != nil {
  1405  				log.Fatalf("running %s failed: %v\n%s", extld, err, out)
  1406  			}
  1407  			return strings.Trim(string(out), "\n")
  1408  		}
  1409  		argv = append(argv, getPathFile("crtcxa.o"))
  1410  		argv = append(argv, getPathFile("crtdbase.o"))
  1411  	}
  1412  
  1413  	if ctxt.linkShared {
  1414  		seenDirs := make(map[string]bool)
  1415  		seenLibs := make(map[string]bool)
  1416  		addshlib := func(path string) {
  1417  			dir, base := filepath.Split(path)
  1418  			if !seenDirs[dir] {
  1419  				argv = append(argv, "-L"+dir)
  1420  				if !rpath.set {
  1421  					argv = append(argv, "-Wl,-rpath="+dir)
  1422  				}
  1423  				seenDirs[dir] = true
  1424  			}
  1425  			base = strings.TrimSuffix(base, ".so")
  1426  			base = strings.TrimPrefix(base, "lib")
  1427  			if !seenLibs[base] {
  1428  				argv = append(argv, "-l"+base)
  1429  				seenLibs[base] = true
  1430  			}
  1431  		}
  1432  		for _, shlib := range ctxt.Shlibs {
  1433  			addshlib(shlib.Path)
  1434  			for _, dep := range shlib.Deps {
  1435  				if dep == "" {
  1436  					continue
  1437  				}
  1438  				libpath := findshlib(ctxt, dep)
  1439  				if libpath != "" {
  1440  					addshlib(libpath)
  1441  				}
  1442  			}
  1443  		}
  1444  	}
  1445  
  1446  	// clang, unlike GCC, passes -rdynamic to the linker
  1447  	// even when linking with -static, causing a linker
  1448  	// error when using GNU ld. So take out -rdynamic if
  1449  	// we added it. We do it in this order, rather than
  1450  	// only adding -rdynamic later, so that -*extldflags
  1451  	// can override -rdynamic without using -static.
  1452  	checkStatic := func(arg string) {
  1453  		if ctxt.IsELF && arg == "-static" {
  1454  			for i := range argv {
  1455  				if argv[i] == "-rdynamic" {
  1456  					argv[i] = "-static"
  1457  				}
  1458  			}
  1459  		}
  1460  	}
  1461  
  1462  	for _, p := range ldflag {
  1463  		argv = append(argv, p)
  1464  		checkStatic(p)
  1465  	}
  1466  
  1467  	// When building a program with the default -buildmode=exe the
  1468  	// gc compiler generates code requires DT_TEXTREL in a
  1469  	// position independent executable (PIE). On systems where the
  1470  	// toolchain creates PIEs by default, and where DT_TEXTREL
  1471  	// does not work, the resulting programs will not run. See
  1472  	// issue #17847. To avoid this problem pass -no-pie to the
  1473  	// toolchain if it is supported.
  1474  	if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
  1475  		// GCC uses -no-pie, clang uses -nopie.
  1476  		for _, nopie := range []string{"-no-pie", "-nopie"} {
  1477  			if linkerFlagSupported(argv[0], nopie) {
  1478  				argv = append(argv, nopie)
  1479  				break
  1480  			}
  1481  		}
  1482  	}
  1483  
  1484  	for _, p := range strings.Fields(*flagExtldflags) {
  1485  		argv = append(argv, p)
  1486  		checkStatic(p)
  1487  	}
  1488  	if ctxt.HeadType == objabi.Hwindows {
  1489  		// use gcc linker script to work around gcc bug
  1490  		// (see https://golang.org/issue/20183 for details).
  1491  		p := writeGDBLinkerScript()
  1492  		argv = append(argv, "-Wl,-T,"+p)
  1493  		// libmingw32 and libmingwex have some inter-dependencies,
  1494  		// so must use linker groups.
  1495  		argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
  1496  		argv = append(argv, peimporteddlls()...)
  1497  	}
  1498  
  1499  	if ctxt.Debugvlog != 0 {
  1500  		ctxt.Logf("host link:")
  1501  		for _, v := range argv {
  1502  			ctxt.Logf(" %q", v)
  1503  		}
  1504  		ctxt.Logf("\n")
  1505  	}
  1506  
  1507  	out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
  1508  	if err != nil {
  1509  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1510  	}
  1511  
  1512  	// Filter out useless linker warnings caused by bugs outside Go.
  1513  	// See also cmd/go/internal/work/exec.go's gccld method.
  1514  	var save [][]byte
  1515  	var skipLines int
  1516  	for _, line := range bytes.SplitAfter(out, []byte("\n")) {
  1517  		// golang.org/issue/26073 - Apple Xcode bug
  1518  		if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
  1519  			continue
  1520  		}
  1521  
  1522  		if skipLines > 0 {
  1523  			skipLines--
  1524  			continue
  1525  		}
  1526  
  1527  		// Remove TOC overflow warning on AIX.
  1528  		if bytes.Contains(line, []byte("ld: 0711-783")) {
  1529  			skipLines = 2
  1530  			continue
  1531  		}
  1532  
  1533  		save = append(save, line)
  1534  	}
  1535  	out = bytes.Join(save, nil)
  1536  
  1537  	if len(out) > 0 {
  1538  		// always print external output even if the command is successful, so that we don't
  1539  		// swallow linker warnings (see https://golang.org/issue/17935).
  1540  		ctxt.Logf("%s", out)
  1541  	}
  1542  
  1543  	if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
  1544  		dsym := filepath.Join(*flagTmpdir, "go.dwarf")
  1545  		if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
  1546  			Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
  1547  		}
  1548  		// Skip combining if `dsymutil` didn't generate a file. See #11994.
  1549  		if _, err := os.Stat(dsym); os.IsNotExist(err) {
  1550  			return
  1551  		}
  1552  		// For os.Rename to work reliably, must be in same directory as outfile.
  1553  		combinedOutput := *flagOutfile + "~"
  1554  		exef, err := os.Open(*flagOutfile)
  1555  		if err != nil {
  1556  			Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1557  		}
  1558  		defer exef.Close()
  1559  		exem, err := macho.NewFile(exef)
  1560  		if err != nil {
  1561  			Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
  1562  		}
  1563  		// Only macOS supports unmapped segments such as our __DWARF segment.
  1564  		if machoPlatform == PLATFORM_MACOS {
  1565  			if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
  1566  				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1567  			}
  1568  			os.Remove(*flagOutfile)
  1569  			if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
  1570  				Exitf("%s: %v", os.Args[0], err)
  1571  			}
  1572  		}
  1573  	}
  1574  }
  1575  
  1576  var createTrivialCOnce sync.Once
  1577  
  1578  func linkerFlagSupported(linker, flag string) bool {
  1579  	createTrivialCOnce.Do(func() {
  1580  		src := filepath.Join(*flagTmpdir, "trivial.c")
  1581  		if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
  1582  			Errorf(nil, "WriteFile trivial.c failed: %v", err)
  1583  		}
  1584  	})
  1585  
  1586  	flagsWithNextArgSkip := []string{
  1587  		"-F",
  1588  		"-l",
  1589  		"-L",
  1590  		"-framework",
  1591  		"-Wl,-framework",
  1592  		"-Wl,-rpath",
  1593  		"-Wl,-undefined",
  1594  	}
  1595  	flagsWithNextArgKeep := []string{
  1596  		"-arch",
  1597  		"-isysroot",
  1598  		"--sysroot",
  1599  		"-target",
  1600  	}
  1601  	prefixesToKeep := []string{
  1602  		"-f",
  1603  		"-m",
  1604  		"-p",
  1605  		"-Wl,",
  1606  		"-arch",
  1607  		"-isysroot",
  1608  		"--sysroot",
  1609  		"-target",
  1610  	}
  1611  
  1612  	var flags []string
  1613  	keep := false
  1614  	skip := false
  1615  	extldflags := strings.Fields(*flagExtldflags)
  1616  	for _, f := range append(extldflags, ldflag...) {
  1617  		if keep {
  1618  			flags = append(flags, f)
  1619  			keep = false
  1620  		} else if skip {
  1621  			skip = false
  1622  		} else if f == "" || f[0] != '-' {
  1623  		} else if contains(flagsWithNextArgSkip, f) {
  1624  			skip = true
  1625  		} else if contains(flagsWithNextArgKeep, f) {
  1626  			flags = append(flags, f)
  1627  			keep = true
  1628  		} else {
  1629  			for _, p := range prefixesToKeep {
  1630  				if strings.HasPrefix(f, p) {
  1631  					flags = append(flags, f)
  1632  					break
  1633  				}
  1634  			}
  1635  		}
  1636  	}
  1637  
  1638  	flags = append(flags, flag, "trivial.c")
  1639  
  1640  	cmd := exec.Command(linker, flags...)
  1641  	cmd.Dir = *flagTmpdir
  1642  	cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
  1643  	out, err := cmd.CombinedOutput()
  1644  	// GCC says "unrecognized command line option ‘-no-pie’"
  1645  	// clang says "unknown argument: '-no-pie'"
  1646  	return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
  1647  }
  1648  
  1649  // hostlinkArchArgs returns arguments to pass to the external linker
  1650  // based on the architecture.
  1651  func hostlinkArchArgs(arch *sys.Arch) []string {
  1652  	switch arch.Family {
  1653  	case sys.I386:
  1654  		return []string{"-m32"}
  1655  	case sys.AMD64, sys.S390X:
  1656  		return []string{"-m64"}
  1657  	case sys.ARM:
  1658  		return []string{"-marm"}
  1659  	case sys.ARM64:
  1660  		// nothing needed
  1661  	case sys.MIPS64:
  1662  		return []string{"-mabi=64"}
  1663  	case sys.MIPS:
  1664  		return []string{"-mabi=32"}
  1665  	case sys.PPC64:
  1666  		if objabi.GOOS == "aix" {
  1667  			return []string{"-maix64"}
  1668  		} else {
  1669  			return []string{"-m64"}
  1670  		}
  1671  
  1672  	}
  1673  	return nil
  1674  }
  1675  
  1676  // ldobj loads an input object. If it is a host object (an object
  1677  // compiled by a non-Go compiler) it returns the Hostobj pointer. If
  1678  // it is a Go object, it returns nil.
  1679  func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
  1680  	pkg := objabi.PathToPrefix(lib.Pkg)
  1681  
  1682  	eof := f.Offset() + length
  1683  	start := f.Offset()
  1684  	c1 := bgetc(f)
  1685  	c2 := bgetc(f)
  1686  	c3 := bgetc(f)
  1687  	c4 := bgetc(f)
  1688  	f.MustSeek(start, 0)
  1689  
  1690  	unit := &sym.CompilationUnit{Lib: lib}
  1691  	lib.Units = append(lib.Units, unit)
  1692  
  1693  	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
  1694  	if magic == 0x7f454c46 { // \x7F E L F
  1695  		if *flagNewobj {
  1696  			ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1697  				textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
  1698  				if err != nil {
  1699  					Errorf(nil, "%v", err)
  1700  					return
  1701  				}
  1702  				ehdr.flags = flags
  1703  				ctxt.Textp = append(ctxt.Textp, textp...)
  1704  			}
  1705  			return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
  1706  		} else {
  1707  			ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1708  				textp, flags, err := loadelf.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
  1709  				if err != nil {
  1710  					Errorf(nil, "%v", err)
  1711  					return
  1712  				}
  1713  				ehdr.flags = flags
  1714  				ctxt.Textp = append(ctxt.Textp, textp...)
  1715  			}
  1716  			return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
  1717  		}
  1718  	}
  1719  
  1720  	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
  1721  		if *flagNewobj {
  1722  			ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1723  				textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1724  				if err != nil {
  1725  					Errorf(nil, "%v", err)
  1726  					return
  1727  				}
  1728  				ctxt.Textp = append(ctxt.Textp, textp...)
  1729  			}
  1730  			return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
  1731  		} else {
  1732  			ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1733  				textp, err := loadmacho.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1734  				if err != nil {
  1735  					Errorf(nil, "%v", err)
  1736  					return
  1737  				}
  1738  				ctxt.Textp = append(ctxt.Textp, textp...)
  1739  			}
  1740  			return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
  1741  		}
  1742  	}
  1743  
  1744  	if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
  1745  		if *flagNewobj {
  1746  			ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1747  				textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1748  				if err != nil {
  1749  					Errorf(nil, "%v", err)
  1750  					return
  1751  				}
  1752  				if rsrc != nil {
  1753  					setpersrc(ctxt, rsrc)
  1754  				}
  1755  				ctxt.Textp = append(ctxt.Textp, textp...)
  1756  			}
  1757  			return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
  1758  		} else {
  1759  			ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1760  				textp, rsrc, err := loadpe.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1761  				if err != nil {
  1762  					Errorf(nil, "%v", err)
  1763  					return
  1764  				}
  1765  				if rsrc != nil {
  1766  					setpersrc(ctxt, rsrc)
  1767  				}
  1768  				ctxt.Textp = append(ctxt.Textp, textp...)
  1769  			}
  1770  			return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
  1771  		}
  1772  	}
  1773  
  1774  	if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
  1775  		if *flagNewobj {
  1776  			ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1777  				textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1778  				if err != nil {
  1779  					Errorf(nil, "%v", err)
  1780  					return
  1781  				}
  1782  				ctxt.Textp = append(ctxt.Textp, textp...)
  1783  			}
  1784  			return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
  1785  		} else {
  1786  			ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1787  				textp, err := loadxcoff.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1788  				if err != nil {
  1789  					Errorf(nil, "%v", err)
  1790  					return
  1791  				}
  1792  				ctxt.Textp = append(ctxt.Textp, textp...)
  1793  			}
  1794  			return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
  1795  		}
  1796  	}
  1797  
  1798  	/* check the header */
  1799  	line, err := f.ReadString('\n')
  1800  	if err != nil {
  1801  		Errorf(nil, "truncated object file: %s: %v", pn, err)
  1802  		return nil
  1803  	}
  1804  
  1805  	if !strings.HasPrefix(line, "go object ") {
  1806  		if strings.HasSuffix(pn, ".go") {
  1807  			Exitf("%s: uncompiled .go source file", pn)
  1808  			return nil
  1809  		}
  1810  
  1811  		if line == ctxt.Arch.Name {
  1812  			// old header format: just $GOOS
  1813  			Errorf(nil, "%s: stale object file", pn)
  1814  			return nil
  1815  		}
  1816  
  1817  		Errorf(nil, "%s: not an object file", pn)
  1818  		return nil
  1819  	}
  1820  
  1821  	// First, check that the basic GOOS, GOARCH, and Version match.
  1822  	t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
  1823  
  1824  	line = strings.TrimRight(line, "\n")
  1825  	if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
  1826  		Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
  1827  		return nil
  1828  	}
  1829  
  1830  	// Second, check that longer lines match each other exactly,
  1831  	// so that the Go compiler and write additional information
  1832  	// that must be the same from run to run.
  1833  	if len(line) >= len(t)+10 {
  1834  		if theline == "" {
  1835  			theline = line[10:]
  1836  		} else if theline != line[10:] {
  1837  			Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
  1838  			return nil
  1839  		}
  1840  	}
  1841  
  1842  	// Skip over exports and other info -- ends with \n!\n.
  1843  	//
  1844  	// Note: It's possible for "\n!\n" to appear within the binary
  1845  	// package export data format. To avoid truncating the package
  1846  	// definition prematurely (issue 21703), we keep track of
  1847  	// how many "$$" delimiters we've seen.
  1848  
  1849  	import0 := f.Offset()
  1850  
  1851  	c1 = '\n' // the last line ended in \n
  1852  	c2 = bgetc(f)
  1853  	c3 = bgetc(f)
  1854  	markers := 0
  1855  	for {
  1856  		if c1 == '\n' {
  1857  			if markers%2 == 0 && c2 == '!' && c3 == '\n' {
  1858  				break
  1859  			}
  1860  			if c2 == '$' && c3 == '$' {
  1861  				markers++
  1862  			}
  1863  		}
  1864  
  1865  		c1 = c2
  1866  		c2 = c3
  1867  		c3 = bgetc(f)
  1868  		if c3 == -1 {
  1869  			Errorf(nil, "truncated object file: %s", pn)
  1870  			return nil
  1871  		}
  1872  	}
  1873  
  1874  	import1 := f.Offset()
  1875  
  1876  	f.MustSeek(import0, 0)
  1877  	ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
  1878  	f.MustSeek(import1, 0)
  1879  
  1880  	flags := 0
  1881  	switch *FlagStrictDups {
  1882  	case 0:
  1883  		break
  1884  	case 1:
  1885  		flags = objfile.StrictDupsWarnFlag
  1886  	case 2:
  1887  		flags = objfile.StrictDupsErrFlag
  1888  	default:
  1889  		log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
  1890  	}
  1891  	var c int
  1892  	if *flagNewobj {
  1893  		ctxt.loader.Preload(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
  1894  	} else {
  1895  		c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
  1896  	}
  1897  	strictDupMsgCount += c
  1898  	addImports(ctxt, lib, pn)
  1899  	return nil
  1900  }
  1901  
  1902  func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
  1903  	data := make([]byte, sym.Size)
  1904  	sect := f.Sections[sym.Section]
  1905  	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  1906  		Errorf(nil, "reading %s from non-data section", sym.Name)
  1907  	}
  1908  	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  1909  	if uint64(n) != sym.Size {
  1910  		Errorf(nil, "reading contents of %s: %v", sym.Name, err)
  1911  	}
  1912  	return data
  1913  }
  1914  
  1915  func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  1916  	data := make([]byte, Rnd(int64(sz), 4))
  1917  	_, err := io.ReadFull(r, data)
  1918  	if err != nil {
  1919  		return nil, err
  1920  	}
  1921  	data = data[:sz]
  1922  	return data, nil
  1923  }
  1924  
  1925  func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  1926  	for _, sect := range f.Sections {
  1927  		if sect.Type != elf.SHT_NOTE {
  1928  			continue
  1929  		}
  1930  		r := sect.Open()
  1931  		for {
  1932  			var namesize, descsize, noteType int32
  1933  			err := binary.Read(r, f.ByteOrder, &namesize)
  1934  			if err != nil {
  1935  				if err == io.EOF {
  1936  					break
  1937  				}
  1938  				return nil, fmt.Errorf("read namesize failed: %v", err)
  1939  			}
  1940  			err = binary.Read(r, f.ByteOrder, &descsize)
  1941  			if err != nil {
  1942  				return nil, fmt.Errorf("read descsize failed: %v", err)
  1943  			}
  1944  			err = binary.Read(r, f.ByteOrder, &noteType)
  1945  			if err != nil {
  1946  				return nil, fmt.Errorf("read type failed: %v", err)
  1947  			}
  1948  			noteName, err := readwithpad(r, namesize)
  1949  			if err != nil {
  1950  				return nil, fmt.Errorf("read name failed: %v", err)
  1951  			}
  1952  			desc, err := readwithpad(r, descsize)
  1953  			if err != nil {
  1954  				return nil, fmt.Errorf("read desc failed: %v", err)
  1955  			}
  1956  			if string(name) == string(noteName) && typ == noteType {
  1957  				return desc, nil
  1958  			}
  1959  		}
  1960  	}
  1961  	return nil, nil
  1962  }
  1963  
  1964  func findshlib(ctxt *Link, shlib string) string {
  1965  	if filepath.IsAbs(shlib) {
  1966  		return shlib
  1967  	}
  1968  	for _, libdir := range ctxt.Libdir {
  1969  		libpath := filepath.Join(libdir, shlib)
  1970  		if _, err := os.Stat(libpath); err == nil {
  1971  			return libpath
  1972  		}
  1973  	}
  1974  	Errorf(nil, "cannot find shared library: %s", shlib)
  1975  	return ""
  1976  }
  1977  
  1978  func ldshlibsyms(ctxt *Link, shlib string) {
  1979  	var libpath string
  1980  	if filepath.IsAbs(shlib) {
  1981  		libpath = shlib
  1982  		shlib = filepath.Base(shlib)
  1983  	} else {
  1984  		libpath = findshlib(ctxt, shlib)
  1985  		if libpath == "" {
  1986  			return
  1987  		}
  1988  	}
  1989  	for _, processedlib := range ctxt.Shlibs {
  1990  		if processedlib.Path == libpath {
  1991  			return
  1992  		}
  1993  	}
  1994  	if ctxt.Debugvlog > 1 {
  1995  		ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
  1996  	}
  1997  
  1998  	f, err := elf.Open(libpath)
  1999  	if err != nil {
  2000  		Errorf(nil, "cannot open shared library: %s", libpath)
  2001  		return
  2002  	}
  2003  	defer f.Close()
  2004  
  2005  	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  2006  	if err != nil {
  2007  		Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
  2008  		return
  2009  	}
  2010  
  2011  	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  2012  	if err != nil {
  2013  		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
  2014  		return
  2015  	}
  2016  	var deps []string
  2017  	for _, dep := range strings.Split(string(depsbytes), "\n") {
  2018  		if dep == "" {
  2019  			continue
  2020  		}
  2021  		if !filepath.IsAbs(dep) {
  2022  			// If the dep can be interpreted as a path relative to the shlib
  2023  			// in which it was found, do that. Otherwise, we will leave it
  2024  			// to be resolved by libdir lookup.
  2025  			abs := filepath.Join(filepath.Dir(libpath), dep)
  2026  			if _, err := os.Stat(abs); err == nil {
  2027  				dep = abs
  2028  			}
  2029  		}
  2030  		deps = append(deps, dep)
  2031  	}
  2032  
  2033  	syms, err := f.DynamicSymbols()
  2034  	if err != nil {
  2035  		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
  2036  		return
  2037  	}
  2038  	gcdataLocations := make(map[uint64]*sym.Symbol)
  2039  	for _, elfsym := range syms {
  2040  		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  2041  			continue
  2042  		}
  2043  
  2044  		// Symbols whose names start with "type." are compiler
  2045  		// generated, so make functions with that prefix internal.
  2046  		ver := 0
  2047  		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
  2048  			ver = sym.SymVerABIInternal
  2049  		}
  2050  
  2051  		var lsym *sym.Symbol
  2052  		if *flagNewobj {
  2053  			i := ctxt.loader.AddExtSym(elfsym.Name, ver)
  2054  			if i == 0 {
  2055  				continue
  2056  			}
  2057  			lsym = ctxt.Syms.Newsym(elfsym.Name, ver)
  2058  			ctxt.loader.Syms[i] = lsym
  2059  		} else {
  2060  			lsym = ctxt.Syms.Lookup(elfsym.Name, ver)
  2061  		}
  2062  		// Because loadlib above loads all .a files before loading any shared
  2063  		// libraries, any non-dynimport symbols we find that duplicate symbols
  2064  		// already loaded should be ignored (the symbols from the .a files
  2065  		// "win").
  2066  		if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
  2067  			continue
  2068  		}
  2069  		lsym.Type = sym.SDYNIMPORT
  2070  		lsym.SetElfType(elf.ST_TYPE(elfsym.Info))
  2071  		lsym.Size = int64(elfsym.Size)
  2072  		if elfsym.Section != elf.SHN_UNDEF {
  2073  			// Set .File for the library that actually defines the symbol.
  2074  			lsym.File = libpath
  2075  			// The decodetype_* functions in decodetype.go need access to
  2076  			// the type data.
  2077  			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
  2078  				lsym.P = readelfsymboldata(ctxt, f, &elfsym)
  2079  				gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
  2080  			}
  2081  		}
  2082  		// For function symbols, we don't know what ABI is
  2083  		// available, so alias it under both ABIs.
  2084  		//
  2085  		// TODO(austin): This is almost certainly wrong once
  2086  		// the ABIs are actually different. We might have to
  2087  		// mangle Go function names in the .so to include the
  2088  		// ABI.
  2089  		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
  2090  			var alias *sym.Symbol
  2091  			if *flagNewobj {
  2092  				i := ctxt.loader.AddExtSym(elfsym.Name, sym.SymVerABIInternal)
  2093  				if i == 0 {
  2094  					continue
  2095  				}
  2096  				alias = ctxt.Syms.Newsym(elfsym.Name, sym.SymVerABIInternal)
  2097  				ctxt.loader.Syms[i] = alias
  2098  			} else {
  2099  				alias = ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal)
  2100  			}
  2101  			if alias.Type != 0 {
  2102  				continue
  2103  			}
  2104  			alias.Type = sym.SABIALIAS
  2105  			alias.R = []sym.Reloc{{Sym: lsym}}
  2106  		}
  2107  	}
  2108  	gcdataAddresses := make(map[*sym.Symbol]uint64)
  2109  	if ctxt.Arch.Family == sys.ARM64 {
  2110  		for _, sect := range f.Sections {
  2111  			if sect.Type == elf.SHT_RELA {
  2112  				var rela elf.Rela64
  2113  				rdr := sect.Open()
  2114  				for {
  2115  					err := binary.Read(rdr, f.ByteOrder, &rela)
  2116  					if err == io.EOF {
  2117  						break
  2118  					} else if err != nil {
  2119  						Errorf(nil, "reading relocation failed %v", err)
  2120  						return
  2121  					}
  2122  					t := elf.R_AARCH64(rela.Info & 0xffff)
  2123  					if t != elf.R_AARCH64_RELATIVE {
  2124  						continue
  2125  					}
  2126  					if lsym, ok := gcdataLocations[rela.Off]; ok {
  2127  						gcdataAddresses[lsym] = uint64(rela.Addend)
  2128  					}
  2129  				}
  2130  			}
  2131  		}
  2132  	}
  2133  
  2134  	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
  2135  }
  2136  
  2137  func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
  2138  	sect := new(sym.Section)
  2139  	sect.Rwx = uint8(rwx)
  2140  	sect.Name = name
  2141  	sect.Seg = seg
  2142  	sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
  2143  	seg.Sections = append(seg.Sections, sect)
  2144  	return sect
  2145  }
  2146  
  2147  type chain struct {
  2148  	sym   *sym.Symbol
  2149  	up    *chain
  2150  	limit int // limit on entry to sym
  2151  }
  2152  
  2153  var morestack *sym.Symbol
  2154  
  2155  // TODO: Record enough information in new object files to
  2156  // allow stack checks here.
  2157  
  2158  func haslinkregister(ctxt *Link) bool {
  2159  	return ctxt.FixedFrameSize() != 0
  2160  }
  2161  
  2162  func callsize(ctxt *Link) int {
  2163  	if haslinkregister(ctxt) {
  2164  		return 0
  2165  	}
  2166  	return ctxt.Arch.RegSize
  2167  }
  2168  
  2169  func (ctxt *Link) dostkcheck() {
  2170  	var ch chain
  2171  
  2172  	morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
  2173  
  2174  	// Every splitting function ensures that there are at least StackLimit
  2175  	// bytes available below SP when the splitting prologue finishes.
  2176  	// If the splitting function calls F, then F begins execution with
  2177  	// at least StackLimit - callsize() bytes available.
  2178  	// Check that every function behaves correctly with this amount
  2179  	// of stack, following direct calls in order to piece together chains
  2180  	// of non-splitting functions.
  2181  	ch.up = nil
  2182  
  2183  	ch.limit = objabi.StackLimit - callsize(ctxt)
  2184  	if objabi.GOARCH == "arm64" {
  2185  		// need extra 8 bytes below SP to save FP
  2186  		ch.limit -= 8
  2187  	}
  2188  
  2189  	// Check every function, but do the nosplit functions in a first pass,
  2190  	// to make the printed failure chains as short as possible.
  2191  	for _, s := range ctxt.Textp {
  2192  		// runtime.racesymbolizethunk is called from gcc-compiled C
  2193  		// code running on the operating system thread stack.
  2194  		// It uses more than the usual amount of stack but that's okay.
  2195  		if s.Name == "runtime.racesymbolizethunk" {
  2196  			continue
  2197  		}
  2198  
  2199  		if s.Attr.NoSplit() {
  2200  			ch.sym = s
  2201  			stkcheck(ctxt, &ch, 0)
  2202  		}
  2203  	}
  2204  
  2205  	for _, s := range ctxt.Textp {
  2206  		if !s.Attr.NoSplit() {
  2207  			ch.sym = s
  2208  			stkcheck(ctxt, &ch, 0)
  2209  		}
  2210  	}
  2211  }
  2212  
  2213  func stkcheck(ctxt *Link, up *chain, depth int) int {
  2214  	limit := up.limit
  2215  	s := up.sym
  2216  
  2217  	// Don't duplicate work: only need to consider each
  2218  	// function at top of safe zone once.
  2219  	top := limit == objabi.StackLimit-callsize(ctxt)
  2220  	if top {
  2221  		if s.Attr.StackCheck() {
  2222  			return 0
  2223  		}
  2224  		s.Attr |= sym.AttrStackCheck
  2225  	}
  2226  
  2227  	if depth > 500 {
  2228  		Errorf(s, "nosplit stack check too deep")
  2229  		stkbroke(ctxt, up, 0)
  2230  		return -1
  2231  	}
  2232  
  2233  	if s.Attr.External() || s.FuncInfo == nil {
  2234  		// external function.
  2235  		// should never be called directly.
  2236  		// onlyctxt.Diagnose the direct caller.
  2237  		// TODO(mwhudson): actually think about this.
  2238  		// TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack.
  2239  		// See the trampolines in src/runtime/sys_darwin_$ARCH.go.
  2240  		if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
  2241  			ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
  2242  			//Errorf(s, "call to external function")
  2243  		}
  2244  		return -1
  2245  	}
  2246  
  2247  	if limit < 0 {
  2248  		stkbroke(ctxt, up, limit)
  2249  		return -1
  2250  	}
  2251  
  2252  	// morestack looks like it calls functions,
  2253  	// but it switches the stack pointer first.
  2254  	if s == morestack {
  2255  		return 0
  2256  	}
  2257  
  2258  	var ch chain
  2259  	ch.up = up
  2260  
  2261  	if !s.Attr.NoSplit() {
  2262  		// Ensure we have enough stack to call morestack.
  2263  		ch.limit = limit - callsize(ctxt)
  2264  		ch.sym = morestack
  2265  		if stkcheck(ctxt, &ch, depth+1) < 0 {
  2266  			return -1
  2267  		}
  2268  		if !top {
  2269  			return 0
  2270  		}
  2271  		// Raise limit to allow frame.
  2272  		locals := int32(0)
  2273  		if s.FuncInfo != nil {
  2274  			locals = s.FuncInfo.Locals
  2275  		}
  2276  		limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize())
  2277  	}
  2278  
  2279  	// Walk through sp adjustments in function, consuming relocs.
  2280  	ri := 0
  2281  
  2282  	endr := len(s.R)
  2283  	var ch1 chain
  2284  	pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
  2285  	var r *sym.Reloc
  2286  	for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
  2287  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  2288  
  2289  		// Check stack size in effect for this span.
  2290  		if int32(limit)-pcsp.Value < 0 {
  2291  			stkbroke(ctxt, up, int(int32(limit)-pcsp.Value))
  2292  			return -1
  2293  		}
  2294  
  2295  		// Process calls in this span.
  2296  		for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ {
  2297  			r = &s.R[ri]
  2298  			switch {
  2299  			case r.Type.IsDirectCall():
  2300  				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
  2301  				ch.sym = r.Sym
  2302  				if stkcheck(ctxt, &ch, depth+1) < 0 {
  2303  					return -1
  2304  				}
  2305  
  2306  			// Indirect call. Assume it is a call to a splitting function,
  2307  			// so we have to make sure it can call morestack.
  2308  			// Arrange the data structures to report both calls, so that
  2309  			// if there is an error, stkprint shows all the steps involved.
  2310  			case r.Type == objabi.R_CALLIND:
  2311  				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
  2312  				ch.sym = nil
  2313  				ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
  2314  				ch1.up = &ch
  2315  				ch1.sym = morestack
  2316  				if stkcheck(ctxt, &ch1, depth+2) < 0 {
  2317  					return -1
  2318  				}
  2319  			}
  2320  		}
  2321  	}
  2322  
  2323  	return 0
  2324  }
  2325  
  2326  func stkbroke(ctxt *Link, ch *chain, limit int) {
  2327  	Errorf(ch.sym, "nosplit stack overflow")
  2328  	stkprint(ctxt, ch, limit)
  2329  }
  2330  
  2331  func stkprint(ctxt *Link, ch *chain, limit int) {
  2332  	var name string
  2333  
  2334  	if ch.sym != nil {
  2335  		name = ch.sym.Name
  2336  		if ch.sym.Attr.NoSplit() {
  2337  			name += " (nosplit)"
  2338  		}
  2339  	} else {
  2340  		name = "function pointer"
  2341  	}
  2342  
  2343  	if ch.up == nil {
  2344  		// top of chain.  ch->sym != nil.
  2345  		if ch.sym.Attr.NoSplit() {
  2346  			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  2347  		} else {
  2348  			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  2349  		}
  2350  	} else {
  2351  		stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
  2352  		if !haslinkregister(ctxt) {
  2353  			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  2354  		}
  2355  	}
  2356  
  2357  	if ch.limit != limit {
  2358  		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  2359  	}
  2360  }
  2361  
  2362  func usage() {
  2363  	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  2364  	objabi.Flagprint(os.Stderr)
  2365  	Exit(2)
  2366  }
  2367  
  2368  type SymbolType int8
  2369  
  2370  const (
  2371  	// see also https://9p.io/magic/man2html/1/nm
  2372  	TextSym      SymbolType = 'T'
  2373  	DataSym      SymbolType = 'D'
  2374  	BSSSym       SymbolType = 'B'
  2375  	UndefinedSym SymbolType = 'U'
  2376  	TLSSym       SymbolType = 't'
  2377  	FrameSym     SymbolType = 'm'
  2378  	ParamSym     SymbolType = 'p'
  2379  	AutoSym      SymbolType = 'a'
  2380  
  2381  	// Deleted auto (not a real sym, just placeholder for type)
  2382  	DeletedAutoSym = 'x'
  2383  )
  2384  
  2385  func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
  2386  	// These symbols won't show up in the first loop below because we
  2387  	// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
  2388  	s := ctxt.Syms.Lookup("runtime.text", 0)
  2389  	if s.Type == sym.STEXT {
  2390  		// We've already included this symbol in ctxt.Textp
  2391  		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
  2392  		// on AIX with external linker.
  2393  		// See data.go:/textaddress
  2394  		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2395  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2396  		}
  2397  	}
  2398  
  2399  	n := 0
  2400  
  2401  	// Generate base addresses for all text sections if there are multiple
  2402  	for _, sect := range Segtext.Sections {
  2403  		if n == 0 {
  2404  			n++
  2405  			continue
  2406  		}
  2407  		if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2408  			// On AIX, runtime.text.X are symbols already in the symtab.
  2409  			break
  2410  		}
  2411  		s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
  2412  		if s == nil {
  2413  			break
  2414  		}
  2415  		if s.Type == sym.STEXT {
  2416  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2417  		}
  2418  		n++
  2419  	}
  2420  
  2421  	s = ctxt.Syms.Lookup("runtime.etext", 0)
  2422  	if s.Type == sym.STEXT {
  2423  		// We've already included this symbol in ctxt.Textp
  2424  		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
  2425  		// on AIX with external linker.
  2426  		// See data.go:/textaddress
  2427  		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2428  			put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2429  		}
  2430  	}
  2431  
  2432  	shouldBeInSymbolTable := func(s *sym.Symbol) bool {
  2433  		if s.Attr.NotInSymbolTable() {
  2434  			return false
  2435  		}
  2436  		if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" {
  2437  			// On AIX, .go.buildinfo must be in the symbol table as
  2438  			// it has relocations.
  2439  			return true
  2440  		}
  2441  		if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
  2442  			return false
  2443  		}
  2444  		return true
  2445  	}
  2446  
  2447  	for _, s := range ctxt.Syms.Allsym {
  2448  		if !shouldBeInSymbolTable(s) {
  2449  			continue
  2450  		}
  2451  		switch s.Type {
  2452  		case sym.SCONST,
  2453  			sym.SRODATA,
  2454  			sym.SSYMTAB,
  2455  			sym.SPCLNTAB,
  2456  			sym.SINITARR,
  2457  			sym.SDATA,
  2458  			sym.SNOPTRDATA,
  2459  			sym.SELFROSECT,
  2460  			sym.SMACHOGOT,
  2461  			sym.STYPE,
  2462  			sym.SSTRING,
  2463  			sym.SGOSTRING,
  2464  			sym.SGOFUNC,
  2465  			sym.SGCBITS,
  2466  			sym.STYPERELRO,
  2467  			sym.SSTRINGRELRO,
  2468  			sym.SGOSTRINGRELRO,
  2469  			sym.SGOFUNCRELRO,
  2470  			sym.SGCBITSRELRO,
  2471  			sym.SRODATARELRO,
  2472  			sym.STYPELINK,
  2473  			sym.SITABLINK,
  2474  			sym.SWINDOWS:
  2475  			if !s.Attr.Reachable() {
  2476  				continue
  2477  			}
  2478  			put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
  2479  
  2480  		case sym.SBSS, sym.SNOPTRBSS, sym.SLIBFUZZER_EXTRA_COUNTER:
  2481  			if !s.Attr.Reachable() {
  2482  				continue
  2483  			}
  2484  			if len(s.P) > 0 {
  2485  				Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
  2486  			}
  2487  			put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
  2488  
  2489  		case sym.SUNDEFEXT:
  2490  			if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
  2491  				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
  2492  			}
  2493  
  2494  		case sym.SHOSTOBJ:
  2495  			if !s.Attr.Reachable() {
  2496  				continue
  2497  			}
  2498  			if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
  2499  				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
  2500  			}
  2501  
  2502  		case sym.SDYNIMPORT:
  2503  			if !s.Attr.Reachable() {
  2504  				continue
  2505  			}
  2506  			put(ctxt, s, s.Extname(), UndefinedSym, 0, nil)
  2507  
  2508  		case sym.STLSBSS:
  2509  			if ctxt.LinkMode == LinkExternal {
  2510  				put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
  2511  			}
  2512  		}
  2513  	}
  2514  
  2515  	for _, s := range ctxt.Textp {
  2516  		put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
  2517  
  2518  		locals := int32(0)
  2519  		if s.FuncInfo != nil {
  2520  			locals = s.FuncInfo.Locals
  2521  		}
  2522  		// NOTE(ality): acid can't produce a stack trace without .frame symbols
  2523  		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
  2524  
  2525  		if s.FuncInfo == nil {
  2526  			continue
  2527  		}
  2528  	}
  2529  
  2530  	if ctxt.Debugvlog != 0 || *flagN {
  2531  		ctxt.Logf("symsize = %d\n", uint32(Symsize))
  2532  	}
  2533  }
  2534  
  2535  func Symaddr(s *sym.Symbol) int64 {
  2536  	if !s.Attr.Reachable() {
  2537  		Errorf(s, "unreachable symbol in symaddr")
  2538  	}
  2539  	return s.Value
  2540  }
  2541  
  2542  func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
  2543  	s := ctxt.Syms.Lookup(p, 0)
  2544  	s.Type = t
  2545  	s.Value = v
  2546  	s.Attr |= sym.AttrReachable
  2547  	s.Attr |= sym.AttrSpecial
  2548  	s.Attr |= sym.AttrLocal
  2549  }
  2550  
  2551  func datoff(s *sym.Symbol, addr int64) int64 {
  2552  	if uint64(addr) >= Segdata.Vaddr {
  2553  		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2554  	}
  2555  	if uint64(addr) >= Segtext.Vaddr {
  2556  		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2557  	}
  2558  	Errorf(s, "invalid datoff %#x", addr)
  2559  	return 0
  2560  }
  2561  
  2562  func Entryvalue(ctxt *Link) int64 {
  2563  	a := *flagEntrySymbol
  2564  	if a[0] >= '0' && a[0] <= '9' {
  2565  		return atolwhex(a)
  2566  	}
  2567  	s := ctxt.Syms.Lookup(a, 0)
  2568  	if s.Type == 0 {
  2569  		return *FlagTextAddr
  2570  	}
  2571  	if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT {
  2572  		Errorf(s, "entry not text")
  2573  	}
  2574  	return s.Value
  2575  }
  2576  
  2577  func undefsym(ctxt *Link, s *sym.Symbol) {
  2578  	var r *sym.Reloc
  2579  
  2580  	for i := 0; i < len(s.R); i++ {
  2581  		r = &s.R[i]
  2582  		if r.Sym == nil { // happens for some external ARM relocs
  2583  			continue
  2584  		}
  2585  		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
  2586  		// sense and should be removed when someone has thought about it properly.
  2587  		if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
  2588  			Errorf(s, "undefined: %q", r.Sym.Name)
  2589  		}
  2590  		if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
  2591  			Errorf(s, "relocation target %q", r.Sym.Name)
  2592  		}
  2593  	}
  2594  }
  2595  
  2596  func (ctxt *Link) undef() {
  2597  	// undefsym performs checks (almost) identical to checks
  2598  	// that report undefined relocations in relocsym.
  2599  	// Both undefsym and relocsym can report same symbol as undefined,
  2600  	// which results in error message duplication (see #10978).
  2601  	//
  2602  	// The undef is run after Arch.Asmb and could detect some
  2603  	// programming errors there, but if object being linked is already
  2604  	// failed with errors, it is better to avoid duplicated errors.
  2605  	if nerrors > 0 {
  2606  		return
  2607  	}
  2608  
  2609  	for _, s := range ctxt.Textp {
  2610  		undefsym(ctxt, s)
  2611  	}
  2612  	for _, s := range datap {
  2613  		undefsym(ctxt, s)
  2614  	}
  2615  	if nerrors > 0 {
  2616  		errorexit()
  2617  	}
  2618  }
  2619  
  2620  func (ctxt *Link) callgraph() {
  2621  	if !*FlagC {
  2622  		return
  2623  	}
  2624  
  2625  	var i int
  2626  	var r *sym.Reloc
  2627  	for _, s := range ctxt.Textp {
  2628  		for i = 0; i < len(s.R); i++ {
  2629  			r = &s.R[i]
  2630  			if r.Sym == nil {
  2631  				continue
  2632  			}
  2633  			if r.Type.IsDirectCall() && r.Sym.Type == sym.STEXT {
  2634  				ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
  2635  			}
  2636  		}
  2637  	}
  2638  }
  2639  
  2640  func Rnd(v int64, r int64) int64 {
  2641  	if r <= 0 {
  2642  		return v
  2643  	}
  2644  	v += r - 1
  2645  	c := v % r
  2646  	if c < 0 {
  2647  		c += r
  2648  	}
  2649  	v -= c
  2650  	return v
  2651  }
  2652  
  2653  func bgetc(r *bio.Reader) int {
  2654  	c, err := r.ReadByte()
  2655  	if err != nil {
  2656  		if err != io.EOF {
  2657  			log.Fatalf("reading input: %v", err)
  2658  		}
  2659  		return -1
  2660  	}
  2661  	return int(c)
  2662  }
  2663  
  2664  type markKind uint8 // for postorder traversal
  2665  const (
  2666  	_ markKind = iota
  2667  	visiting
  2668  	visited
  2669  )
  2670  
  2671  func postorder(libs []*sym.Library) []*sym.Library {
  2672  	order := make([]*sym.Library, 0, len(libs)) // hold the result
  2673  	mark := make(map[*sym.Library]markKind, len(libs))
  2674  	for _, lib := range libs {
  2675  		dfs(lib, mark, &order)
  2676  	}
  2677  	return order
  2678  }
  2679  
  2680  func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
  2681  	if mark[lib] == visited {
  2682  		return
  2683  	}
  2684  	if mark[lib] == visiting {
  2685  		panic("found import cycle while visiting " + lib.Pkg)
  2686  	}
  2687  	mark[lib] = visiting
  2688  	for _, i := range lib.Imports {
  2689  		dfs(i, mark, order)
  2690  	}
  2691  	mark[lib] = visited
  2692  	*order = append(*order, lib)
  2693  }
  2694  
  2695  func (ctxt *Link) loadlibfull() {
  2696  	// Load full symbol contents, resolve indexed references.
  2697  	ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
  2698  
  2699  	// Pull the symbols out.
  2700  	ctxt.loader.ExtractSymbols(ctxt.Syms)
  2701  
  2702  	// Load cgo directives.
  2703  	for _, d := range ctxt.cgodata {
  2704  		setCgoAttr(ctxt, ctxt.Syms.Lookup, d.file, d.pkg, d.directives)
  2705  	}
  2706  
  2707  	setupdynexp(ctxt)
  2708  
  2709  	// Populate ctxt.Reachparent if appropriate.
  2710  	if ctxt.Reachparent != nil {
  2711  		for i := 0; i < len(ctxt.loader.Reachparent); i++ {
  2712  			p := ctxt.loader.Reachparent[i]
  2713  			if p == 0 {
  2714  				continue
  2715  			}
  2716  			if p == loader.Sym(i) {
  2717  				panic("self-cycle in reachparent")
  2718  			}
  2719  			sym := ctxt.loader.Syms[i]
  2720  			psym := ctxt.loader.Syms[p]
  2721  			ctxt.Reachparent[sym] = psym
  2722  		}
  2723  	}
  2724  
  2725  	// Drop the reference.
  2726  	ctxt.loader = nil
  2727  	ctxt.cgodata = nil
  2728  
  2729  	addToTextp(ctxt)
  2730  }
  2731  
  2732  func (ctxt *Link) dumpsyms() {
  2733  	for _, s := range ctxt.Syms.Allsym {
  2734  		fmt.Printf("%s %s %p %v %v\n", s, s.Type, s, s.Attr.Reachable(), s.Attr.OnList())
  2735  		for i := range s.R {
  2736  			fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
  2737  		}
  2738  	}
  2739  }