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