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