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