github.com/aloncn/graphics-go@v0.0.1/src/cmd/link/internal/ld/lib.go (about)

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