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