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