github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/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  	if Debug['u'] != 0 {
   813  		ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
   814  	}
   815  
   816  	/*
   817  	 * load all the object files from the archive now.
   818  	 * this gives us sequential file access and keeps us
   819  	 * from needing to come back later to pick up more
   820  	 * objects.  it breaks the usual C archive model, but
   821  	 * this is Go, not C.  the common case in Go is that
   822  	 * we need to load all the objects, and then we throw away
   823  	 * the individual symbols that are unused.
   824  	 *
   825  	 * loading every object will also make it possible to
   826  	 * load foreign objects not referenced by __.GOSYMDEF.
   827  	 */
   828  	for {
   829  		l = nextar(f, off, &arhdr)
   830  		if l == 0 {
   831  			break
   832  		}
   833  		if l < 0 {
   834  			Exitf("%s: malformed archive", lib.File)
   835  		}
   836  
   837  		off += l
   838  
   839  		pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
   840  		l = atolwhex(arhdr.size)
   841  		ldobj(f, pkg, l, pname, lib.File, ArchiveObj)
   842  	}
   843  
   844  out:
   845  	obj.Bterm(f)
   846  }
   847  
   848  type Hostobj struct {
   849  	ld     func(*obj.Biobuf, string, int64, string)
   850  	pkg    string
   851  	pn     string
   852  	file   string
   853  	off    int64
   854  	length int64
   855  }
   856  
   857  var hostobj []Hostobj
   858  
   859  // These packages can use internal linking mode.
   860  // Others trigger external mode.
   861  var internalpkg = []string{
   862  	"crypto/x509",
   863  	"net",
   864  	"os/user",
   865  	"runtime/cgo",
   866  	"runtime/race",
   867  	"runtime/msan",
   868  }
   869  
   870  func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg string, length int64, pn string, file string) *Hostobj {
   871  	isinternal := false
   872  	for i := 0; i < len(internalpkg); i++ {
   873  		if pkg == internalpkg[i] {
   874  			isinternal = true
   875  			break
   876  		}
   877  	}
   878  
   879  	// DragonFly declares errno with __thread, which results in a symbol
   880  	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
   881  	// currently know how to handle TLS relocations, hence we have to
   882  	// force external linking for any libraries that link in code that
   883  	// uses errno. This can be removed if the Go linker ever supports
   884  	// these relocation types.
   885  	if HEADTYPE == obj.Hdragonfly {
   886  		if pkg == "net" || pkg == "os/user" {
   887  			isinternal = false
   888  		}
   889  	}
   890  
   891  	if !isinternal {
   892  		externalobj = true
   893  	}
   894  
   895  	hostobj = append(hostobj, Hostobj{})
   896  	h := &hostobj[len(hostobj)-1]
   897  	h.ld = ld
   898  	h.pkg = pkg
   899  	h.pn = pn
   900  	h.file = file
   901  	h.off = obj.Boffset(f)
   902  	h.length = length
   903  	return h
   904  }
   905  
   906  func hostobjs() {
   907  	var f *obj.Biobuf
   908  	var h *Hostobj
   909  
   910  	for i := 0; i < len(hostobj); i++ {
   911  		h = &hostobj[i]
   912  		var err error
   913  		f, err = obj.Bopenr(h.file)
   914  		if f == nil {
   915  			Exitf("cannot reopen %s: %v", h.pn, err)
   916  		}
   917  
   918  		obj.Bseek(f, h.off, 0)
   919  		h.ld(f, h.pkg, h.length, h.pn)
   920  		obj.Bterm(f)
   921  	}
   922  }
   923  
   924  // provided by lib9
   925  
   926  func rmtemp() {
   927  	os.RemoveAll(tmpdir)
   928  }
   929  
   930  func hostlinksetup() {
   931  	if Linkmode != LinkExternal {
   932  		return
   933  	}
   934  
   935  	// For external link, record that we need to tell the external linker -s,
   936  	// and turn off -s internally: the external linker needs the symbol
   937  	// information for its final link.
   938  	debug_s = Debug['s']
   939  	Debug['s'] = 0
   940  
   941  	// create temporary directory and arrange cleanup
   942  	if tmpdir == "" {
   943  		dir, err := ioutil.TempDir("", "go-link-")
   944  		if err != nil {
   945  			log.Fatal(err)
   946  		}
   947  		tmpdir = dir
   948  		AtExit(rmtemp)
   949  	}
   950  
   951  	// change our output to temporary object file
   952  	coutbuf.f.Close()
   953  	mayberemoveoutfile()
   954  
   955  	p := fmt.Sprintf("%s/go.o", tmpdir)
   956  	var err error
   957  	f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
   958  	if err != nil {
   959  		Exitf("cannot create %s: %v", p, err)
   960  	}
   961  
   962  	coutbuf.Writer = bufio.NewWriter(f)
   963  	coutbuf.f = f
   964  }
   965  
   966  // hostobjCopy creates a copy of the object files in hostobj in a
   967  // temporary directory.
   968  func hostobjCopy() (paths []string) {
   969  	var wg sync.WaitGroup
   970  	sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
   971  	for i, h := range hostobj {
   972  		h := h
   973  		dst := fmt.Sprintf("%s/%06d.o", tmpdir, i)
   974  		paths = append(paths, dst)
   975  
   976  		wg.Add(1)
   977  		go func() {
   978  			sema <- struct{}{}
   979  			defer func() {
   980  				<-sema
   981  				wg.Done()
   982  			}()
   983  			f, err := os.Open(h.file)
   984  			if err != nil {
   985  				Exitf("cannot reopen %s: %v", h.pn, err)
   986  			}
   987  			if _, err := f.Seek(h.off, 0); err != nil {
   988  				Exitf("cannot seek %s: %v", h.pn, err)
   989  			}
   990  
   991  			w, err := os.Create(dst)
   992  			if err != nil {
   993  				Exitf("cannot create %s: %v", dst, err)
   994  			}
   995  			if _, err := io.CopyN(w, f, h.length); err != nil {
   996  				Exitf("cannot write %s: %v", dst, err)
   997  			}
   998  			if err := w.Close(); err != nil {
   999  				Exitf("cannot close %s: %v", dst, err)
  1000  			}
  1001  		}()
  1002  	}
  1003  	wg.Wait()
  1004  	return paths
  1005  }
  1006  
  1007  // archive builds a .a archive from the hostobj object files.
  1008  func archive() {
  1009  	if Buildmode != BuildmodeCArchive {
  1010  		return
  1011  	}
  1012  
  1013  	mayberemoveoutfile()
  1014  	argv := []string{"ar", "-q", "-c", "-s", outfile}
  1015  	argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir))
  1016  	argv = append(argv, hostobjCopy()...)
  1017  
  1018  	if Debug['v'] != 0 {
  1019  		fmt.Fprintf(&Bso, "archive: %s\n", strings.Join(argv, " "))
  1020  		Bso.Flush()
  1021  	}
  1022  
  1023  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1024  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1025  	}
  1026  }
  1027  
  1028  func hostlink() {
  1029  	if Linkmode != LinkExternal || nerrors > 0 {
  1030  		return
  1031  	}
  1032  	if Buildmode == BuildmodeCArchive {
  1033  		return
  1034  	}
  1035  
  1036  	if extld == "" {
  1037  		extld = "gcc"
  1038  	}
  1039  
  1040  	var argv []string
  1041  	argv = append(argv, extld)
  1042  	argv = append(argv, hostlinkArchArgs()...)
  1043  
  1044  	if Debug['s'] == 0 && debug_s == 0 {
  1045  		argv = append(argv, "-gdwarf-2")
  1046  	} else {
  1047  		argv = append(argv, "-s")
  1048  	}
  1049  
  1050  	if HEADTYPE == obj.Hdarwin {
  1051  		argv = append(argv, "-Wl,-no_pie,-headerpad,1144")
  1052  	}
  1053  	if HEADTYPE == obj.Hopenbsd {
  1054  		argv = append(argv, "-Wl,-nopie")
  1055  	}
  1056  	if HEADTYPE == obj.Hwindows {
  1057  		if headstring == "windowsgui" {
  1058  			argv = append(argv, "-mwindows")
  1059  		} else {
  1060  			argv = append(argv, "-mconsole")
  1061  		}
  1062  	}
  1063  
  1064  	switch Buildmode {
  1065  	case BuildmodeExe:
  1066  		if HEADTYPE == obj.Hdarwin {
  1067  			argv = append(argv, "-Wl,-pagezero_size,4000000")
  1068  		}
  1069  	case BuildmodePIE:
  1070  		argv = append(argv, "-pie")
  1071  	case BuildmodeCShared:
  1072  		if HEADTYPE == obj.Hdarwin {
  1073  			argv = append(argv, "-dynamiclib")
  1074  		} else {
  1075  			// ELF.
  1076  			argv = append(argv, "-Wl,-Bsymbolic")
  1077  			if UseRelro() {
  1078  				argv = append(argv, "-Wl,-z,relro")
  1079  			}
  1080  			// Pass -z nodelete to mark the shared library as
  1081  			// non-closeable: a dlclose will do nothing.
  1082  			argv = append(argv, "-shared", "-Wl,-z,nodelete")
  1083  		}
  1084  	case BuildmodeShared:
  1085  		if UseRelro() {
  1086  			argv = append(argv, "-Wl,-z,relro")
  1087  		}
  1088  		argv = append(argv, "-shared")
  1089  	}
  1090  
  1091  	if Iself && DynlinkingGo() {
  1092  		// We force all symbol resolution to be done at program startup
  1093  		// because lazy PLT resolution can use large amounts of stack at
  1094  		// times we cannot allow it to do so.
  1095  		argv = append(argv, "-Wl,-znow")
  1096  	}
  1097  
  1098  	if Iself && len(buildinfo) > 0 {
  1099  		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
  1100  	}
  1101  
  1102  	// On Windows, given -o foo, GCC will append ".exe" to produce
  1103  	// "foo.exe".  We have decided that we want to honor the -o
  1104  	// option.  To make this work, we append a '.' so that GCC
  1105  	// will decide that the file already has an extension.  We
  1106  	// only want to do this when producing a Windows output file
  1107  	// on a Windows host.
  1108  	outopt := outfile
  1109  	if goos == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
  1110  		outopt += "."
  1111  	}
  1112  	argv = append(argv, "-o")
  1113  	argv = append(argv, outopt)
  1114  
  1115  	if rpath.val != "" {
  1116  		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
  1117  	}
  1118  
  1119  	// Force global symbols to be exported for dlopen, etc.
  1120  	if Iself {
  1121  		argv = append(argv, "-rdynamic")
  1122  	}
  1123  
  1124  	if strings.Contains(argv[0], "clang") {
  1125  		argv = append(argv, "-Qunused-arguments")
  1126  	}
  1127  
  1128  	argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir))
  1129  	argv = append(argv, hostobjCopy()...)
  1130  
  1131  	if Linkshared {
  1132  		seenDirs := make(map[string]bool)
  1133  		seenLibs := make(map[string]bool)
  1134  		addshlib := func(path string) {
  1135  			dir, base := filepath.Split(path)
  1136  			if !seenDirs[dir] {
  1137  				argv = append(argv, "-L"+dir)
  1138  				if !rpath.set {
  1139  					argv = append(argv, "-Wl,-rpath="+dir)
  1140  				}
  1141  				seenDirs[dir] = true
  1142  			}
  1143  			base = strings.TrimSuffix(base, ".so")
  1144  			base = strings.TrimPrefix(base, "lib")
  1145  			if !seenLibs[base] {
  1146  				argv = append(argv, "-l"+base)
  1147  				seenLibs[base] = true
  1148  			}
  1149  		}
  1150  		for _, shlib := range Ctxt.Shlibs {
  1151  			addshlib(shlib.Path)
  1152  			for _, dep := range shlib.Deps {
  1153  				if dep == "" {
  1154  					continue
  1155  				}
  1156  				libpath := findshlib(dep)
  1157  				if libpath != "" {
  1158  					addshlib(libpath)
  1159  				}
  1160  			}
  1161  		}
  1162  	}
  1163  
  1164  	argv = append(argv, ldflag...)
  1165  
  1166  	for _, p := range strings.Fields(extldflags) {
  1167  		argv = append(argv, p)
  1168  
  1169  		// clang, unlike GCC, passes -rdynamic to the linker
  1170  		// even when linking with -static, causing a linker
  1171  		// error when using GNU ld.  So take out -rdynamic if
  1172  		// we added it.  We do it in this order, rather than
  1173  		// only adding -rdynamic later, so that -extldflags
  1174  		// can override -rdynamic without using -static.
  1175  		if Iself && p == "-static" {
  1176  			for i := range argv {
  1177  				if argv[i] == "-rdynamic" {
  1178  					argv[i] = "-static"
  1179  				}
  1180  			}
  1181  		}
  1182  	}
  1183  	if HEADTYPE == obj.Hwindows {
  1184  		argv = append(argv, peimporteddlls()...)
  1185  	}
  1186  
  1187  	if Debug['v'] != 0 {
  1188  		fmt.Fprintf(&Bso, "host link:")
  1189  		for _, v := range argv {
  1190  			fmt.Fprintf(&Bso, " %q", v)
  1191  		}
  1192  		fmt.Fprintf(&Bso, "\n")
  1193  		Bso.Flush()
  1194  	}
  1195  
  1196  	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1197  		Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1198  	} else if Debug['v'] != 0 && len(out) > 0 {
  1199  		fmt.Fprintf(&Bso, "%s", out)
  1200  		Bso.Flush()
  1201  	}
  1202  
  1203  	if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin {
  1204  		// Skip combining dwarf on arm.
  1205  		if Thearch.Thechar != '5' && Thearch.Thechar != '7' {
  1206  			dsym := fmt.Sprintf("%s/go.dwarf", tmpdir)
  1207  			if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
  1208  				Ctxt.Cursym = nil
  1209  				Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
  1210  			}
  1211  			// Skip combining if `dsymutil` didn't generate a file. See #11994.
  1212  			if _, err := os.Stat(dsym); os.IsNotExist(err) {
  1213  				return
  1214  			}
  1215  			// For os.Rename to work reliably, must be in same directory as outfile.
  1216  			combinedOutput := outfile + "~"
  1217  			if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil {
  1218  				Ctxt.Cursym = nil
  1219  				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1220  			}
  1221  			os.Remove(outfile)
  1222  			if err := os.Rename(combinedOutput, outfile); err != nil {
  1223  				Ctxt.Cursym = nil
  1224  				Exitf("%s: %v", os.Args[0], err)
  1225  			}
  1226  		}
  1227  	}
  1228  }
  1229  
  1230  // hostlinkArchArgs returns arguments to pass to the external linker
  1231  // based on the architecture.
  1232  func hostlinkArchArgs() []string {
  1233  	switch Thearch.Thechar {
  1234  	case '8':
  1235  		return []string{"-m32"}
  1236  	case '6', '9':
  1237  		return []string{"-m64"}
  1238  	case '5':
  1239  		return []string{"-marm"}
  1240  	case '7':
  1241  		// nothing needed
  1242  	}
  1243  	return nil
  1244  }
  1245  
  1246  // ldobj loads an input object.  If it is a host object (an object
  1247  // compiled by a non-Go compiler) it returns the Hostobj pointer.  If
  1248  // it is a Go object, it returns nil.
  1249  func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) *Hostobj {
  1250  	eof := obj.Boffset(f) + length
  1251  
  1252  	start := obj.Boffset(f)
  1253  	c1 := obj.Bgetc(f)
  1254  	c2 := obj.Bgetc(f)
  1255  	c3 := obj.Bgetc(f)
  1256  	c4 := obj.Bgetc(f)
  1257  	obj.Bseek(f, start, 0)
  1258  
  1259  	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
  1260  	if magic == 0x7f454c46 { // \x7F E L F
  1261  		return ldhostobj(ldelf, f, pkg, length, pn, file)
  1262  	}
  1263  
  1264  	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
  1265  		return ldhostobj(ldmacho, f, pkg, length, pn, file)
  1266  	}
  1267  
  1268  	if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
  1269  		return ldhostobj(ldpe, f, pkg, length, pn, file)
  1270  	}
  1271  
  1272  	/* check the header */
  1273  	line := obj.Brdline(f, '\n')
  1274  	if line == "" {
  1275  		if obj.Blinelen(f) > 0 {
  1276  			Diag("%s: not an object file", pn)
  1277  			return nil
  1278  		}
  1279  		Diag("truncated object file: %s", pn)
  1280  		return nil
  1281  	}
  1282  
  1283  	if !strings.HasPrefix(line, "go object ") {
  1284  		if strings.HasSuffix(pn, ".go") {
  1285  			Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar)
  1286  		}
  1287  
  1288  		if line == Thestring {
  1289  			// old header format: just $GOOS
  1290  			Diag("%s: stale object file", pn)
  1291  			return nil
  1292  		}
  1293  
  1294  		Diag("%s: not an object file", pn)
  1295  		return nil
  1296  	}
  1297  
  1298  	// First, check that the basic goos, goarch, and version match.
  1299  	t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion())
  1300  
  1301  	line = strings.TrimRight(line, "\n")
  1302  	if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 {
  1303  		Diag("%s: object is [%s] expected [%s]", pn, line[10:], t)
  1304  		return nil
  1305  	}
  1306  
  1307  	// Second, check that longer lines match each other exactly,
  1308  	// so that the Go compiler and write additional information
  1309  	// that must be the same from run to run.
  1310  	if len(line) >= len(t)+10 {
  1311  		if theline == "" {
  1312  			theline = line[10:]
  1313  		} else if theline != line[10:] {
  1314  			Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline)
  1315  			return nil
  1316  		}
  1317  	}
  1318  
  1319  	/* skip over exports and other info -- ends with \n!\n */
  1320  	import0 := obj.Boffset(f)
  1321  
  1322  	c1 = '\n' // the last line ended in \n
  1323  	c2 = obj.Bgetc(f)
  1324  	c3 = obj.Bgetc(f)
  1325  	for c1 != '\n' || c2 != '!' || c3 != '\n' {
  1326  		c1 = c2
  1327  		c2 = c3
  1328  		c3 = obj.Bgetc(f)
  1329  		if c3 == obj.Beof {
  1330  			Diag("truncated object file: %s", pn)
  1331  			return nil
  1332  		}
  1333  	}
  1334  
  1335  	import1 := obj.Boffset(f)
  1336  
  1337  	obj.Bseek(f, import0, 0)
  1338  	ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n
  1339  	obj.Bseek(f, import1, 0)
  1340  
  1341  	ldobjfile(Ctxt, f, pkg, eof-obj.Boffset(f), pn)
  1342  	return nil
  1343  }
  1344  
  1345  func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte {
  1346  	data := make([]byte, sym.Size)
  1347  	sect := f.Sections[sym.Section]
  1348  	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  1349  		Diag("reading %s from non-data section", sym.Name)
  1350  	}
  1351  	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  1352  	if uint64(n) != sym.Size {
  1353  		Diag("reading contents of %s: %v", sym.Name, err)
  1354  	}
  1355  	return data
  1356  }
  1357  
  1358  func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  1359  	data := make([]byte, Rnd(int64(sz), 4))
  1360  	_, err := io.ReadFull(r, data)
  1361  	if err != nil {
  1362  		return nil, err
  1363  	}
  1364  	data = data[:sz]
  1365  	return data, nil
  1366  }
  1367  
  1368  func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  1369  	for _, sect := range f.Sections {
  1370  		if sect.Type != elf.SHT_NOTE {
  1371  			continue
  1372  		}
  1373  		r := sect.Open()
  1374  		for {
  1375  			var namesize, descsize, noteType int32
  1376  			err := binary.Read(r, f.ByteOrder, &namesize)
  1377  			if err != nil {
  1378  				if err == io.EOF {
  1379  					break
  1380  				}
  1381  				return nil, fmt.Errorf("read namesize failed: %v", err)
  1382  			}
  1383  			err = binary.Read(r, f.ByteOrder, &descsize)
  1384  			if err != nil {
  1385  				return nil, fmt.Errorf("read descsize failed: %v", err)
  1386  			}
  1387  			err = binary.Read(r, f.ByteOrder, &noteType)
  1388  			if err != nil {
  1389  				return nil, fmt.Errorf("read type failed: %v", err)
  1390  			}
  1391  			noteName, err := readwithpad(r, namesize)
  1392  			if err != nil {
  1393  				return nil, fmt.Errorf("read name failed: %v", err)
  1394  			}
  1395  			desc, err := readwithpad(r, descsize)
  1396  			if err != nil {
  1397  				return nil, fmt.Errorf("read desc failed: %v", err)
  1398  			}
  1399  			if string(name) == string(noteName) && typ == noteType {
  1400  				return desc, nil
  1401  			}
  1402  		}
  1403  	}
  1404  	return nil, nil
  1405  }
  1406  
  1407  func findshlib(shlib string) string {
  1408  	for _, libdir := range Ctxt.Libdir {
  1409  		libpath := filepath.Join(libdir, shlib)
  1410  		if _, err := os.Stat(libpath); err == nil {
  1411  			return libpath
  1412  		}
  1413  	}
  1414  	Diag("cannot find shared library: %s", shlib)
  1415  	return ""
  1416  }
  1417  
  1418  func ldshlibsyms(shlib string) {
  1419  	libpath := findshlib(shlib)
  1420  	if libpath == "" {
  1421  		return
  1422  	}
  1423  	for _, processedlib := range Ctxt.Shlibs {
  1424  		if processedlib.Path == libpath {
  1425  			return
  1426  		}
  1427  	}
  1428  	if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil {
  1429  		fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath)
  1430  		Ctxt.Bso.Flush()
  1431  	}
  1432  
  1433  	f, err := elf.Open(libpath)
  1434  	if err != nil {
  1435  		Diag("cannot open shared library: %s", libpath)
  1436  		return
  1437  	}
  1438  
  1439  	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  1440  	if err != nil {
  1441  		Diag("cannot read ABI hash from shared library %s: %v", libpath, err)
  1442  		return
  1443  	}
  1444  
  1445  	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  1446  	if err != nil {
  1447  		Diag("cannot read dep list from shared library %s: %v", libpath, err)
  1448  		return
  1449  	}
  1450  	deps := strings.Split(string(depsbytes), "\n")
  1451  
  1452  	syms, err := f.DynamicSymbols()
  1453  	if err != nil {
  1454  		Diag("cannot read symbols from shared library: %s", libpath)
  1455  		return
  1456  	}
  1457  	gcdata_locations := make(map[uint64]*LSym)
  1458  	for _, elfsym := range syms {
  1459  		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  1460  			continue
  1461  		}
  1462  		lsym := Linklookup(Ctxt, elfsym.Name, 0)
  1463  		if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 {
  1464  			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 {
  1465  				Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File)
  1466  			}
  1467  			if lsym.Size > int64(elfsym.Size) {
  1468  				// If the existing symbol is a BSS value that is
  1469  				// larger than the one read from the shared library,
  1470  				// keep references to that.  Conversely, if the
  1471  				// version from the shared libray is larger, we want
  1472  				// to make all references be to that.
  1473  				continue
  1474  			}
  1475  		}
  1476  		lsym.Type = obj.SDYNIMPORT
  1477  		lsym.ElfType = elf.ST_TYPE(elfsym.Info)
  1478  		lsym.Size = int64(elfsym.Size)
  1479  		if elfsym.Section != elf.SHN_UNDEF {
  1480  			// Set .File for the library that actually defines the symbol.
  1481  			lsym.File = libpath
  1482  			// The decodetype_* functions in decodetype.go need access to
  1483  			// the type data.
  1484  			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
  1485  				lsym.P = readelfsymboldata(f, &elfsym)
  1486  				gcdata_locations[elfsym.Value+2*uint64(Thearch.Ptrsize)+8+1*uint64(Thearch.Ptrsize)] = lsym
  1487  			}
  1488  		}
  1489  	}
  1490  	gcdata_addresses := make(map[*LSym]uint64)
  1491  	if Thearch.Thechar == '7' {
  1492  		for _, sect := range f.Sections {
  1493  			if sect.Type == elf.SHT_RELA {
  1494  				var rela elf.Rela64
  1495  				rdr := sect.Open()
  1496  				for {
  1497  					err := binary.Read(rdr, f.ByteOrder, &rela)
  1498  					if err == io.EOF {
  1499  						break
  1500  					} else if err != nil {
  1501  						Diag("reading relocation failed %v", err)
  1502  						return
  1503  					}
  1504  					t := elf.R_AARCH64(rela.Info & 0xffff)
  1505  					if t != elf.R_AARCH64_RELATIVE {
  1506  						continue
  1507  					}
  1508  					if lsym, ok := gcdata_locations[rela.Off]; ok {
  1509  						gcdata_addresses[lsym] = uint64(rela.Addend)
  1510  					}
  1511  				}
  1512  			}
  1513  		}
  1514  	}
  1515  
  1516  	// We might have overwritten some functions above (this tends to happen for the
  1517  	// autogenerated type equality/hashing functions) and we don't want to generated
  1518  	// pcln table entries for these any more so unstitch them from the Textp linked
  1519  	// list.
  1520  	var last *LSym
  1521  
  1522  	for s := Ctxt.Textp; s != nil; s = s.Next {
  1523  		if s.Type == obj.SDYNIMPORT {
  1524  			continue
  1525  		}
  1526  
  1527  		if last == nil {
  1528  			Ctxt.Textp = s
  1529  		} else {
  1530  			last.Next = s
  1531  		}
  1532  		last = s
  1533  	}
  1534  
  1535  	if last == nil {
  1536  		Ctxt.Textp = nil
  1537  		Ctxt.Etextp = nil
  1538  	} else {
  1539  		last.Next = nil
  1540  		Ctxt.Etextp = last
  1541  	}
  1542  
  1543  	Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdata_addresses: gcdata_addresses})
  1544  }
  1545  
  1546  func mywhatsys() {
  1547  	goroot = obj.Getgoroot()
  1548  	goos = obj.Getgoos()
  1549  	goarch = obj.Getgoarch()
  1550  
  1551  	if !strings.HasPrefix(goarch, Thestring) {
  1552  		log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch)
  1553  	}
  1554  }
  1555  
  1556  // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
  1557  /*
  1558   * Convert raw string to the prefix that will be used in the symbol table.
  1559   * Invalid bytes turn into %xx.	 Right now the only bytes that need
  1560   * escaping are %, ., and ", but we escape all control characters too.
  1561   *
  1562   * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
  1563   * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
  1564   */
  1565  func pathtoprefix(s string) string {
  1566  	slash := strings.LastIndex(s, "/")
  1567  	for i := 0; i < len(s); i++ {
  1568  		c := s[i]
  1569  		if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
  1570  			var buf bytes.Buffer
  1571  			for i := 0; i < len(s); i++ {
  1572  				c := s[i]
  1573  				if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
  1574  					fmt.Fprintf(&buf, "%%%02x", c)
  1575  					continue
  1576  				}
  1577  				buf.WriteByte(c)
  1578  			}
  1579  			return buf.String()
  1580  		}
  1581  	}
  1582  	return s
  1583  }
  1584  
  1585  func addsection(seg *Segment, name string, rwx int) *Section {
  1586  	var l **Section
  1587  
  1588  	for l = &seg.Sect; *l != nil; l = &(*l).Next {
  1589  	}
  1590  	sect := new(Section)
  1591  	sect.Rwx = uint8(rwx)
  1592  	sect.Name = name
  1593  	sect.Seg = seg
  1594  	sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned
  1595  	*l = sect
  1596  	return sect
  1597  }
  1598  
  1599  func Le16(b []byte) uint16 {
  1600  	return uint16(b[0]) | uint16(b[1])<<8
  1601  }
  1602  
  1603  func Le32(b []byte) uint32 {
  1604  	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  1605  }
  1606  
  1607  func Le64(b []byte) uint64 {
  1608  	return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32
  1609  }
  1610  
  1611  func Be16(b []byte) uint16 {
  1612  	return uint16(b[0])<<8 | uint16(b[1])
  1613  }
  1614  
  1615  func Be32(b []byte) uint32 {
  1616  	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  1617  }
  1618  
  1619  type Chain struct {
  1620  	sym   *LSym
  1621  	up    *Chain
  1622  	limit int // limit on entry to sym
  1623  }
  1624  
  1625  var morestack *LSym
  1626  
  1627  // TODO: Record enough information in new object files to
  1628  // allow stack checks here.
  1629  
  1630  func haslinkregister() bool {
  1631  	return Ctxt.FixedFrameSize() != 0
  1632  }
  1633  
  1634  func callsize() int {
  1635  	if haslinkregister() {
  1636  		return 0
  1637  	}
  1638  	return Thearch.Regsize
  1639  }
  1640  
  1641  func dostkcheck() {
  1642  	var ch Chain
  1643  
  1644  	morestack = Linklookup(Ctxt, "runtime.morestack", 0)
  1645  
  1646  	// Every splitting function ensures that there are at least StackLimit
  1647  	// bytes available below SP when the splitting prologue finishes.
  1648  	// If the splitting function calls F, then F begins execution with
  1649  	// at least StackLimit - callsize() bytes available.
  1650  	// Check that every function behaves correctly with this amount
  1651  	// of stack, following direct calls in order to piece together chains
  1652  	// of non-splitting functions.
  1653  	ch.up = nil
  1654  
  1655  	ch.limit = obj.StackLimit - callsize()
  1656  
  1657  	// Check every function, but do the nosplit functions in a first pass,
  1658  	// to make the printed failure chains as short as possible.
  1659  	for s := Ctxt.Textp; s != nil; s = s.Next {
  1660  		// runtime.racesymbolizethunk is called from gcc-compiled C
  1661  		// code running on the operating system thread stack.
  1662  		// It uses more than the usual amount of stack but that's okay.
  1663  		if s.Name == "runtime.racesymbolizethunk" {
  1664  			continue
  1665  		}
  1666  
  1667  		if s.Nosplit != 0 {
  1668  			Ctxt.Cursym = s
  1669  			ch.sym = s
  1670  			stkcheck(&ch, 0)
  1671  		}
  1672  	}
  1673  
  1674  	for s := Ctxt.Textp; s != nil; s = s.Next {
  1675  		if s.Nosplit == 0 {
  1676  			Ctxt.Cursym = s
  1677  			ch.sym = s
  1678  			stkcheck(&ch, 0)
  1679  		}
  1680  	}
  1681  }
  1682  
  1683  func stkcheck(up *Chain, depth int) int {
  1684  	limit := up.limit
  1685  	s := up.sym
  1686  
  1687  	// Don't duplicate work: only need to consider each
  1688  	// function at top of safe zone once.
  1689  	top := limit == obj.StackLimit-callsize()
  1690  	if top {
  1691  		if s.Stkcheck != 0 {
  1692  			return 0
  1693  		}
  1694  		s.Stkcheck = 1
  1695  	}
  1696  
  1697  	if depth > 100 {
  1698  		Diag("nosplit stack check too deep")
  1699  		stkbroke(up, 0)
  1700  		return -1
  1701  	}
  1702  
  1703  	if s.External != 0 || s.Pcln == nil {
  1704  		// external function.
  1705  		// should never be called directly.
  1706  		// only diagnose the direct caller.
  1707  		// TODO(mwhudson): actually think about this.
  1708  		if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() &&
  1709  			Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared {
  1710  			Diag("call to external function %s", s.Name)
  1711  		}
  1712  		return -1
  1713  	}
  1714  
  1715  	if limit < 0 {
  1716  		stkbroke(up, limit)
  1717  		return -1
  1718  	}
  1719  
  1720  	// morestack looks like it calls functions,
  1721  	// but it switches the stack pointer first.
  1722  	if s == morestack {
  1723  		return 0
  1724  	}
  1725  
  1726  	var ch Chain
  1727  	ch.up = up
  1728  
  1729  	if s.Nosplit == 0 {
  1730  		// Ensure we have enough stack to call morestack.
  1731  		ch.limit = limit - callsize()
  1732  		ch.sym = morestack
  1733  		if stkcheck(&ch, depth+1) < 0 {
  1734  			return -1
  1735  		}
  1736  		if !top {
  1737  			return 0
  1738  		}
  1739  		// Raise limit to allow frame.
  1740  		limit = int(obj.StackLimit+s.Locals) + int(Ctxt.FixedFrameSize())
  1741  	}
  1742  
  1743  	// Walk through sp adjustments in function, consuming relocs.
  1744  	ri := 0
  1745  
  1746  	endr := len(s.R)
  1747  	var ch1 Chain
  1748  	var pcsp Pciter
  1749  	var r *Reloc
  1750  	for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1751  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  1752  
  1753  		// Check stack size in effect for this span.
  1754  		if int32(limit)-pcsp.value < 0 {
  1755  			stkbroke(up, int(int32(limit)-pcsp.value))
  1756  			return -1
  1757  		}
  1758  
  1759  		// Process calls in this span.
  1760  		for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
  1761  			r = &s.R[ri]
  1762  			switch r.Type {
  1763  			// Direct call.
  1764  			case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER, obj.R_CALLMIPS:
  1765  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
  1766  				ch.sym = r.Sym
  1767  				if stkcheck(&ch, depth+1) < 0 {
  1768  					return -1
  1769  				}
  1770  
  1771  			// Indirect call.  Assume it is a call to a splitting function,
  1772  			// so we have to make sure it can call morestack.
  1773  			// Arrange the data structures to report both calls, so that
  1774  			// if there is an error, stkprint shows all the steps involved.
  1775  			case obj.R_CALLIND:
  1776  				ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
  1777  
  1778  				ch.sym = nil
  1779  				ch1.limit = ch.limit - callsize() // for morestack in called prologue
  1780  				ch1.up = &ch
  1781  				ch1.sym = morestack
  1782  				if stkcheck(&ch1, depth+2) < 0 {
  1783  					return -1
  1784  				}
  1785  			}
  1786  		}
  1787  	}
  1788  
  1789  	return 0
  1790  }
  1791  
  1792  func stkbroke(ch *Chain, limit int) {
  1793  	Diag("nosplit stack overflow")
  1794  	stkprint(ch, limit)
  1795  }
  1796  
  1797  func stkprint(ch *Chain, limit int) {
  1798  	var name string
  1799  
  1800  	if ch.sym != nil {
  1801  		name = ch.sym.Name
  1802  		if ch.sym.Nosplit != 0 {
  1803  			name += " (nosplit)"
  1804  		}
  1805  	} else {
  1806  		name = "function pointer"
  1807  	}
  1808  
  1809  	if ch.up == nil {
  1810  		// top of chain.  ch->sym != nil.
  1811  		if ch.sym.Nosplit != 0 {
  1812  			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  1813  		} else {
  1814  			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  1815  		}
  1816  	} else {
  1817  		stkprint(ch.up, ch.limit+callsize())
  1818  		if !haslinkregister() {
  1819  			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  1820  		}
  1821  	}
  1822  
  1823  	if ch.limit != limit {
  1824  		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  1825  	}
  1826  }
  1827  
  1828  func Cflush() {
  1829  	if err := coutbuf.Writer.Flush(); err != nil {
  1830  		Exitf("flushing %s: %v", coutbuf.f.Name(), err)
  1831  	}
  1832  }
  1833  
  1834  func Cpos() int64 {
  1835  	off, err := coutbuf.f.Seek(0, 1)
  1836  	if err != nil {
  1837  		Exitf("seeking in output [0, 1]: %v", err)
  1838  	}
  1839  	return off + int64(coutbuf.Buffered())
  1840  }
  1841  
  1842  func Cseek(p int64) {
  1843  	Cflush()
  1844  	if _, err := coutbuf.f.Seek(p, 0); err != nil {
  1845  		Exitf("seeking in output [0, 1]: %v", err)
  1846  	}
  1847  }
  1848  
  1849  func Cwrite(p []byte) {
  1850  	coutbuf.Write(p)
  1851  }
  1852  
  1853  func Cput(c uint8) {
  1854  	coutbuf.WriteByte(c)
  1855  }
  1856  
  1857  func usage() {
  1858  	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  1859  	obj.Flagprint(2)
  1860  	Exit(2)
  1861  }
  1862  
  1863  func setheadtype(s string) {
  1864  	h := headtype(s)
  1865  	if h < 0 {
  1866  		Exitf("unknown header type -H %s", s)
  1867  	}
  1868  
  1869  	headstring = s
  1870  	HEADTYPE = int32(headtype(s))
  1871  }
  1872  
  1873  func setinterp(s string) {
  1874  	Debug['I'] = 1 // denote cmdline interpreter override
  1875  	interpreter = s
  1876  }
  1877  
  1878  func doversion() {
  1879  	Exitf("version %s", obj.Getgoversion())
  1880  }
  1881  
  1882  func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
  1883  	// These symbols won't show up in the first loop below because we
  1884  	// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
  1885  	s := Linklookup(Ctxt, "runtime.text", 0)
  1886  
  1887  	if s.Type == obj.STEXT {
  1888  		put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
  1889  	}
  1890  	s = Linklookup(Ctxt, "runtime.etext", 0)
  1891  	if s.Type == obj.STEXT {
  1892  		put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
  1893  	}
  1894  
  1895  	for s := Ctxt.Allsym; s != nil; s = s.Allsym {
  1896  		if s.Hide != 0 || ((s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC.") {
  1897  			continue
  1898  		}
  1899  		switch s.Type & obj.SMASK {
  1900  		case obj.SCONST,
  1901  			obj.SRODATA,
  1902  			obj.SSYMTAB,
  1903  			obj.SPCLNTAB,
  1904  			obj.SINITARR,
  1905  			obj.SDATA,
  1906  			obj.SNOPTRDATA,
  1907  			obj.SELFROSECT,
  1908  			obj.SMACHOGOT,
  1909  			obj.STYPE,
  1910  			obj.SSTRING,
  1911  			obj.SGOSTRING,
  1912  			obj.SGOFUNC,
  1913  			obj.SGCBITS,
  1914  			obj.STYPERELRO,
  1915  			obj.SSTRINGRELRO,
  1916  			obj.SGOSTRINGRELRO,
  1917  			obj.SGOFUNCRELRO,
  1918  			obj.SGCBITSRELRO,
  1919  			obj.SRODATARELRO,
  1920  			obj.STYPELINK,
  1921  			obj.SWINDOWS:
  1922  			if !s.Reachable {
  1923  				continue
  1924  			}
  1925  			put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype)
  1926  
  1927  		case obj.SBSS, obj.SNOPTRBSS:
  1928  			if !s.Reachable {
  1929  				continue
  1930  			}
  1931  			if len(s.P) > 0 {
  1932  				Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special)
  1933  			}
  1934  			put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
  1935  
  1936  		case obj.SFILE:
  1937  			put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil)
  1938  
  1939  		case obj.SHOSTOBJ:
  1940  			if HEADTYPE == obj.Hwindows || Iself {
  1941  				put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil)
  1942  			}
  1943  
  1944  		case obj.SDYNIMPORT:
  1945  			if !s.Reachable {
  1946  				continue
  1947  			}
  1948  			put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
  1949  
  1950  		case obj.STLSBSS:
  1951  			if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd {
  1952  				put(s, s.Name, 't', Symaddr(s), s.Size, int(s.Version), s.Gotype)
  1953  			}
  1954  		}
  1955  	}
  1956  
  1957  	var a *Auto
  1958  	var off int32
  1959  	for s := Ctxt.Textp; s != nil; s = s.Next {
  1960  		put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
  1961  
  1962  		// NOTE(ality): acid can't produce a stack trace without .frame symbols
  1963  		put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil)
  1964  
  1965  		for a = s.Autom; a != nil; a = a.Link {
  1966  			// Emit a or p according to actual offset, even if label is wrong.
  1967  			// This avoids negative offsets, which cannot be encoded.
  1968  			if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM {
  1969  				continue
  1970  			}
  1971  
  1972  			// compute offset relative to FP
  1973  			if a.Name == obj.A_PARAM {
  1974  				off = a.Aoffset
  1975  			} else {
  1976  				off = a.Aoffset - int32(Thearch.Ptrsize)
  1977  			}
  1978  
  1979  			// FP
  1980  			if off >= 0 {
  1981  				put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype)
  1982  				continue
  1983  			}
  1984  
  1985  			// SP
  1986  			if off <= int32(-Thearch.Ptrsize) {
  1987  				put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype)
  1988  				continue
  1989  			}
  1990  		}
  1991  	}
  1992  
  1993  	// Otherwise, off is addressing the saved program counter.
  1994  	// Something underhanded is going on. Say nothing.
  1995  	if Debug['v'] != 0 || Debug['n'] != 0 {
  1996  		fmt.Fprintf(&Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize))
  1997  	}
  1998  	Bso.Flush()
  1999  }
  2000  
  2001  func Symaddr(s *LSym) int64 {
  2002  	if !s.Reachable {
  2003  		Diag("unreachable symbol in symaddr - %s", s.Name)
  2004  	}
  2005  	return s.Value
  2006  }
  2007  
  2008  func xdefine(p string, t int, v int64) {
  2009  	s := Linklookup(Ctxt, p, 0)
  2010  	s.Type = int16(t)
  2011  	s.Value = v
  2012  	s.Reachable = true
  2013  	s.Special = 1
  2014  	s.Local = true
  2015  }
  2016  
  2017  func datoff(addr int64) int64 {
  2018  	if uint64(addr) >= Segdata.Vaddr {
  2019  		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2020  	}
  2021  	if uint64(addr) >= Segtext.Vaddr {
  2022  		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2023  	}
  2024  	Diag("datoff %#x", addr)
  2025  	return 0
  2026  }
  2027  
  2028  func Entryvalue() int64 {
  2029  	a := INITENTRY
  2030  	if a[0] >= '0' && a[0] <= '9' {
  2031  		return atolwhex(a)
  2032  	}
  2033  	s := Linklookup(Ctxt, a, 0)
  2034  	if s.Type == 0 {
  2035  		return INITTEXT
  2036  	}
  2037  	if s.Type != obj.STEXT {
  2038  		Diag("entry not text: %s", s.Name)
  2039  	}
  2040  	return s.Value
  2041  }
  2042  
  2043  func undefsym(s *LSym) {
  2044  	var r *Reloc
  2045  
  2046  	Ctxt.Cursym = s
  2047  	for i := 0; i < len(s.R); i++ {
  2048  		r = &s.R[i]
  2049  		if r.Sym == nil { // happens for some external ARM relocs
  2050  			continue
  2051  		}
  2052  		if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF {
  2053  			Diag("undefined: %s", r.Sym.Name)
  2054  		}
  2055  		if !r.Sym.Reachable {
  2056  			Diag("use of unreachable symbol: %s", r.Sym.Name)
  2057  		}
  2058  	}
  2059  }
  2060  
  2061  func undef() {
  2062  	for s := Ctxt.Textp; s != nil; s = s.Next {
  2063  		undefsym(s)
  2064  	}
  2065  	for s := datap; s != nil; s = s.Next {
  2066  		undefsym(s)
  2067  	}
  2068  	if nerrors > 0 {
  2069  		errorexit()
  2070  	}
  2071  }
  2072  
  2073  func callgraph() {
  2074  	if Debug['c'] == 0 {
  2075  		return
  2076  	}
  2077  
  2078  	var i int
  2079  	var r *Reloc
  2080  	for s := Ctxt.Textp; s != nil; s = s.Next {
  2081  		for i = 0; i < len(s.R); i++ {
  2082  			r = &s.R[i]
  2083  			if r.Sym == nil {
  2084  				continue
  2085  			}
  2086  			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 {
  2087  				fmt.Fprintf(&Bso, "%s calls %s\n", s.Name, r.Sym.Name)
  2088  			}
  2089  		}
  2090  	}
  2091  }
  2092  
  2093  func Diag(format string, args ...interface{}) {
  2094  	tn := ""
  2095  	sep := ""
  2096  	if Ctxt.Cursym != nil {
  2097  		tn = Ctxt.Cursym.Name
  2098  		sep = ": "
  2099  	}
  2100  	fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...))
  2101  	nerrors++
  2102  	if Debug['h'] != 0 {
  2103  		panic("error")
  2104  	}
  2105  	if nerrors > 20 {
  2106  		Exitf("too many errors")
  2107  	}
  2108  }
  2109  
  2110  func checkgo() {
  2111  	if Debug['C'] == 0 {
  2112  		return
  2113  	}
  2114  
  2115  	// TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all,
  2116  	// which would simplify this logic quite a bit.
  2117  
  2118  	// Mark every Go-called C function with cfunc=2, recursively.
  2119  	var changed int
  2120  	var i int
  2121  	var r *Reloc
  2122  	var s *LSym
  2123  	for {
  2124  		changed = 0
  2125  		for s = Ctxt.Textp; s != nil; s = s.Next {
  2126  			if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) {
  2127  				for i = 0; i < len(s.R); i++ {
  2128  					r = &s.R[i]
  2129  					if r.Sym == nil {
  2130  						continue
  2131  					}
  2132  					if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT {
  2133  						if r.Sym.Cfunc == 1 {
  2134  							changed = 1
  2135  							r.Sym.Cfunc = 2
  2136  						}
  2137  					}
  2138  				}
  2139  			}
  2140  		}
  2141  		if changed == 0 {
  2142  			break
  2143  		}
  2144  	}
  2145  
  2146  	// Complain about Go-called C functions that can split the stack
  2147  	// (that can be preempted for garbage collection or trigger a stack copy).
  2148  	for s := Ctxt.Textp; s != nil; s = s.Next {
  2149  		if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) {
  2150  			for i = 0; i < len(s.R); i++ {
  2151  				r = &s.R[i]
  2152  				if r.Sym == nil {
  2153  					continue
  2154  				}
  2155  				if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT {
  2156  					if s.Cfunc == 0 && r.Sym.Cfunc == 2 && r.Sym.Nosplit == 0 {
  2157  						fmt.Printf("Go %s calls C %s\n", s.Name, r.Sym.Name)
  2158  					} else if s.Cfunc == 2 && s.Nosplit != 0 && r.Sym.Nosplit == 0 {
  2159  						fmt.Printf("Go calls C %s calls %s\n", s.Name, r.Sym.Name)
  2160  					}
  2161  				}
  2162  			}
  2163  		}
  2164  	}
  2165  }
  2166  
  2167  func Rnd(v int64, r int64) int64 {
  2168  	if r <= 0 {
  2169  		return v
  2170  	}
  2171  	v += r - 1
  2172  	c := v % r
  2173  	if c < 0 {
  2174  		c += r
  2175  	}
  2176  	v -= c
  2177  	return v
  2178  }