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