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