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