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