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