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