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