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