github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/link/internal/ld/lib.go (about)

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