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