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