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