github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/link/internal/ld/lib.go (about)

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