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