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