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