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