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