...

Source file src/pkg/cmd/link/internal/ld/lib.go

     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@terzarima.net)
     6	//	Portions Copyright © 1997-1999 Vita Nuova Limited
     7	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8	//	Portions Copyright © 2004,2006 Bruce Ellis
     9	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11	//	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12	//
    13	// Permission is hereby granted, free of charge, to any person obtaining a copy
    14	// of this software and associated documentation files (the "Software"), to deal
    15	// in the Software without restriction, including without limitation the rights
    16	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17	// copies of the Software, and to permit persons to whom the Software is
    18	// furnished to do so, subject to the following conditions:
    19	//
    20	// The above copyright notice and this permission notice shall be included in
    21	// all copies or substantial portions of the Software.
    22	//
    23	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29	// THE SOFTWARE.
    30	
    31	package ld
    32	
    33	import (
    34		"bufio"
    35		"bytes"
    36		"cmd/internal/bio"
    37		"cmd/internal/objabi"
    38		"cmd/internal/sys"
    39		"cmd/link/internal/loadelf"
    40		"cmd/link/internal/loadmacho"
    41		"cmd/link/internal/loadpe"
    42		"cmd/link/internal/loadxcoff"
    43		"cmd/link/internal/objfile"
    44		"cmd/link/internal/sym"
    45		"crypto/sha1"
    46		"debug/elf"
    47		"debug/macho"
    48		"encoding/base64"
    49		"encoding/binary"
    50		"encoding/hex"
    51		"fmt"
    52		"io"
    53		"io/ioutil"
    54		"log"
    55		"os"
    56		"os/exec"
    57		"path/filepath"
    58		"runtime"
    59		"strings"
    60		"sync"
    61	)
    62	
    63	// Data layout and relocation.
    64	
    65	// Derived from Inferno utils/6l/l.h
    66	// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
    67	//
    68	//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
    69	//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
    70	//	Portions Copyright © 1997-1999 Vita Nuova Limited
    71	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
    72	//	Portions Copyright © 2004,2006 Bruce Ellis
    73	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    74	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    75	//	Portions Copyright © 2009 The Go Authors. All rights reserved.
    76	//
    77	// Permission is hereby granted, free of charge, to any person obtaining a copy
    78	// of this software and associated documentation files (the "Software"), to deal
    79	// in the Software without restriction, including without limitation the rights
    80	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    81	// copies of the Software, and to permit persons to whom the Software is
    82	// furnished to do so, subject to the following conditions:
    83	//
    84	// The above copyright notice and this permission notice shall be included in
    85	// all copies or substantial portions of the Software.
    86	//
    87	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    88	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    89	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    90	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    91	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    92	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    93	// THE SOFTWARE.
    94	
    95	type Arch struct {
    96		Funcalign      int
    97		Maxalign       int
    98		Minalign       int
    99		Dwarfregsp     int
   100		Dwarfreglr     int
   101		Linuxdynld     string
   102		Freebsddynld   string
   103		Netbsddynld    string
   104		Openbsddynld   string
   105		Dragonflydynld string
   106		Solarisdynld   string
   107		Adddynrel      func(*Link, *sym.Symbol, *sym.Reloc) bool
   108		Archinit       func(*Link)
   109		// Archreloc is an arch-specific hook that assists in
   110		// relocation processing (invoked by 'relocsym'); it handles
   111		// target-specific relocation tasks. Here "rel" is the current
   112		// relocation being examined, "sym" is the symbol containing the
   113		// chunk of data to which the relocation applies, and "off" is the
   114		// contents of the to-be-relocated data item (from sym.P). Return
   115		// value is the appropriately relocated value (to be written back
   116		// to the same spot in sym.P) and a boolean indicating
   117		// success/failure (a failing value indicates a fatal error).
   118		Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
   119			offset int64) (relocatedOffset int64, success bool)
   120		// Archrelocvariant is a second arch-specific hook used for
   121		// relocation processing; it handles relocations where r.Type is
   122		// insufficient to describe the relocation (r.Variant !=
   123		// sym.RV_NONE). Here "rel" is the relocation being applied, "sym"
   124		// is the symbol containing the chunk of data to which the
   125		// relocation applies, and "off" is the contents of the
   126		// to-be-relocated data item (from sym.P). Return is an updated
   127		// offset value.
   128		Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
   129			offset int64) (relocatedOffset int64)
   130		Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
   131	
   132		// Asmb and Asmb2 are arch-specific routines that write the output
   133		// file. Typically, Asmb writes most of the content (sections and
   134		// segments), for which we have computed the size and offset. Asmb2
   135		// writes the rest.
   136		Asmb  func(*Link)
   137		Asmb2 func(*Link)
   138	
   139		Elfreloc1   func(*Link, *sym.Reloc, int64) bool
   140		Elfsetupplt func(*Link)
   141		Gentext     func(*Link)
   142		Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   143		PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   144		Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
   145	
   146		// TLSIEtoLE converts a TLS Initial Executable relocation to
   147		// a TLS Local Executable relocation.
   148		//
   149		// This is possible when a TLS IE relocation refers to a local
   150		// symbol in an executable, which is typical when internally
   151		// linking PIE binaries.
   152		TLSIEtoLE func(s *sym.Symbol, off, size int)
   153	
   154		// optional override for assignAddress
   155		AssignAddress func(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64)
   156	}
   157	
   158	var (
   159		thearch Arch
   160		Lcsize  int32
   161		rpath   Rpath
   162		Spsize  int32
   163		Symsize int32
   164	)
   165	
   166	const (
   167		MINFUNC = 16 // minimum size for a function
   168	)
   169	
   170	// DynlinkingGo reports whether we are producing Go code that can live
   171	// in separate shared libraries linked together at runtime.
   172	func (ctxt *Link) DynlinkingGo() bool {
   173		if !ctxt.Loaded {
   174			panic("DynlinkingGo called before all symbols loaded")
   175		}
   176		return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins()
   177	}
   178	
   179	// CanUsePlugins reports whether a plugins can be used
   180	func (ctxt *Link) CanUsePlugins() bool {
   181		return ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil
   182	}
   183	
   184	// UseRelro reports whether to make use of "read only relocations" aka
   185	// relro.
   186	func (ctxt *Link) UseRelro() bool {
   187		switch ctxt.BuildMode {
   188		case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
   189			return ctxt.IsELF || ctxt.HeadType == objabi.Haix
   190		default:
   191			return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal)
   192		}
   193	}
   194	
   195	var (
   196		dynexp          []*sym.Symbol
   197		dynlib          []string
   198		ldflag          []string
   199		havedynamic     int
   200		Funcalign       int
   201		iscgo           bool
   202		elfglobalsymndx int
   203		interpreter     string
   204	
   205		debug_s bool // backup old value of debug['s']
   206		HEADR   int32
   207	
   208		nerrors  int
   209		liveness int64
   210	
   211		// See -strictdups command line flag.
   212		checkStrictDups   int // 0=off 1=warning 2=error
   213		strictDupMsgCount int
   214	)
   215	
   216	var (
   217		Segtext      sym.Segment
   218		Segrodata    sym.Segment
   219		Segrelrodata sym.Segment
   220		Segdata      sym.Segment
   221		Segdwarf     sym.Segment
   222	)
   223	
   224	const pkgdef = "__.PKGDEF"
   225	
   226	var (
   227		// Set if we see an object compiled by the host compiler that is not
   228		// from a package that is known to support internal linking mode.
   229		externalobj = false
   230		theline     string
   231	)
   232	
   233	func Lflag(ctxt *Link, arg string) {
   234		ctxt.Libdir = append(ctxt.Libdir, arg)
   235	}
   236	
   237	/*
   238	 * Unix doesn't like it when we write to a running (or, sometimes,
   239	 * recently run) binary, so remove the output file before writing it.
   240	 * On Windows 7, remove() can force a subsequent create() to fail.
   241	 * S_ISREG() does not exist on Plan 9.
   242	 */
   243	func mayberemoveoutfile() {
   244		if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
   245			return
   246		}
   247		os.Remove(*flagOutfile)
   248	}
   249	
   250	func libinit(ctxt *Link) {
   251		Funcalign = thearch.Funcalign
   252	
   253		// add goroot to the end of the libdir list.
   254		suffix := ""
   255	
   256		suffixsep := ""
   257		if *flagInstallSuffix != "" {
   258			suffixsep = "_"
   259			suffix = *flagInstallSuffix
   260		} else if *flagRace {
   261			suffixsep = "_"
   262			suffix = "race"
   263		} else if *flagMsan {
   264			suffixsep = "_"
   265			suffix = "msan"
   266		}
   267	
   268		Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
   269	
   270		mayberemoveoutfile()
   271		f, err := os.OpenFile(*flagOutfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
   272		if err != nil {
   273			Exitf("cannot create %s: %v", *flagOutfile, err)
   274		}
   275	
   276		ctxt.Out.w = bufio.NewWriter(f)
   277		ctxt.Out.f = f
   278	
   279		if *flagEntrySymbol == "" {
   280			switch ctxt.BuildMode {
   281			case BuildModeCShared, BuildModeCArchive:
   282				*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
   283			case BuildModeExe, BuildModePIE:
   284				*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
   285			case BuildModeShared, BuildModePlugin:
   286				// No *flagEntrySymbol for -buildmode=shared and plugin
   287			default:
   288				Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
   289			}
   290		}
   291	}
   292	
   293	func errorexit() {
   294		if nerrors != 0 {
   295			Exit(2)
   296		}
   297		if checkStrictDups > 1 && strictDupMsgCount > 0 {
   298			Exit(2)
   299		}
   300		Exit(0)
   301	}
   302	
   303	func loadinternal(ctxt *Link, name string) *sym.Library {
   304		if ctxt.linkShared && ctxt.PackageShlib != nil {
   305			if shlib := ctxt.PackageShlib[name]; shlib != "" {
   306				return addlibpath(ctxt, "internal", "internal", "", name, shlib)
   307			}
   308		}
   309		if ctxt.PackageFile != nil {
   310			if pname := ctxt.PackageFile[name]; pname != "" {
   311				return addlibpath(ctxt, "internal", "internal", pname, name, "")
   312			}
   313			ctxt.Logf("loadinternal: cannot find %s\n", name)
   314			return nil
   315		}
   316	
   317		for _, libdir := range ctxt.Libdir {
   318			if ctxt.linkShared {
   319				shlibname := filepath.Join(libdir, name+".shlibname")
   320				if ctxt.Debugvlog != 0 {
   321					ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
   322				}
   323				if _, err := os.Stat(shlibname); err == nil {
   324					return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
   325				}
   326			}
   327			pname := filepath.Join(libdir, name+".a")
   328			if ctxt.Debugvlog != 0 {
   329				ctxt.Logf("searching for %s.a in %s\n", name, pname)
   330			}
   331			if _, err := os.Stat(pname); err == nil {
   332				return addlibpath(ctxt, "internal", "internal", pname, name, "")
   333			}
   334		}
   335	
   336		ctxt.Logf("warning: unable to find %s.a\n", name)
   337		return nil
   338	}
   339	
   340	// extld returns the current external linker.
   341	func (ctxt *Link) extld() string {
   342		if *flagExtld == "" {
   343			*flagExtld = "gcc"
   344		}
   345		return *flagExtld
   346	}
   347	
   348	// findLibPathCmd uses cmd command to find gcc library libname.
   349	// It returns library full path if found, or "none" if not found.
   350	func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
   351		extld := ctxt.extld()
   352		args := hostlinkArchArgs(ctxt.Arch)
   353		args = append(args, cmd)
   354		if ctxt.Debugvlog != 0 {
   355			ctxt.Logf("%s %v\n", extld, args)
   356		}
   357		out, err := exec.Command(extld, args...).Output()
   358		if err != nil {
   359			if ctxt.Debugvlog != 0 {
   360				ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
   361			}
   362			return "none"
   363		}
   364		return strings.TrimSpace(string(out))
   365	}
   366	
   367	// findLibPath searches for library libname.
   368	// It returns library full path if found, or "none" if not found.
   369	func (ctxt *Link) findLibPath(libname string) string {
   370		return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
   371	}
   372	
   373	func (ctxt *Link) loadlib() {
   374		switch ctxt.BuildMode {
   375		case BuildModeCShared, BuildModePlugin:
   376			s := ctxt.Syms.Lookup("runtime.islibrary", 0)
   377			s.Attr |= sym.AttrDuplicateOK
   378			s.AddUint8(1)
   379		case BuildModeCArchive:
   380			s := ctxt.Syms.Lookup("runtime.isarchive", 0)
   381			s.Attr |= sym.AttrDuplicateOK
   382			s.AddUint8(1)
   383		}
   384	
   385		loadinternal(ctxt, "runtime")
   386		if ctxt.Arch.Family == sys.ARM {
   387			loadinternal(ctxt, "math")
   388		}
   389		if *flagRace {
   390			loadinternal(ctxt, "runtime/race")
   391		}
   392		if *flagMsan {
   393			loadinternal(ctxt, "runtime/msan")
   394		}
   395	
   396		// ctxt.Library grows during the loop, so not a range loop.
   397		for i := 0; i < len(ctxt.Library); i++ {
   398			lib := ctxt.Library[i]
   399			if lib.Shlib == "" {
   400				if ctxt.Debugvlog > 1 {
   401					ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), lib.File, lib.Objref)
   402				}
   403				loadobjfile(ctxt, lib)
   404			}
   405		}
   406	
   407		for _, lib := range ctxt.Library {
   408			if lib.Shlib != "" {
   409				if ctxt.Debugvlog > 1 {
   410					ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), lib.Shlib, lib.Objref)
   411				}
   412				ldshlibsyms(ctxt, lib.Shlib)
   413			}
   414		}
   415	
   416		iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
   417	
   418		// We now have enough information to determine the link mode.
   419		determineLinkMode(ctxt)
   420	
   421		// Recalculate pe parameters now that we have ctxt.LinkMode set.
   422		if ctxt.HeadType == objabi.Hwindows {
   423			Peinit(ctxt)
   424		}
   425	
   426		if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
   427			*FlagTextAddr = 0
   428		}
   429	
   430		if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
   431			toc := ctxt.Syms.Lookup(".TOC.", 0)
   432			toc.Type = sym.SDYNIMPORT
   433		}
   434	
   435		if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil && !(objabi.GOOS == "darwin" && (ctxt.Arch.Family == sys.AMD64 || ctxt.Arch.Family == sys.I386)) {
   436			// This indicates a user requested -linkmode=external.
   437			// The startup code uses an import of runtime/cgo to decide
   438			// whether to initialize the TLS.  So give it one. This could
   439			// be handled differently but it's an unusual case.
   440			if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil {
   441				if lib.Shlib != "" {
   442					ldshlibsyms(ctxt, lib.Shlib)
   443				} else {
   444					if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
   445						Exitf("cannot implicitly include runtime/cgo in a shared library")
   446					}
   447					loadobjfile(ctxt, lib)
   448				}
   449			}
   450		}
   451	
   452		if ctxt.LinkMode == LinkInternal {
   453			// Drop all the cgo_import_static declarations.
   454			// Turns out we won't be needing them.
   455			for _, s := range ctxt.Syms.Allsym {
   456				if s.Type == sym.SHOSTOBJ {
   457					// If a symbol was marked both
   458					// cgo_import_static and cgo_import_dynamic,
   459					// then we want to make it cgo_import_dynamic
   460					// now.
   461					if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
   462						s.Type = sym.SDYNIMPORT
   463					} else {
   464						s.Type = 0
   465					}
   466				}
   467			}
   468		}
   469	
   470		// The Android Q linker started to complain about underalignment of the our TLS
   471		// section. We don't actually use the section on android, so dont't
   472		// generate it.
   473		if objabi.GOOS != "android" {
   474			tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0)
   475	
   476			// runtime.tlsg is used for external linking on platforms that do not define
   477			// a variable to hold g in assembly (currently only intel).
   478			if tlsg.Type == 0 {
   479				tlsg.Type = sym.STLSBSS
   480				tlsg.Size = int64(ctxt.Arch.PtrSize)
   481			} else if tlsg.Type != sym.SDYNIMPORT {
   482				Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
   483			}
   484			tlsg.Attr |= sym.AttrReachable
   485			ctxt.Tlsg = tlsg
   486		}
   487	
   488		var moduledata *sym.Symbol
   489		if ctxt.BuildMode == BuildModePlugin {
   490			moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
   491			moduledata.Attr |= sym.AttrLocal
   492		} else {
   493			moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
   494		}
   495		if moduledata.Type != 0 && moduledata.Type != sym.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 ctxt.Arch.Family == sys.ARM {
   506				s := ctxt.Syms.Lookup("runtime.goarm", 0)
   507				s.Type = sym.SDATA
   508				s.Size = 0
   509				s.AddUint8(uint8(objabi.GOARM))
   510			}
   511	
   512			if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
   513				s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
   514				s.Type = sym.SDATA
   515				s.Size = 0
   516				s.AddUint8(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 |= sym.AttrLocal
   523		}
   524		// In all cases way we mark the moduledata as noptrdata to hide it from
   525		// the GC.
   526		moduledata.Type = sym.SNOPTRDATA
   527		moduledata.Attr |= sym.AttrReachable
   528		ctxt.Moduledata = moduledata
   529	
   530		// Now that we know the link mode, trim the dynexp list.
   531		x := sym.AttrCgoExportDynamic
   532	
   533		if ctxt.LinkMode == LinkExternal {
   534			x = sym.AttrCgoExportStatic
   535		}
   536		w := 0
   537		for i := range dynexp {
   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 ctxt.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 i := range s.R {
   554					r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
   555					if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
   556						any = true
   557						break
   558					}
   559				}
   560			}
   561			if any {
   562				if *flagLibGCC == "" {
   563					*flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
   564				}
   565				if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" {
   566					// On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a".
   567					// In this case we fail to load libgcc.a and can encounter link
   568					// errors - see if we can find libcompiler_rt.a instead.
   569					*flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
   570				}
   571				if *flagLibGCC != "none" {
   572					hostArchive(ctxt, *flagLibGCC)
   573				}
   574				if ctxt.HeadType == objabi.Hwindows {
   575					if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
   576						hostArchive(ctxt, p)
   577					}
   578					if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
   579						hostArchive(ctxt, p)
   580					}
   581					// TODO: maybe do something similar to peimporteddlls to collect all lib names
   582					// and try link them all to final exe just like libmingwex.a and libmingw32.a:
   583					/*
   584						for:
   585						#cgo windows LDFLAGS: -lmsvcrt -lm
   586						import:
   587						libmsvcrt.a libm.a
   588					*/
   589				}
   590			}
   591		} else {
   592			hostlinksetup(ctxt)
   593		}
   594	
   595		// We've loaded all the code now.
   596		ctxt.Loaded = true
   597	
   598		// If there are no dynamic libraries needed, gcc disables dynamic linking.
   599		// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   600		// assumes that a dynamic binary always refers to at least one dynamic library.
   601		// Rather than be a source of test cases for glibc, disable dynamic linking
   602		// the same way that gcc would.
   603		//
   604		// Exception: on OS X, programs such as Shark only work with dynamic
   605		// binaries, so leave it enabled on OS X (Mach-O) binaries.
   606		// Also leave it enabled on Solaris which doesn't support
   607		// statically linked binaries.
   608		if ctxt.BuildMode == BuildModeExe {
   609			if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
   610				*FlagD = true
   611			}
   612		}
   613	
   614		// If package versioning is required, generate a hash of the
   615		// packages used in the link.
   616		if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
   617			for _, lib := range ctxt.Library {
   618				if lib.Shlib == "" {
   619					genhash(ctxt, lib)
   620				}
   621			}
   622		}
   623	
   624		if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
   625			if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
   626				got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
   627				got.Type = sym.SDYNIMPORT
   628				got.Attr |= sym.AttrReachable
   629			}
   630		}
   631	
   632		importcycles()
   633	
   634		// put symbols into Textp
   635		// do it in postorder so that packages are laid down in dependency order
   636		// internal first, then everything else
   637		ctxt.Library = postorder(ctxt.Library)
   638		for _, doInternal := range [2]bool{true, false} {
   639			for _, lib := range ctxt.Library {
   640				if isRuntimeDepPkg(lib.Pkg) != doInternal {
   641					continue
   642				}
   643				ctxt.Textp = append(ctxt.Textp, lib.Textp...)
   644				for _, s := range lib.DupTextSyms {
   645					if !s.Attr.OnList() {
   646						ctxt.Textp = append(ctxt.Textp, s)
   647						s.Attr |= sym.AttrOnList
   648						// dupok symbols may be defined in multiple packages. its
   649						// associated package is chosen sort of arbitrarily (the
   650						// first containing package that the linker loads). canonicalize
   651						// it here to the package with which it will be laid down
   652						// in text.
   653						s.File = objabi.PathToPrefix(lib.Pkg)
   654					}
   655				}
   656			}
   657		}
   658	
   659		if len(ctxt.Shlibs) > 0 {
   660			// We might have overwritten some functions above (this tends to happen for the
   661			// autogenerated type equality/hashing functions) and we don't want to generated
   662			// pcln table entries for these any more so remove them from Textp.
   663			textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
   664			for _, s := range ctxt.Textp {
   665				if s.Type != sym.SDYNIMPORT {
   666					textp = append(textp, s)
   667				}
   668			}
   669			ctxt.Textp = textp
   670		}
   671	
   672		// Resolve ABI aliases in the list of cgo-exported functions.
   673		// This is necessary because we load the ABI0 symbol for all
   674		// cgo exports.
   675		for i, s := range dynexp {
   676			if s.Type != sym.SABIALIAS {
   677				continue
   678			}
   679			t := resolveABIAlias(s)
   680			t.Attr |= s.Attr
   681			t.SetExtname(s.Extname())
   682			dynexp[i] = t
   683		}
   684	}
   685	
   686	// mangleTypeSym shortens the names of symbols that represent Go types
   687	// if they are visible in the symbol table.
   688	//
   689	// As the names of these symbols are derived from the string of
   690	// the type, they can run to many kilobytes long. So we shorten
   691	// them using a SHA-1 when the name appears in the final binary.
   692	// This also removes characters that upset external linkers.
   693	//
   694	// These are the symbols that begin with the prefix 'type.' and
   695	// contain run-time type information used by the runtime and reflect
   696	// packages. All Go binaries contain these symbols, but only
   697	// those programs loaded dynamically in multiple parts need these
   698	// symbols to have entries in the symbol table.
   699	func (ctxt *Link) mangleTypeSym() {
   700		if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() {
   701			return
   702		}
   703	
   704		for _, s := range ctxt.Syms.Allsym {
   705			newName := typeSymbolMangle(s.Name)
   706			if newName != s.Name {
   707				ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent)
   708			}
   709		}
   710	}
   711	
   712	// typeSymbolMangle mangles the given symbol name into something shorter.
   713	//
   714	// Keep the type.. prefix, which parts of the linker (like the
   715	// DWARF generator) know means the symbol is not decodable.
   716	// Leave type.runtime. symbols alone, because other parts of
   717	// the linker manipulates them.
   718	func typeSymbolMangle(name string) string {
   719		if !strings.HasPrefix(name, "type.") {
   720			return name
   721		}
   722		if strings.HasPrefix(name, "type.runtime.") {
   723			return name
   724		}
   725		if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
   726			return name
   727		}
   728		hash := sha1.Sum([]byte(name))
   729		prefix := "type."
   730		if name[5] == '.' {
   731			prefix = "type.."
   732		}
   733		return prefix + base64.StdEncoding.EncodeToString(hash[:6])
   734	}
   735	
   736	/*
   737	 * look for the next file in an archive.
   738	 * adapted from libmach.
   739	 */
   740	func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
   741		if off&1 != 0 {
   742			off++
   743		}
   744		bp.MustSeek(off, 0)
   745		var buf [SAR_HDR]byte
   746		if n, err := io.ReadFull(bp, buf[:]); err != nil {
   747			if n == 0 && err != io.EOF {
   748				return -1
   749			}
   750			return 0
   751		}
   752	
   753		a.name = artrim(buf[0:16])
   754		a.date = artrim(buf[16:28])
   755		a.uid = artrim(buf[28:34])
   756		a.gid = artrim(buf[34:40])
   757		a.mode = artrim(buf[40:48])
   758		a.size = artrim(buf[48:58])
   759		a.fmag = artrim(buf[58:60])
   760	
   761		arsize := atolwhex(a.size)
   762		if arsize&1 != 0 {
   763			arsize++
   764		}
   765		return arsize + SAR_HDR
   766	}
   767	
   768	func genhash(ctxt *Link, lib *sym.Library) {
   769		f, err := bio.Open(lib.File)
   770		if err != nil {
   771			Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
   772			return
   773		}
   774		defer f.Close()
   775	
   776		var magbuf [len(ARMAG)]byte
   777		if _, err := io.ReadFull(f, magbuf[:]); err != nil {
   778			Exitf("file %s too short", lib.File)
   779		}
   780	
   781		if string(magbuf[:]) != ARMAG {
   782			Exitf("%s is not an archive file", lib.File)
   783		}
   784	
   785		var arhdr ArHdr
   786		l := nextar(f, f.Offset(), &arhdr)
   787		if l <= 0 {
   788			Errorf(nil, "%s: short read on archive file symbol header", lib.File)
   789			return
   790		}
   791		if arhdr.name != pkgdef {
   792			Errorf(nil, "%s: missing package data entry", lib.File)
   793			return
   794		}
   795	
   796		h := sha1.New()
   797	
   798		// To compute the hash of a package, we hash the first line of
   799		// __.PKGDEF (which contains the toolchain version and any
   800		// GOEXPERIMENT flags) and the export data (which is between
   801		// the first two occurrences of "\n$$").
   802	
   803		pkgDefBytes := make([]byte, atolwhex(arhdr.size))
   804		_, err = io.ReadFull(f, pkgDefBytes)
   805		if err != nil {
   806			Errorf(nil, "%s: error reading package data: %v", lib.File, err)
   807			return
   808		}
   809		firstEOL := bytes.IndexByte(pkgDefBytes, '\n')
   810		if firstEOL < 0 {
   811			Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
   812			return
   813		}
   814		firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$"))
   815		if firstDoubleDollar < 0 {
   816			Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File)
   817			return
   818		}
   819		secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$"))
   820		if secondDoubleDollar < 0 {
   821			Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File)
   822			return
   823		}
   824		h.Write(pkgDefBytes[0:firstEOL])
   825		h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
   826		lib.Hash = hex.EncodeToString(h.Sum(nil))
   827	}
   828	
   829	func loadobjfile(ctxt *Link, lib *sym.Library) {
   830		pkg := objabi.PathToPrefix(lib.Pkg)
   831	
   832		if ctxt.Debugvlog > 1 {
   833			ctxt.Logf("%5.2f ldobj: %s (%s)\n", Cputime(), lib.File, pkg)
   834		}
   835		f, err := bio.Open(lib.File)
   836		if err != nil {
   837			Exitf("cannot open file %s: %v", lib.File, err)
   838		}
   839		defer f.Close()
   840		defer func() {
   841			if pkg == "main" && !lib.Main {
   842				Exitf("%s: not package main", lib.File)
   843			}
   844	
   845			// Ideally, we'd check that *all* object files within
   846			// the archive were marked safe, but here we settle
   847			// for *any*.
   848			//
   849			// Historically, cmd/link only checked the __.PKGDEF
   850			// file, which in turn came from the first object
   851			// file, typically produced by cmd/compile. The
   852			// remaining object files are normally produced by
   853			// cmd/asm, which doesn't support marking files as
   854			// safe anyway. So at least in practice, this matches
   855			// how safe mode has always worked.
   856			if *flagU && !lib.Safe {
   857				Exitf("%s: load of unsafe package %s", lib.File, pkg)
   858			}
   859		}()
   860	
   861		for i := 0; i < len(ARMAG); i++ {
   862			if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
   863				continue
   864			}
   865	
   866			/* load it as a regular file */
   867			l := f.MustSeek(0, 2)
   868			f.MustSeek(0, 0)
   869			ldobj(ctxt, f, lib, l, lib.File, lib.File)
   870			return
   871		}
   872	
   873		/*
   874		 * load all the object files from the archive now.
   875		 * this gives us sequential file access and keeps us
   876		 * from needing to come back later to pick up more
   877		 * objects.  it breaks the usual C archive model, but
   878		 * this is Go, not C.  the common case in Go is that
   879		 * we need to load all the objects, and then we throw away
   880		 * the individual symbols that are unused.
   881		 *
   882		 * loading every object will also make it possible to
   883		 * load foreign objects not referenced by __.PKGDEF.
   884		 */
   885		var arhdr ArHdr
   886		off := f.Offset()
   887		for {
   888			l := nextar(f, off, &arhdr)
   889			if l == 0 {
   890				break
   891			}
   892			if l < 0 {
   893				Exitf("%s: malformed archive", lib.File)
   894			}
   895			off += l
   896	
   897			// __.PKGDEF isn't a real Go object file, and it's
   898			// absent in -linkobj builds anyway. Skipping it
   899			// ensures consistency between -linkobj and normal
   900			// build modes.
   901			if arhdr.name == pkgdef {
   902				continue
   903			}
   904	
   905			// Skip other special (non-object-file) sections that
   906			// build tools may have added. Such sections must have
   907			// short names so that the suffix is not truncated.
   908			if len(arhdr.name) < 16 {
   909				if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" {
   910					continue
   911				}
   912			}
   913	
   914			pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
   915			l = atolwhex(arhdr.size)
   916			ldobj(ctxt, f, lib, l, pname, lib.File)
   917		}
   918	}
   919	
   920	type Hostobj struct {
   921		ld     func(*Link, *bio.Reader, string, int64, string)
   922		pkg    string
   923		pn     string
   924		file   string
   925		off    int64
   926		length int64
   927	}
   928	
   929	var hostobj []Hostobj
   930	
   931	// These packages can use internal linking mode.
   932	// Others trigger external mode.
   933	var internalpkg = []string{
   934		"crypto/x509",
   935		"net",
   936		"os/user",
   937		"runtime/cgo",
   938		"runtime/race",
   939		"runtime/msan",
   940	}
   941	
   942	func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
   943		isinternal := false
   944		for _, intpkg := range internalpkg {
   945			if pkg == intpkg {
   946				isinternal = true
   947				break
   948			}
   949		}
   950	
   951		// DragonFly declares errno with __thread, which results in a symbol
   952		// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
   953		// currently know how to handle TLS relocations, hence we have to
   954		// force external linking for any libraries that link in code that
   955		// uses errno. This can be removed if the Go linker ever supports
   956		// these relocation types.
   957		if headType == objabi.Hdragonfly {
   958			if pkg == "net" || pkg == "os/user" {
   959				isinternal = false
   960			}
   961		}
   962	
   963		if !isinternal {
   964			externalobj = true
   965		}
   966	
   967		hostobj = append(hostobj, Hostobj{})
   968		h := &hostobj[len(hostobj)-1]
   969		h.ld = ld
   970		h.pkg = pkg
   971		h.pn = pn
   972		h.file = file
   973		h.off = f.Offset()
   974		h.length = length
   975		return h
   976	}
   977	
   978	func hostobjs(ctxt *Link) {
   979		var h *Hostobj
   980	
   981		for i := 0; i < len(hostobj); i++ {
   982			h = &hostobj[i]
   983			f, err := bio.Open(h.file)
   984			if err != nil {
   985				Exitf("cannot reopen %s: %v", h.pn, err)
   986			}
   987	
   988			f.MustSeek(h.off, 0)
   989			h.ld(ctxt, f, h.pkg, h.length, h.pn)
   990			f.Close()
   991		}
   992	}
   993	
   994	func hostlinksetup(ctxt *Link) {
   995		if ctxt.LinkMode != LinkExternal {
   996			return
   997		}
   998	
   999		// For external link, record that we need to tell the external linker -s,
  1000		// and turn off -s internally: the external linker needs the symbol
  1001		// information for its final link.
  1002		debug_s = *FlagS
  1003		*FlagS = false
  1004	
  1005		// create temporary directory and arrange cleanup
  1006		if *flagTmpdir == "" {
  1007			dir, err := ioutil.TempDir("", "go-link-")
  1008			if err != nil {
  1009				log.Fatal(err)
  1010			}
  1011			*flagTmpdir = dir
  1012			AtExit(func() {
  1013				ctxt.Out.f.Close()
  1014				os.RemoveAll(*flagTmpdir)
  1015			})
  1016		}
  1017	
  1018		// change our output to temporary object file
  1019		ctxt.Out.f.Close()
  1020		mayberemoveoutfile()
  1021	
  1022		p := filepath.Join(*flagTmpdir, "go.o")
  1023		var err error
  1024		f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
  1025		if err != nil {
  1026			Exitf("cannot create %s: %v", p, err)
  1027		}
  1028	
  1029		ctxt.Out.w = bufio.NewWriter(f)
  1030		ctxt.Out.f = f
  1031		ctxt.Out.off = 0
  1032	}
  1033	
  1034	// hostobjCopy creates a copy of the object files in hostobj in a
  1035	// temporary directory.
  1036	func hostobjCopy() (paths []string) {
  1037		var wg sync.WaitGroup
  1038		sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
  1039		for i, h := range hostobj {
  1040			h := h
  1041			dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
  1042			paths = append(paths, dst)
  1043	
  1044			wg.Add(1)
  1045			go func() {
  1046				sema <- struct{}{}
  1047				defer func() {
  1048					<-sema
  1049					wg.Done()
  1050				}()
  1051				f, err := os.Open(h.file)
  1052				if err != nil {
  1053					Exitf("cannot reopen %s: %v", h.pn, err)
  1054				}
  1055				defer f.Close()
  1056				if _, err := f.Seek(h.off, 0); err != nil {
  1057					Exitf("cannot seek %s: %v", h.pn, err)
  1058				}
  1059	
  1060				w, err := os.Create(dst)
  1061				if err != nil {
  1062					Exitf("cannot create %s: %v", dst, err)
  1063				}
  1064				if _, err := io.CopyN(w, f, h.length); err != nil {
  1065					Exitf("cannot write %s: %v", dst, err)
  1066				}
  1067				if err := w.Close(); err != nil {
  1068					Exitf("cannot close %s: %v", dst, err)
  1069				}
  1070			}()
  1071		}
  1072		wg.Wait()
  1073		return paths
  1074	}
  1075	
  1076	// writeGDBLinkerScript creates gcc linker script file in temp
  1077	// directory. writeGDBLinkerScript returns created file path.
  1078	// The script is used to work around gcc bug
  1079	// (see https://golang.org/issue/20183 for details).
  1080	func writeGDBLinkerScript() string {
  1081		name := "fix_debug_gdb_scripts.ld"
  1082		path := filepath.Join(*flagTmpdir, name)
  1083		src := `SECTIONS
  1084	{
  1085	  .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
  1086	  {
  1087	    *(.debug_gdb_scripts)
  1088	  }
  1089	}
  1090	INSERT AFTER .debug_types;
  1091	`
  1092		err := ioutil.WriteFile(path, []byte(src), 0666)
  1093		if err != nil {
  1094			Errorf(nil, "WriteFile %s failed: %v", name, err)
  1095		}
  1096		return path
  1097	}
  1098	
  1099	// archive builds a .a archive from the hostobj object files.
  1100	func (ctxt *Link) archive() {
  1101		if ctxt.BuildMode != BuildModeCArchive {
  1102			return
  1103		}
  1104	
  1105		if *flagExtar == "" {
  1106			*flagExtar = "ar"
  1107		}
  1108	
  1109		mayberemoveoutfile()
  1110	
  1111		// Force the buffer to flush here so that external
  1112		// tools will see a complete file.
  1113		ctxt.Out.Flush()
  1114		if err := ctxt.Out.f.Close(); err != nil {
  1115			Exitf("close: %v", err)
  1116		}
  1117		ctxt.Out.f = nil
  1118	
  1119		argv := []string{*flagExtar, "-q", "-c", "-s"}
  1120		if ctxt.HeadType == objabi.Haix {
  1121			argv = append(argv, "-X64")
  1122		}
  1123		argv = append(argv, *flagOutfile)
  1124		argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1125		argv = append(argv, hostobjCopy()...)
  1126	
  1127		if ctxt.Debugvlog != 0 {
  1128			ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
  1129		}
  1130	
  1131		if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
  1132			Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1133		}
  1134	}
  1135	
  1136	func (ctxt *Link) hostlink() {
  1137		if ctxt.LinkMode != LinkExternal || nerrors > 0 {
  1138			return
  1139		}
  1140		if ctxt.BuildMode == BuildModeCArchive {
  1141			return
  1142		}
  1143	
  1144		var argv []string
  1145		argv = append(argv, ctxt.extld())
  1146		argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
  1147	
  1148		if *FlagS || debug_s {
  1149			if ctxt.HeadType == objabi.Hdarwin {
  1150				// Recent versions of macOS print
  1151				//	ld: warning: option -s is obsolete and being ignored
  1152				// so do not pass any arguments.
  1153			} else {
  1154				argv = append(argv, "-s")
  1155			}
  1156		}
  1157	
  1158		switch ctxt.HeadType {
  1159		case objabi.Hdarwin:
  1160			argv = append(argv, "-Wl,-headerpad,1144")
  1161			if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
  1162				argv = append(argv, "-Wl,-flat_namespace")
  1163			}
  1164			if ctxt.BuildMode == BuildModeExe && !ctxt.Arch.InFamily(sys.ARM64) {
  1165				argv = append(argv, "-Wl,-no_pie")
  1166			}
  1167		case objabi.Hopenbsd:
  1168			argv = append(argv, "-Wl,-nopie")
  1169		case objabi.Hwindows:
  1170			if windowsgui {
  1171				argv = append(argv, "-mwindows")
  1172			} else {
  1173				argv = append(argv, "-mconsole")
  1174			}
  1175		case objabi.Haix:
  1176			argv = append(argv, "-pthread")
  1177			// prevent ld to reorder .text functions to keep the same
  1178			// first/last functions for moduledata.
  1179			argv = append(argv, "-Wl,-bnoobjreorder")
  1180			// mcmodel=large is needed for every gcc generated files, but
  1181			// ld still need -bbigtoc in order to allow larger TOC.
  1182			argv = append(argv, "-mcmodel=large")
  1183			argv = append(argv, "-Wl,-bbigtoc")
  1184		}
  1185	
  1186		switch ctxt.BuildMode {
  1187		case BuildModeExe:
  1188			if ctxt.HeadType == objabi.Hdarwin {
  1189				if ctxt.Arch.Family == sys.ARM64 {
  1190					// __PAGEZERO segment size determined empirically.
  1191					// XCode 9.0.1 successfully uploads an iOS app with this value.
  1192					argv = append(argv, "-Wl,-pagezero_size,100000000")
  1193				} else {
  1194					argv = append(argv, "-Wl,-pagezero_size,4000000")
  1195				}
  1196			}
  1197		case BuildModePIE:
  1198			// ELF.
  1199			if ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix {
  1200				if ctxt.UseRelro() {
  1201					argv = append(argv, "-Wl,-z,relro")
  1202				}
  1203				argv = append(argv, "-pie")
  1204			}
  1205		case BuildModeCShared:
  1206			if ctxt.HeadType == objabi.Hdarwin {
  1207				argv = append(argv, "-dynamiclib")
  1208				if ctxt.Arch.Family != sys.AMD64 {
  1209					argv = append(argv, "-Wl,-read_only_relocs,suppress")
  1210				}
  1211			} else {
  1212				// ELF.
  1213				argv = append(argv, "-Wl,-Bsymbolic")
  1214				if ctxt.UseRelro() {
  1215					argv = append(argv, "-Wl,-z,relro")
  1216				}
  1217				argv = append(argv, "-shared")
  1218				if ctxt.HeadType != objabi.Hwindows {
  1219					// Pass -z nodelete to mark the shared library as
  1220					// non-closeable: a dlclose will do nothing.
  1221					argv = append(argv, "-Wl,-z,nodelete")
  1222				}
  1223			}
  1224		case BuildModeShared:
  1225			if ctxt.UseRelro() {
  1226				argv = append(argv, "-Wl,-z,relro")
  1227			}
  1228			argv = append(argv, "-shared")
  1229		case BuildModePlugin:
  1230			if ctxt.HeadType == objabi.Hdarwin {
  1231				argv = append(argv, "-dynamiclib")
  1232			} else {
  1233				if ctxt.UseRelro() {
  1234					argv = append(argv, "-Wl,-z,relro")
  1235				}
  1236				argv = append(argv, "-shared")
  1237			}
  1238		}
  1239	
  1240		if ctxt.IsELF && ctxt.DynlinkingGo() {
  1241			// We force all symbol resolution to be done at program startup
  1242			// because lazy PLT resolution can use large amounts of stack at
  1243			// times we cannot allow it to do so.
  1244			argv = append(argv, "-Wl,-znow")
  1245	
  1246			// Do not let the host linker generate COPY relocations. These
  1247			// can move symbols out of sections that rely on stable offsets
  1248			// from the beginning of the section (like sym.STYPE).
  1249			argv = append(argv, "-Wl,-znocopyreloc")
  1250	
  1251			if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
  1252				// On ARM, the GNU linker will generate COPY relocations
  1253				// even with -znocopyreloc set.
  1254				// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
  1255				//
  1256				// On ARM64, the GNU linker will fail instead of
  1257				// generating COPY relocations.
  1258				//
  1259				// In both cases, switch to gold.
  1260				argv = append(argv, "-fuse-ld=gold")
  1261	
  1262				// If gold is not installed, gcc will silently switch
  1263				// back to ld.bfd. So we parse the version information
  1264				// and provide a useful error if gold is missing.
  1265				cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version")
  1266				if out, err := cmd.CombinedOutput(); err == nil {
  1267					if !bytes.Contains(out, []byte("GNU gold")) {
  1268						log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
  1269					}
  1270				}
  1271			}
  1272		}
  1273	
  1274		if ctxt.IsELF && len(buildinfo) > 0 {
  1275			argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
  1276		}
  1277	
  1278		// On Windows, given -o foo, GCC will append ".exe" to produce
  1279		// "foo.exe".  We have decided that we want to honor the -o
  1280		// option. To make this work, we append a '.' so that GCC
  1281		// will decide that the file already has an extension. We
  1282		// only want to do this when producing a Windows output file
  1283		// on a Windows host.
  1284		outopt := *flagOutfile
  1285		if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
  1286			outopt += "."
  1287		}
  1288		argv = append(argv, "-o")
  1289		argv = append(argv, outopt)
  1290	
  1291		if rpath.val != "" {
  1292			argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
  1293		}
  1294	
  1295		// Force global symbols to be exported for dlopen, etc.
  1296		if ctxt.IsELF {
  1297			argv = append(argv, "-rdynamic")
  1298		}
  1299		if ctxt.HeadType == objabi.Haix {
  1300			fileName := xcoffCreateExportFile(ctxt)
  1301			argv = append(argv, "-Wl,-bE:"+fileName)
  1302		}
  1303	
  1304		if strings.Contains(argv[0], "clang") {
  1305			argv = append(argv, "-Qunused-arguments")
  1306		}
  1307	
  1308		const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
  1309		if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) {
  1310			argv = append(argv, compressDWARF)
  1311		}
  1312	
  1313		argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
  1314		argv = append(argv, hostobjCopy()...)
  1315		if ctxt.HeadType == objabi.Haix {
  1316			// We want to have C files after Go files to remove
  1317			// trampolines csects made by ld.
  1318			argv = append(argv, "-nostartfiles")
  1319			argv = append(argv, "/lib/crt0_64.o")
  1320	
  1321			extld := ctxt.extld()
  1322			// Get starting files.
  1323			getPathFile := func(file string) string {
  1324				args := []string{"-maix64", "--print-file-name=" + file}
  1325				out, err := exec.Command(extld, args...).CombinedOutput()
  1326				if err != nil {
  1327					log.Fatalf("running %s failed: %v\n%s", extld, err, out)
  1328				}
  1329				return strings.Trim(string(out), "\n")
  1330			}
  1331			argv = append(argv, getPathFile("crtcxa.o"))
  1332			argv = append(argv, getPathFile("crtdbase.o"))
  1333		}
  1334	
  1335		if ctxt.linkShared {
  1336			seenDirs := make(map[string]bool)
  1337			seenLibs := make(map[string]bool)
  1338			addshlib := func(path string) {
  1339				dir, base := filepath.Split(path)
  1340				if !seenDirs[dir] {
  1341					argv = append(argv, "-L"+dir)
  1342					if !rpath.set {
  1343						argv = append(argv, "-Wl,-rpath="+dir)
  1344					}
  1345					seenDirs[dir] = true
  1346				}
  1347				base = strings.TrimSuffix(base, ".so")
  1348				base = strings.TrimPrefix(base, "lib")
  1349				if !seenLibs[base] {
  1350					argv = append(argv, "-l"+base)
  1351					seenLibs[base] = true
  1352				}
  1353			}
  1354			for _, shlib := range ctxt.Shlibs {
  1355				addshlib(shlib.Path)
  1356				for _, dep := range shlib.Deps {
  1357					if dep == "" {
  1358						continue
  1359					}
  1360					libpath := findshlib(ctxt, dep)
  1361					if libpath != "" {
  1362						addshlib(libpath)
  1363					}
  1364				}
  1365			}
  1366		}
  1367	
  1368		// clang, unlike GCC, passes -rdynamic to the linker
  1369		// even when linking with -static, causing a linker
  1370		// error when using GNU ld. So take out -rdynamic if
  1371		// we added it. We do it in this order, rather than
  1372		// only adding -rdynamic later, so that -*extldflags
  1373		// can override -rdynamic without using -static.
  1374		checkStatic := func(arg string) {
  1375			if ctxt.IsELF && arg == "-static" {
  1376				for i := range argv {
  1377					if argv[i] == "-rdynamic" {
  1378						argv[i] = "-static"
  1379					}
  1380				}
  1381			}
  1382		}
  1383	
  1384		for _, p := range ldflag {
  1385			argv = append(argv, p)
  1386			checkStatic(p)
  1387		}
  1388	
  1389		// When building a program with the default -buildmode=exe the
  1390		// gc compiler generates code requires DT_TEXTREL in a
  1391		// position independent executable (PIE). On systems where the
  1392		// toolchain creates PIEs by default, and where DT_TEXTREL
  1393		// does not work, the resulting programs will not run. See
  1394		// issue #17847. To avoid this problem pass -no-pie to the
  1395		// toolchain if it is supported.
  1396		if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
  1397			// GCC uses -no-pie, clang uses -nopie.
  1398			for _, nopie := range []string{"-no-pie", "-nopie"} {
  1399				if linkerFlagSupported(argv[0], nopie) {
  1400					argv = append(argv, nopie)
  1401					break
  1402				}
  1403			}
  1404		}
  1405	
  1406		for _, p := range strings.Fields(*flagExtldflags) {
  1407			argv = append(argv, p)
  1408			checkStatic(p)
  1409		}
  1410		if ctxt.HeadType == objabi.Hwindows {
  1411			// use gcc linker script to work around gcc bug
  1412			// (see https://golang.org/issue/20183 for details).
  1413			p := writeGDBLinkerScript()
  1414			argv = append(argv, "-Wl,-T,"+p)
  1415			// libmingw32 and libmingwex have some inter-dependencies,
  1416			// so must use linker groups.
  1417			argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
  1418			argv = append(argv, peimporteddlls()...)
  1419		}
  1420	
  1421		if ctxt.Debugvlog != 0 {
  1422			ctxt.Logf("%5.2f host link:", Cputime())
  1423			for _, v := range argv {
  1424				ctxt.Logf(" %q", v)
  1425			}
  1426			ctxt.Logf("\n")
  1427		}
  1428	
  1429		out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
  1430		if err != nil {
  1431			Exitf("running %s failed: %v\n%s", argv[0], err, out)
  1432		}
  1433	
  1434		// Filter out useless linker warnings caused by bugs outside Go.
  1435		// See also cmd/go/internal/work/exec.go's gccld method.
  1436		var save [][]byte
  1437		var skipLines int
  1438		for _, line := range bytes.SplitAfter(out, []byte("\n")) {
  1439			// golang.org/issue/26073 - Apple Xcode bug
  1440			if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
  1441				continue
  1442			}
  1443	
  1444			if skipLines > 0 {
  1445				skipLines--
  1446				continue
  1447			}
  1448	
  1449			// Remove TOC overflow warning on AIX.
  1450			if bytes.Contains(line, []byte("ld: 0711-783")) {
  1451				skipLines = 2
  1452				continue
  1453			}
  1454	
  1455			save = append(save, line)
  1456		}
  1457		out = bytes.Join(save, nil)
  1458	
  1459		if len(out) > 0 {
  1460			// always print external output even if the command is successful, so that we don't
  1461			// swallow linker warnings (see https://golang.org/issue/17935).
  1462			ctxt.Logf("%s", out)
  1463		}
  1464	
  1465		if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
  1466			dsym := filepath.Join(*flagTmpdir, "go.dwarf")
  1467			if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
  1468				Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
  1469			}
  1470			// Skip combining if `dsymutil` didn't generate a file. See #11994.
  1471			if _, err := os.Stat(dsym); os.IsNotExist(err) {
  1472				return
  1473			}
  1474			// For os.Rename to work reliably, must be in same directory as outfile.
  1475			combinedOutput := *flagOutfile + "~"
  1476			exef, err := os.Open(*flagOutfile)
  1477			if err != nil {
  1478				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1479			}
  1480			defer exef.Close()
  1481			exem, err := macho.NewFile(exef)
  1482			if err != nil {
  1483				Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
  1484			}
  1485			// Only macOS supports unmapped segments such as our __DWARF segment.
  1486			if machoPlatform == PLATFORM_MACOS {
  1487				if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
  1488					Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
  1489				}
  1490				os.Remove(*flagOutfile)
  1491				if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
  1492					Exitf("%s: %v", os.Args[0], err)
  1493				}
  1494			}
  1495		}
  1496	}
  1497	
  1498	var createTrivialCOnce sync.Once
  1499	
  1500	func linkerFlagSupported(linker, flag string) bool {
  1501		createTrivialCOnce.Do(func() {
  1502			src := filepath.Join(*flagTmpdir, "trivial.c")
  1503			if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
  1504				Errorf(nil, "WriteFile trivial.c failed: %v", err)
  1505			}
  1506		})
  1507	
  1508		flagsWithNextArgSkip := []string{
  1509			"-F",
  1510			"-l",
  1511			"-L",
  1512			"-framework",
  1513			"-Wl,-framework",
  1514			"-Wl,-rpath",
  1515			"-Wl,-undefined",
  1516		}
  1517		flagsWithNextArgKeep := []string{
  1518			"-arch",
  1519			"-isysroot",
  1520			"--sysroot",
  1521			"-target",
  1522		}
  1523		prefixesToKeep := []string{
  1524			"-f",
  1525			"-m",
  1526			"-p",
  1527			"-Wl,",
  1528			"-arch",
  1529			"-isysroot",
  1530			"--sysroot",
  1531			"-target",
  1532		}
  1533	
  1534		var flags []string
  1535		keep := false
  1536		skip := false
  1537		extldflags := strings.Fields(*flagExtldflags)
  1538		for _, f := range append(extldflags, ldflag...) {
  1539			if keep {
  1540				flags = append(flags, f)
  1541				keep = false
  1542			} else if skip {
  1543				skip = false
  1544			} else if f == "" || f[0] != '-' {
  1545			} else if contains(flagsWithNextArgSkip, f) {
  1546				skip = true
  1547			} else if contains(flagsWithNextArgKeep, f) {
  1548				flags = append(flags, f)
  1549				keep = true
  1550			} else {
  1551				for _, p := range prefixesToKeep {
  1552					if strings.HasPrefix(f, p) {
  1553						flags = append(flags, f)
  1554						break
  1555					}
  1556				}
  1557			}
  1558		}
  1559	
  1560		flags = append(flags, flag, "trivial.c")
  1561	
  1562		cmd := exec.Command(linker, flags...)
  1563		cmd.Dir = *flagTmpdir
  1564		cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
  1565		out, err := cmd.CombinedOutput()
  1566		// GCC says "unrecognized command line option ‘-no-pie’"
  1567		// clang says "unknown argument: '-no-pie'"
  1568		return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
  1569	}
  1570	
  1571	// hostlinkArchArgs returns arguments to pass to the external linker
  1572	// based on the architecture.
  1573	func hostlinkArchArgs(arch *sys.Arch) []string {
  1574		switch arch.Family {
  1575		case sys.I386:
  1576			return []string{"-m32"}
  1577		case sys.AMD64, sys.S390X:
  1578			return []string{"-m64"}
  1579		case sys.ARM:
  1580			return []string{"-marm"}
  1581		case sys.ARM64:
  1582			// nothing needed
  1583		case sys.MIPS64:
  1584			return []string{"-mabi=64"}
  1585		case sys.MIPS:
  1586			return []string{"-mabi=32"}
  1587		case sys.PPC64:
  1588			if objabi.GOOS == "aix" {
  1589				return []string{"-maix64"}
  1590			} else {
  1591				return []string{"-m64"}
  1592			}
  1593	
  1594		}
  1595		return nil
  1596	}
  1597	
  1598	// ldobj loads an input object. If it is a host object (an object
  1599	// compiled by a non-Go compiler) it returns the Hostobj pointer. If
  1600	// it is a Go object, it returns nil.
  1601	func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
  1602		pkg := objabi.PathToPrefix(lib.Pkg)
  1603	
  1604		eof := f.Offset() + length
  1605		start := f.Offset()
  1606		c1 := bgetc(f)
  1607		c2 := bgetc(f)
  1608		c3 := bgetc(f)
  1609		c4 := bgetc(f)
  1610		f.MustSeek(start, 0)
  1611	
  1612		magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
  1613		if magic == 0x7f454c46 { // \x7F E L F
  1614			ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1615				textp, flags, err := loadelf.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
  1616				if err != nil {
  1617					Errorf(nil, "%v", err)
  1618					return
  1619				}
  1620				ehdr.flags = flags
  1621				ctxt.Textp = append(ctxt.Textp, textp...)
  1622			}
  1623			return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
  1624		}
  1625	
  1626		if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
  1627			ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1628				textp, err := loadmacho.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1629				if err != nil {
  1630					Errorf(nil, "%v", err)
  1631					return
  1632				}
  1633				ctxt.Textp = append(ctxt.Textp, textp...)
  1634			}
  1635			return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
  1636		}
  1637	
  1638		if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
  1639			ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1640				textp, rsrc, err := loadpe.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1641				if err != nil {
  1642					Errorf(nil, "%v", err)
  1643					return
  1644				}
  1645				if rsrc != nil {
  1646					setpersrc(ctxt, rsrc)
  1647				}
  1648				ctxt.Textp = append(ctxt.Textp, textp...)
  1649			}
  1650			return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
  1651		}
  1652	
  1653		if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
  1654			ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
  1655				textp, err := loadxcoff.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
  1656				if err != nil {
  1657					Errorf(nil, "%v", err)
  1658					return
  1659				}
  1660				ctxt.Textp = append(ctxt.Textp, textp...)
  1661			}
  1662			return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
  1663		}
  1664	
  1665		/* check the header */
  1666		line, err := f.ReadString('\n')
  1667		if err != nil {
  1668			Errorf(nil, "truncated object file: %s: %v", pn, err)
  1669			return nil
  1670		}
  1671	
  1672		if !strings.HasPrefix(line, "go object ") {
  1673			if strings.HasSuffix(pn, ".go") {
  1674				Exitf("%s: uncompiled .go source file", pn)
  1675				return nil
  1676			}
  1677	
  1678			if line == ctxt.Arch.Name {
  1679				// old header format: just $GOOS
  1680				Errorf(nil, "%s: stale object file", pn)
  1681				return nil
  1682			}
  1683	
  1684			Errorf(nil, "%s: not an object file", pn)
  1685			return nil
  1686		}
  1687	
  1688		// First, check that the basic GOOS, GOARCH, and Version match.
  1689		t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
  1690	
  1691		line = strings.TrimRight(line, "\n")
  1692		if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
  1693			Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
  1694			return nil
  1695		}
  1696	
  1697		// Second, check that longer lines match each other exactly,
  1698		// so that the Go compiler and write additional information
  1699		// that must be the same from run to run.
  1700		if len(line) >= len(t)+10 {
  1701			if theline == "" {
  1702				theline = line[10:]
  1703			} else if theline != line[10:] {
  1704				Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
  1705				return nil
  1706			}
  1707		}
  1708	
  1709		// Skip over exports and other info -- ends with \n!\n.
  1710		//
  1711		// Note: It's possible for "\n!\n" to appear within the binary
  1712		// package export data format. To avoid truncating the package
  1713		// definition prematurely (issue 21703), we keep track of
  1714		// how many "$$" delimiters we've seen.
  1715	
  1716		import0 := f.Offset()
  1717	
  1718		c1 = '\n' // the last line ended in \n
  1719		c2 = bgetc(f)
  1720		c3 = bgetc(f)
  1721		markers := 0
  1722		for {
  1723			if c1 == '\n' {
  1724				if markers%2 == 0 && c2 == '!' && c3 == '\n' {
  1725					break
  1726				}
  1727				if c2 == '$' && c3 == '$' {
  1728					markers++
  1729				}
  1730			}
  1731	
  1732			c1 = c2
  1733			c2 = c3
  1734			c3 = bgetc(f)
  1735			if c3 == -1 {
  1736				Errorf(nil, "truncated object file: %s", pn)
  1737				return nil
  1738			}
  1739		}
  1740	
  1741		import1 := f.Offset()
  1742	
  1743		f.MustSeek(import0, 0)
  1744		ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
  1745		f.MustSeek(import1, 0)
  1746	
  1747		flags := 0
  1748		switch *FlagStrictDups {
  1749		case 0:
  1750			break
  1751		case 1:
  1752			flags = objfile.StrictDupsWarnFlag
  1753		case 2:
  1754			flags = objfile.StrictDupsErrFlag
  1755		default:
  1756			log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
  1757		}
  1758		c := objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, eof-f.Offset(), pn, flags)
  1759		strictDupMsgCount += c
  1760		addImports(ctxt, lib, pn)
  1761		return nil
  1762	}
  1763	
  1764	func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
  1765		data := make([]byte, sym.Size)
  1766		sect := f.Sections[sym.Section]
  1767		if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
  1768			Errorf(nil, "reading %s from non-data section", sym.Name)
  1769		}
  1770		n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
  1771		if uint64(n) != sym.Size {
  1772			Errorf(nil, "reading contents of %s: %v", sym.Name, err)
  1773		}
  1774		return data
  1775	}
  1776	
  1777	func readwithpad(r io.Reader, sz int32) ([]byte, error) {
  1778		data := make([]byte, Rnd(int64(sz), 4))
  1779		_, err := io.ReadFull(r, data)
  1780		if err != nil {
  1781			return nil, err
  1782		}
  1783		data = data[:sz]
  1784		return data, nil
  1785	}
  1786	
  1787	func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
  1788		for _, sect := range f.Sections {
  1789			if sect.Type != elf.SHT_NOTE {
  1790				continue
  1791			}
  1792			r := sect.Open()
  1793			for {
  1794				var namesize, descsize, noteType int32
  1795				err := binary.Read(r, f.ByteOrder, &namesize)
  1796				if err != nil {
  1797					if err == io.EOF {
  1798						break
  1799					}
  1800					return nil, fmt.Errorf("read namesize failed: %v", err)
  1801				}
  1802				err = binary.Read(r, f.ByteOrder, &descsize)
  1803				if err != nil {
  1804					return nil, fmt.Errorf("read descsize failed: %v", err)
  1805				}
  1806				err = binary.Read(r, f.ByteOrder, &noteType)
  1807				if err != nil {
  1808					return nil, fmt.Errorf("read type failed: %v", err)
  1809				}
  1810				noteName, err := readwithpad(r, namesize)
  1811				if err != nil {
  1812					return nil, fmt.Errorf("read name failed: %v", err)
  1813				}
  1814				desc, err := readwithpad(r, descsize)
  1815				if err != nil {
  1816					return nil, fmt.Errorf("read desc failed: %v", err)
  1817				}
  1818				if string(name) == string(noteName) && typ == noteType {
  1819					return desc, nil
  1820				}
  1821			}
  1822		}
  1823		return nil, nil
  1824	}
  1825	
  1826	func findshlib(ctxt *Link, shlib string) string {
  1827		if filepath.IsAbs(shlib) {
  1828			return shlib
  1829		}
  1830		for _, libdir := range ctxt.Libdir {
  1831			libpath := filepath.Join(libdir, shlib)
  1832			if _, err := os.Stat(libpath); err == nil {
  1833				return libpath
  1834			}
  1835		}
  1836		Errorf(nil, "cannot find shared library: %s", shlib)
  1837		return ""
  1838	}
  1839	
  1840	func ldshlibsyms(ctxt *Link, shlib string) {
  1841		var libpath string
  1842		if filepath.IsAbs(shlib) {
  1843			libpath = shlib
  1844			shlib = filepath.Base(shlib)
  1845		} else {
  1846			libpath = findshlib(ctxt, shlib)
  1847			if libpath == "" {
  1848				return
  1849			}
  1850		}
  1851		for _, processedlib := range ctxt.Shlibs {
  1852			if processedlib.Path == libpath {
  1853				return
  1854			}
  1855		}
  1856		if ctxt.Debugvlog > 1 {
  1857			ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath)
  1858		}
  1859	
  1860		f, err := elf.Open(libpath)
  1861		if err != nil {
  1862			Errorf(nil, "cannot open shared library: %s", libpath)
  1863			return
  1864		}
  1865		defer f.Close()
  1866	
  1867		hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
  1868		if err != nil {
  1869			Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
  1870			return
  1871		}
  1872	
  1873		depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
  1874		if err != nil {
  1875			Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
  1876			return
  1877		}
  1878		var deps []string
  1879		for _, dep := range strings.Split(string(depsbytes), "\n") {
  1880			if dep == "" {
  1881				continue
  1882			}
  1883			if !filepath.IsAbs(dep) {
  1884				// If the dep can be interpreted as a path relative to the shlib
  1885				// in which it was found, do that. Otherwise, we will leave it
  1886				// to be resolved by libdir lookup.
  1887				abs := filepath.Join(filepath.Dir(libpath), dep)
  1888				if _, err := os.Stat(abs); err == nil {
  1889					dep = abs
  1890				}
  1891			}
  1892			deps = append(deps, dep)
  1893		}
  1894	
  1895		syms, err := f.DynamicSymbols()
  1896		if err != nil {
  1897			Errorf(nil, "cannot read symbols from shared library: %s", libpath)
  1898			return
  1899		}
  1900		gcdataLocations := make(map[uint64]*sym.Symbol)
  1901		for _, elfsym := range syms {
  1902			if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
  1903				continue
  1904			}
  1905	
  1906			// Symbols whose names start with "type." are compiler
  1907			// generated, so make functions with that prefix internal.
  1908			ver := 0
  1909			if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
  1910				ver = sym.SymVerABIInternal
  1911			}
  1912	
  1913			lsym := ctxt.Syms.Lookup(elfsym.Name, ver)
  1914			// Because loadlib above loads all .a files before loading any shared
  1915			// libraries, any non-dynimport symbols we find that duplicate symbols
  1916			// already loaded should be ignored (the symbols from the .a files
  1917			// "win").
  1918			if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
  1919				continue
  1920			}
  1921			lsym.Type = sym.SDYNIMPORT
  1922			lsym.SetElfType(elf.ST_TYPE(elfsym.Info))
  1923			lsym.Size = int64(elfsym.Size)
  1924			if elfsym.Section != elf.SHN_UNDEF {
  1925				// Set .File for the library that actually defines the symbol.
  1926				lsym.File = libpath
  1927				// The decodetype_* functions in decodetype.go need access to
  1928				// the type data.
  1929				if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
  1930					lsym.P = readelfsymboldata(ctxt, f, &elfsym)
  1931					gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
  1932				}
  1933			}
  1934			// For function symbols, we don't know what ABI is
  1935			// available, so alias it under both ABIs.
  1936			//
  1937			// TODO(austin): This is almost certainly wrong once
  1938			// the ABIs are actually different. We might have to
  1939			// mangle Go function names in the .so to include the
  1940			// ABI.
  1941			if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
  1942				alias := ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal)
  1943				if alias.Type != 0 {
  1944					continue
  1945				}
  1946				alias.Type = sym.SABIALIAS
  1947				alias.R = []sym.Reloc{{Sym: lsym}}
  1948			}
  1949		}
  1950		gcdataAddresses := make(map[*sym.Symbol]uint64)
  1951		if ctxt.Arch.Family == sys.ARM64 {
  1952			for _, sect := range f.Sections {
  1953				if sect.Type == elf.SHT_RELA {
  1954					var rela elf.Rela64
  1955					rdr := sect.Open()
  1956					for {
  1957						err := binary.Read(rdr, f.ByteOrder, &rela)
  1958						if err == io.EOF {
  1959							break
  1960						} else if err != nil {
  1961							Errorf(nil, "reading relocation failed %v", err)
  1962							return
  1963						}
  1964						t := elf.R_AARCH64(rela.Info & 0xffff)
  1965						if t != elf.R_AARCH64_RELATIVE {
  1966							continue
  1967						}
  1968						if lsym, ok := gcdataLocations[rela.Off]; ok {
  1969							gcdataAddresses[lsym] = uint64(rela.Addend)
  1970						}
  1971					}
  1972				}
  1973			}
  1974		}
  1975	
  1976		ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
  1977	}
  1978	
  1979	func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
  1980		sect := new(sym.Section)
  1981		sect.Rwx = uint8(rwx)
  1982		sect.Name = name
  1983		sect.Seg = seg
  1984		sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
  1985		seg.Sections = append(seg.Sections, sect)
  1986		return sect
  1987	}
  1988	
  1989	type chain struct {
  1990		sym   *sym.Symbol
  1991		up    *chain
  1992		limit int // limit on entry to sym
  1993	}
  1994	
  1995	var morestack *sym.Symbol
  1996	
  1997	// TODO: Record enough information in new object files to
  1998	// allow stack checks here.
  1999	
  2000	func haslinkregister(ctxt *Link) bool {
  2001		return ctxt.FixedFrameSize() != 0
  2002	}
  2003	
  2004	func callsize(ctxt *Link) int {
  2005		if haslinkregister(ctxt) {
  2006			return 0
  2007		}
  2008		return ctxt.Arch.RegSize
  2009	}
  2010	
  2011	func (ctxt *Link) dostkcheck() {
  2012		var ch chain
  2013	
  2014		morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
  2015	
  2016		// Every splitting function ensures that there are at least StackLimit
  2017		// bytes available below SP when the splitting prologue finishes.
  2018		// If the splitting function calls F, then F begins execution with
  2019		// at least StackLimit - callsize() bytes available.
  2020		// Check that every function behaves correctly with this amount
  2021		// of stack, following direct calls in order to piece together chains
  2022		// of non-splitting functions.
  2023		ch.up = nil
  2024	
  2025		ch.limit = objabi.StackLimit - callsize(ctxt)
  2026		if objabi.GOARCH == "arm64" {
  2027			// need extra 8 bytes below SP to save FP
  2028			ch.limit -= 8
  2029		}
  2030	
  2031		// Check every function, but do the nosplit functions in a first pass,
  2032		// to make the printed failure chains as short as possible.
  2033		for _, s := range ctxt.Textp {
  2034			// runtime.racesymbolizethunk is called from gcc-compiled C
  2035			// code running on the operating system thread stack.
  2036			// It uses more than the usual amount of stack but that's okay.
  2037			if s.Name == "runtime.racesymbolizethunk" {
  2038				continue
  2039			}
  2040	
  2041			if s.Attr.NoSplit() {
  2042				ch.sym = s
  2043				stkcheck(ctxt, &ch, 0)
  2044			}
  2045		}
  2046	
  2047		for _, s := range ctxt.Textp {
  2048			if !s.Attr.NoSplit() {
  2049				ch.sym = s
  2050				stkcheck(ctxt, &ch, 0)
  2051			}
  2052		}
  2053	}
  2054	
  2055	func stkcheck(ctxt *Link, up *chain, depth int) int {
  2056		limit := up.limit
  2057		s := up.sym
  2058	
  2059		// Don't duplicate work: only need to consider each
  2060		// function at top of safe zone once.
  2061		top := limit == objabi.StackLimit-callsize(ctxt)
  2062		if top {
  2063			if s.Attr.StackCheck() {
  2064				return 0
  2065			}
  2066			s.Attr |= sym.AttrStackCheck
  2067		}
  2068	
  2069		if depth > 500 {
  2070			Errorf(s, "nosplit stack check too deep")
  2071			stkbroke(ctxt, up, 0)
  2072			return -1
  2073		}
  2074	
  2075		if s.Attr.External() || s.FuncInfo == nil {
  2076			// external function.
  2077			// should never be called directly.
  2078			// onlyctxt.Diagnose the direct caller.
  2079			// TODO(mwhudson): actually think about this.
  2080			// TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack.
  2081			// See the trampolines in src/runtime/sys_darwin_$ARCH.go.
  2082			if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
  2083				ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
  2084				//Errorf(s, "call to external function")
  2085			}
  2086			return -1
  2087		}
  2088	
  2089		if limit < 0 {
  2090			stkbroke(ctxt, up, limit)
  2091			return -1
  2092		}
  2093	
  2094		// morestack looks like it calls functions,
  2095		// but it switches the stack pointer first.
  2096		if s == morestack {
  2097			return 0
  2098		}
  2099	
  2100		var ch chain
  2101		ch.up = up
  2102	
  2103		if !s.Attr.NoSplit() {
  2104			// Ensure we have enough stack to call morestack.
  2105			ch.limit = limit - callsize(ctxt)
  2106			ch.sym = morestack
  2107			if stkcheck(ctxt, &ch, depth+1) < 0 {
  2108				return -1
  2109			}
  2110			if !top {
  2111				return 0
  2112			}
  2113			// Raise limit to allow frame.
  2114			locals := int32(0)
  2115			if s.FuncInfo != nil {
  2116				locals = s.FuncInfo.Locals
  2117			}
  2118			limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize())
  2119		}
  2120	
  2121		// Walk through sp adjustments in function, consuming relocs.
  2122		ri := 0
  2123	
  2124		endr := len(s.R)
  2125		var ch1 chain
  2126		pcsp := newPCIter(ctxt)
  2127		var r *sym.Reloc
  2128		for pcsp.init(s.FuncInfo.Pcsp.P); !pcsp.done; pcsp.next() {
  2129			// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  2130	
  2131			// Check stack size in effect for this span.
  2132			if int32(limit)-pcsp.value < 0 {
  2133				stkbroke(ctxt, up, int(int32(limit)-pcsp.value))
  2134				return -1
  2135			}
  2136	
  2137			// Process calls in this span.
  2138			for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
  2139				r = &s.R[ri]
  2140				switch r.Type {
  2141				// Direct call.
  2142				case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS:
  2143					ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  2144					ch.sym = r.Sym
  2145					if stkcheck(ctxt, &ch, depth+1) < 0 {
  2146						return -1
  2147					}
  2148	
  2149				// Indirect call. Assume it is a call to a splitting function,
  2150				// so we have to make sure it can call morestack.
  2151				// Arrange the data structures to report both calls, so that
  2152				// if there is an error, stkprint shows all the steps involved.
  2153				case objabi.R_CALLIND:
  2154					ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
  2155	
  2156					ch.sym = nil
  2157					ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
  2158					ch1.up = &ch
  2159					ch1.sym = morestack
  2160					if stkcheck(ctxt, &ch1, depth+2) < 0 {
  2161						return -1
  2162					}
  2163				}
  2164			}
  2165		}
  2166	
  2167		return 0
  2168	}
  2169	
  2170	func stkbroke(ctxt *Link, ch *chain, limit int) {
  2171		Errorf(ch.sym, "nosplit stack overflow")
  2172		stkprint(ctxt, ch, limit)
  2173	}
  2174	
  2175	func stkprint(ctxt *Link, ch *chain, limit int) {
  2176		var name string
  2177	
  2178		if ch.sym != nil {
  2179			name = ch.sym.Name
  2180			if ch.sym.Attr.NoSplit() {
  2181				name += " (nosplit)"
  2182			}
  2183		} else {
  2184			name = "function pointer"
  2185		}
  2186	
  2187		if ch.up == nil {
  2188			// top of chain.  ch->sym != nil.
  2189			if ch.sym.Attr.NoSplit() {
  2190				fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
  2191			} else {
  2192				fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
  2193			}
  2194		} else {
  2195			stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
  2196			if !haslinkregister(ctxt) {
  2197				fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
  2198			}
  2199		}
  2200	
  2201		if ch.limit != limit {
  2202			fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
  2203		}
  2204	}
  2205	
  2206	func usage() {
  2207		fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
  2208		objabi.Flagprint(os.Stderr)
  2209		Exit(2)
  2210	}
  2211	
  2212	type SymbolType int8
  2213	
  2214	const (
  2215		// see also https://9p.io/magic/man2html/1/nm
  2216		TextSym      SymbolType = 'T'
  2217		DataSym      SymbolType = 'D'
  2218		BSSSym       SymbolType = 'B'
  2219		UndefinedSym SymbolType = 'U'
  2220		TLSSym       SymbolType = 't'
  2221		FrameSym     SymbolType = 'm'
  2222		ParamSym     SymbolType = 'p'
  2223		AutoSym      SymbolType = 'a'
  2224	
  2225		// Deleted auto (not a real sym, just placeholder for type)
  2226		DeletedAutoSym = 'x'
  2227	)
  2228	
  2229	func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
  2230		// These symbols won't show up in the first loop below because we
  2231		// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
  2232		s := ctxt.Syms.Lookup("runtime.text", 0)
  2233		if s.Type == sym.STEXT {
  2234			// We've already included this symbol in ctxt.Textp
  2235			// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
  2236			// on AIX with external linker.
  2237			// See data.go:/textaddress
  2238			if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2239				put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2240			}
  2241		}
  2242	
  2243		n := 0
  2244	
  2245		// Generate base addresses for all text sections if there are multiple
  2246		for _, sect := range Segtext.Sections {
  2247			if n == 0 {
  2248				n++
  2249				continue
  2250			}
  2251			if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2252				// On AIX, runtime.text.X are symbols already in the symtab.
  2253				break
  2254			}
  2255			s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
  2256			if s == nil {
  2257				break
  2258			}
  2259			if s.Type == sym.STEXT {
  2260				put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2261			}
  2262			n++
  2263		}
  2264	
  2265		s = ctxt.Syms.Lookup("runtime.etext", 0)
  2266		if s.Type == sym.STEXT {
  2267			// We've already included this symbol in ctxt.Textp
  2268			// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
  2269			// on AIX with external linker.
  2270			// See data.go:/textaddress
  2271			if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
  2272				put(ctxt, s, s.Name, TextSym, s.Value, nil)
  2273			}
  2274		}
  2275	
  2276		shouldBeInSymbolTable := func(s *sym.Symbol) bool {
  2277			if s.Attr.NotInSymbolTable() {
  2278				return false
  2279			}
  2280			if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" {
  2281				// On AIX, .go.buildinfo must be in the symbol table as
  2282				// it has relocations.
  2283				return true
  2284			}
  2285			if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
  2286				return false
  2287			}
  2288			return true
  2289		}
  2290	
  2291		for _, s := range ctxt.Syms.Allsym {
  2292			if !shouldBeInSymbolTable(s) {
  2293				continue
  2294			}
  2295			switch s.Type {
  2296			case sym.SCONST,
  2297				sym.SRODATA,
  2298				sym.SSYMTAB,
  2299				sym.SPCLNTAB,
  2300				sym.SINITARR,
  2301				sym.SDATA,
  2302				sym.SNOPTRDATA,
  2303				sym.SELFROSECT,
  2304				sym.SMACHOGOT,
  2305				sym.STYPE,
  2306				sym.SSTRING,
  2307				sym.SGOSTRING,
  2308				sym.SGOFUNC,
  2309				sym.SGCBITS,
  2310				sym.STYPERELRO,
  2311				sym.SSTRINGRELRO,
  2312				sym.SGOSTRINGRELRO,
  2313				sym.SGOFUNCRELRO,
  2314				sym.SGCBITSRELRO,
  2315				sym.SRODATARELRO,
  2316				sym.STYPELINK,
  2317				sym.SITABLINK,
  2318				sym.SWINDOWS:
  2319				if !s.Attr.Reachable() {
  2320					continue
  2321				}
  2322				put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
  2323	
  2324			case sym.SBSS, sym.SNOPTRBSS:
  2325				if !s.Attr.Reachable() {
  2326					continue
  2327				}
  2328				if len(s.P) > 0 {
  2329					Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
  2330				}
  2331				put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
  2332	
  2333			case sym.SHOSTOBJ:
  2334				if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
  2335					put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
  2336				}
  2337	
  2338			case sym.SDYNIMPORT:
  2339				if !s.Attr.Reachable() {
  2340					continue
  2341				}
  2342				put(ctxt, s, s.Extname(), UndefinedSym, 0, nil)
  2343	
  2344			case sym.STLSBSS:
  2345				if ctxt.LinkMode == LinkExternal {
  2346					put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
  2347				}
  2348			}
  2349		}
  2350	
  2351		var off int32
  2352		for _, s := range ctxt.Textp {
  2353			put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
  2354	
  2355			locals := int32(0)
  2356			if s.FuncInfo != nil {
  2357				locals = s.FuncInfo.Locals
  2358			}
  2359			// NOTE(ality): acid can't produce a stack trace without .frame symbols
  2360			put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
  2361	
  2362			if s.FuncInfo == nil {
  2363				continue
  2364			}
  2365			for _, a := range s.FuncInfo.Autom {
  2366				if a.Name == objabi.A_DELETED_AUTO {
  2367					put(ctxt, nil, "", DeletedAutoSym, 0, a.Gotype)
  2368					continue
  2369				}
  2370	
  2371				// Emit a or p according to actual offset, even if label is wrong.
  2372				// This avoids negative offsets, which cannot be encoded.
  2373				if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM {
  2374					continue
  2375				}
  2376	
  2377				// compute offset relative to FP
  2378				if a.Name == objabi.A_PARAM {
  2379					off = a.Aoffset
  2380				} else {
  2381					off = a.Aoffset - int32(ctxt.Arch.PtrSize)
  2382				}
  2383	
  2384				// FP
  2385				if off >= 0 {
  2386					put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype)
  2387					continue
  2388				}
  2389	
  2390				// SP
  2391				if off <= int32(-ctxt.Arch.PtrSize) {
  2392					put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(ctxt.Arch.PtrSize)), a.Gotype)
  2393					continue
  2394				}
  2395				// Otherwise, off is addressing the saved program counter.
  2396				// Something underhanded is going on. Say nothing.
  2397			}
  2398		}
  2399	
  2400		if ctxt.Debugvlog != 0 || *flagN {
  2401			ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize))
  2402		}
  2403	}
  2404	
  2405	func Symaddr(s *sym.Symbol) int64 {
  2406		if !s.Attr.Reachable() {
  2407			Errorf(s, "unreachable symbol in symaddr")
  2408		}
  2409		return s.Value
  2410	}
  2411	
  2412	func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
  2413		s := ctxt.Syms.Lookup(p, 0)
  2414		s.Type = t
  2415		s.Value = v
  2416		s.Attr |= sym.AttrReachable
  2417		s.Attr |= sym.AttrSpecial
  2418		s.Attr |= sym.AttrLocal
  2419	}
  2420	
  2421	func datoff(s *sym.Symbol, addr int64) int64 {
  2422		if uint64(addr) >= Segdata.Vaddr {
  2423			return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
  2424		}
  2425		if uint64(addr) >= Segtext.Vaddr {
  2426			return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
  2427		}
  2428		Errorf(s, "invalid datoff %#x", addr)
  2429		return 0
  2430	}
  2431	
  2432	func Entryvalue(ctxt *Link) int64 {
  2433		a := *flagEntrySymbol
  2434		if a[0] >= '0' && a[0] <= '9' {
  2435			return atolwhex(a)
  2436		}
  2437		s := ctxt.Syms.Lookup(a, 0)
  2438		if s.Type == 0 {
  2439			return *FlagTextAddr
  2440		}
  2441		if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT {
  2442			Errorf(s, "entry not text")
  2443		}
  2444		return s.Value
  2445	}
  2446	
  2447	func undefsym(ctxt *Link, s *sym.Symbol) {
  2448		var r *sym.Reloc
  2449	
  2450		for i := 0; i < len(s.R); i++ {
  2451			r = &s.R[i]
  2452			if r.Sym == nil { // happens for some external ARM relocs
  2453				continue
  2454			}
  2455			// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
  2456			// sense and should be removed when someone has thought about it properly.
  2457			if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
  2458				Errorf(s, "undefined: %q", r.Sym.Name)
  2459			}
  2460			if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
  2461				Errorf(s, "relocation target %q", r.Sym.Name)
  2462			}
  2463		}
  2464	}
  2465	
  2466	func (ctxt *Link) undef() {
  2467		// undefsym performs checks (almost) identical to checks
  2468		// that report undefined relocations in relocsym.
  2469		// Both undefsym and relocsym can report same symbol as undefined,
  2470		// which results in error message duplication (see #10978).
  2471		//
  2472		// The undef is run after Arch.Asmb and could detect some
  2473		// programming errors there, but if object being linked is already
  2474		// failed with errors, it is better to avoid duplicated errors.
  2475		if nerrors > 0 {
  2476			return
  2477		}
  2478	
  2479		for _, s := range ctxt.Textp {
  2480			undefsym(ctxt, s)
  2481		}
  2482		for _, s := range datap {
  2483			undefsym(ctxt, s)
  2484		}
  2485		if nerrors > 0 {
  2486			errorexit()
  2487		}
  2488	}
  2489	
  2490	func (ctxt *Link) callgraph() {
  2491		if !*FlagC {
  2492			return
  2493		}
  2494	
  2495		var i int
  2496		var r *sym.Reloc
  2497		for _, s := range ctxt.Textp {
  2498			for i = 0; i < len(s.R); i++ {
  2499				r = &s.R[i]
  2500				if r.Sym == nil {
  2501					continue
  2502				}
  2503				if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == sym.STEXT {
  2504					ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
  2505				}
  2506			}
  2507		}
  2508	}
  2509	
  2510	func Rnd(v int64, r int64) int64 {
  2511		if r <= 0 {
  2512			return v
  2513		}
  2514		v += r - 1
  2515		c := v % r
  2516		if c < 0 {
  2517			c += r
  2518		}
  2519		v -= c
  2520		return v
  2521	}
  2522	
  2523	func bgetc(r *bio.Reader) int {
  2524		c, err := r.ReadByte()
  2525		if err != nil {
  2526			if err != io.EOF {
  2527				log.Fatalf("reading input: %v", err)
  2528			}
  2529			return -1
  2530		}
  2531		return int(c)
  2532	}
  2533	
  2534	type markKind uint8 // for postorder traversal
  2535	const (
  2536		_ markKind = iota
  2537		visiting
  2538		visited
  2539	)
  2540	
  2541	func postorder(libs []*sym.Library) []*sym.Library {
  2542		order := make([]*sym.Library, 0, len(libs)) // hold the result
  2543		mark := make(map[*sym.Library]markKind, len(libs))
  2544		for _, lib := range libs {
  2545			dfs(lib, mark, &order)
  2546		}
  2547		return order
  2548	}
  2549	
  2550	func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
  2551		if mark[lib] == visited {
  2552			return
  2553		}
  2554		if mark[lib] == visiting {
  2555			panic("found import cycle while visiting " + lib.Pkg)
  2556		}
  2557		mark[lib] = visiting
  2558		for _, i := range lib.Imports {
  2559			dfs(i, mark, order)
  2560		}
  2561		mark[lib] = visited
  2562		*order = append(*order, lib)
  2563	}
  2564	

View as plain text