github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/cmd/link/internal/ld/lib.go (about)

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