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