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