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