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