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