]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/ld/lib.go
cmd/link: suppress -no_pie deprecation warning on darwin
[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         "cmd/internal/bio"
36         "cmd/internal/goobj"
37         "cmd/internal/notsha256"
38         "cmd/internal/objabi"
39         "cmd/internal/sys"
40         "cmd/link/internal/loadelf"
41         "cmd/link/internal/loader"
42         "cmd/link/internal/loadmacho"
43         "cmd/link/internal/loadpe"
44         "cmd/link/internal/loadxcoff"
45         "cmd/link/internal/sym"
46         "debug/elf"
47         "debug/macho"
48         "encoding/base64"
49         "encoding/binary"
50         "fmt"
51         "internal/buildcfg"
52         "io"
53         "io/ioutil"
54         "log"
55         "os"
56         "os/exec"
57         "path/filepath"
58         "runtime"
59         "strings"
60         "sync"
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/msan",
1085         "runtime/asan",
1086 }
1087
1088 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 {
1089         isinternal := false
1090         for _, intpkg := range internalpkg {
1091                 if pkg == intpkg {
1092                         isinternal = true
1093                         break
1094                 }
1095         }
1096
1097         // DragonFly declares errno with __thread, which results in a symbol
1098         // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
1099         // currently know how to handle TLS relocations, hence we have to
1100         // force external linking for any libraries that link in code that
1101         // uses errno. This can be removed if the Go linker ever supports
1102         // these relocation types.
1103         if headType == objabi.Hdragonfly {
1104                 if pkg == "net" || pkg == "os/user" {
1105                         isinternal = false
1106                 }
1107         }
1108
1109         if !isinternal {
1110                 externalobj = true
1111         }
1112
1113         hostobj = append(hostobj, Hostobj{})
1114         h := &hostobj[len(hostobj)-1]
1115         h.ld = ld
1116         h.pkg = pkg
1117         h.pn = pn
1118         h.file = file
1119         h.off = f.Offset()
1120         h.length = length
1121         return h
1122 }
1123
1124 func hostobjs(ctxt *Link) {
1125         if ctxt.LinkMode != LinkInternal {
1126                 return
1127         }
1128         var h *Hostobj
1129
1130         for i := 0; i < len(hostobj); i++ {
1131                 h = &hostobj[i]
1132                 f, err := bio.Open(h.file)
1133                 if err != nil {
1134                         Exitf("cannot reopen %s: %v", h.pn, err)
1135                 }
1136
1137                 f.MustSeek(h.off, 0)
1138                 if h.ld == nil {
1139                         Errorf(nil, "%s: unrecognized object file format", h.pn)
1140                         continue
1141                 }
1142                 h.ld(ctxt, f, h.pkg, h.length, h.pn)
1143                 f.Close()
1144         }
1145 }
1146
1147 func hostlinksetup(ctxt *Link) {
1148         if ctxt.LinkMode != LinkExternal {
1149                 return
1150         }
1151
1152         // For external link, record that we need to tell the external linker -s,
1153         // and turn off -s internally: the external linker needs the symbol
1154         // information for its final link.
1155         debug_s = *FlagS
1156         *FlagS = false
1157
1158         // create temporary directory and arrange cleanup
1159         if *flagTmpdir == "" {
1160                 dir, err := ioutil.TempDir("", "go-link-")
1161                 if err != nil {
1162                         log.Fatal(err)
1163                 }
1164                 *flagTmpdir = dir
1165                 ownTmpDir = true
1166                 AtExit(func() {
1167                         os.RemoveAll(*flagTmpdir)
1168                 })
1169         }
1170
1171         // change our output to temporary object file
1172         if err := ctxt.Out.Close(); err != nil {
1173                 Exitf("error closing output file")
1174         }
1175         mayberemoveoutfile()
1176
1177         p := filepath.Join(*flagTmpdir, "go.o")
1178         if err := ctxt.Out.Open(p); err != nil {
1179                 Exitf("cannot create %s: %v", p, err)
1180         }
1181 }
1182
1183 // hostobjCopy creates a copy of the object files in hostobj in a
1184 // temporary directory.
1185 func hostobjCopy() (paths []string) {
1186         var wg sync.WaitGroup
1187         sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
1188         for i, h := range hostobj {
1189                 h := h
1190                 dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
1191                 paths = append(paths, dst)
1192
1193                 wg.Add(1)
1194                 go func() {
1195                         sema <- struct{}{}
1196                         defer func() {
1197                                 <-sema
1198                                 wg.Done()
1199                         }()
1200                         f, err := os.Open(h.file)
1201                         if err != nil {
1202                                 Exitf("cannot reopen %s: %v", h.pn, err)
1203                         }
1204                         defer f.Close()
1205                         if _, err := f.Seek(h.off, 0); err != nil {
1206                                 Exitf("cannot seek %s: %v", h.pn, err)
1207                         }
1208
1209                         w, err := os.Create(dst)
1210                         if err != nil {
1211                                 Exitf("cannot create %s: %v", dst, err)
1212                         }
1213                         if _, err := io.CopyN(w, f, h.length); err != nil {
1214                                 Exitf("cannot write %s: %v", dst, err)
1215                         }
1216                         if err := w.Close(); err != nil {
1217                                 Exitf("cannot close %s: %v", dst, err)
1218                         }
1219                 }()
1220         }
1221         wg.Wait()
1222         return paths
1223 }
1224
1225 // writeGDBLinkerScript creates gcc linker script file in temp
1226 // directory. writeGDBLinkerScript returns created file path.
1227 // The script is used to work around gcc bug
1228 // (see https://golang.org/issue/20183 for details).
1229 func writeGDBLinkerScript() string {
1230         name := "fix_debug_gdb_scripts.ld"
1231         path := filepath.Join(*flagTmpdir, name)
1232         src := `SECTIONS
1233 {
1234   .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
1235   {
1236     *(.debug_gdb_scripts)
1237   }
1238 }
1239 INSERT AFTER .debug_types;
1240 `
1241         err := ioutil.WriteFile(path, []byte(src), 0666)
1242         if err != nil {
1243                 Errorf(nil, "WriteFile %s failed: %v", name, err)
1244         }
1245         return path
1246 }
1247
1248 // archive builds a .a archive from the hostobj object files.
1249 func (ctxt *Link) archive() {
1250         if ctxt.BuildMode != BuildModeCArchive {
1251                 return
1252         }
1253
1254         exitIfErrors()
1255
1256         if *flagExtar == "" {
1257                 *flagExtar = "ar"
1258         }
1259
1260         mayberemoveoutfile()
1261
1262         // Force the buffer to flush here so that external
1263         // tools will see a complete file.
1264         if err := ctxt.Out.Close(); err != nil {
1265                 Exitf("error closing %v", *flagOutfile)
1266         }
1267
1268         argv := []string{*flagExtar, "-q", "-c", "-s"}
1269         if ctxt.HeadType == objabi.Haix {
1270                 argv = append(argv, "-X64")
1271         }
1272         argv = append(argv, *flagOutfile)
1273         argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
1274         argv = append(argv, hostobjCopy()...)
1275
1276         if ctxt.Debugvlog != 0 {
1277                 ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
1278         }
1279
1280         // If supported, use syscall.Exec() to invoke the archive command,
1281         // which should be the final remaining step needed for the link.
1282         // This will reduce peak RSS for the link (and speed up linking of
1283         // large applications), since when the archive command runs we
1284         // won't be holding onto all of the linker's live memory.
1285         if syscallExecSupported && !ownTmpDir {
1286                 runAtExitFuncs()
1287                 ctxt.execArchive(argv)
1288                 panic("should not get here")
1289         }
1290
1291         // Otherwise invoke 'ar' in the usual way (fork + exec).
1292         if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
1293                 Exitf("running %s failed: %v\n%s", argv[0], err, out)
1294         }
1295 }
1296
1297 func (ctxt *Link) hostlink() {
1298         if ctxt.LinkMode != LinkExternal || nerrors > 0 {
1299                 return
1300         }
1301         if ctxt.BuildMode == BuildModeCArchive {
1302                 return
1303         }
1304
1305         var argv []string
1306         argv = append(argv, ctxt.extld()...)
1307         argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
1308
1309         if *FlagS || debug_s {
1310                 if ctxt.HeadType == objabi.Hdarwin {
1311                         // Recent versions of macOS print
1312                         //      ld: warning: option -s is obsolete and being ignored
1313                         // so do not pass any arguments.
1314                 } else {
1315                         argv = append(argv, "-s")
1316                 }
1317         }
1318
1319         // On darwin, whether to combine DWARF into executable.
1320         // Only macOS supports unmapped segments such as our __DWARF segment.
1321         combineDwarf := ctxt.IsDarwin() && !*FlagS && !*FlagW && !debug_s && machoPlatform == PLATFORM_MACOS
1322
1323         switch ctxt.HeadType {
1324         case objabi.Hdarwin:
1325                 if combineDwarf {
1326                         // Leave room for DWARF combining.
1327                         // -headerpad is incompatible with -fembed-bitcode.
1328                         argv = append(argv, "-Wl,-headerpad,1144")
1329                 }
1330                 if ctxt.DynlinkingGo() && buildcfg.GOOS != "ios" {
1331                         // -flat_namespace is deprecated on iOS.
1332                         // It is useful for supporting plugins. We don't support plugins on iOS.
1333                         // -flat_namespace may cause the dynamic linker to hang at forkExec when
1334                         // resolving a lazy binding. See issue 38824.
1335                         // Force eager resolution to work around.
1336                         argv = append(argv, "-Wl,-flat_namespace", "-Wl,-bind_at_load")
1337                 }
1338                 if !combineDwarf {
1339                         argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols
1340                 }
1341         case objabi.Hopenbsd:
1342                 argv = append(argv, "-Wl,-nopie")
1343                 argv = append(argv, "-pthread")
1344         case objabi.Hwindows:
1345                 if windowsgui {
1346                         argv = append(argv, "-mwindows")
1347                 } else {
1348                         argv = append(argv, "-mconsole")
1349                 }
1350                 // Mark as having awareness of terminal services, to avoid
1351                 // ancient compatibility hacks.
1352                 argv = append(argv, "-Wl,--tsaware")
1353
1354                 // Enable DEP
1355                 argv = append(argv, "-Wl,--nxcompat")
1356
1357                 argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
1358                 argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
1359                 argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
1360                 argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
1361         case objabi.Haix:
1362                 argv = append(argv, "-pthread")
1363                 // prevent ld to reorder .text functions to keep the same
1364                 // first/last functions for moduledata.
1365                 argv = append(argv, "-Wl,-bnoobjreorder")
1366                 // mcmodel=large is needed for every gcc generated files, but
1367                 // ld still need -bbigtoc in order to allow larger TOC.
1368                 argv = append(argv, "-mcmodel=large")
1369                 argv = append(argv, "-Wl,-bbigtoc")
1370         }
1371
1372         // Enable/disable ASLR on Windows.
1373         addASLRargs := func(argv []string, val bool) []string {
1374                 // Old/ancient versions of GCC support "--dynamicbase" and
1375                 // "--high-entropy-va" but don't enable it by default. In
1376                 // addition, they don't accept "--disable-dynamicbase" or
1377                 // "--no-dynamicbase", so the only way to disable ASLR is to
1378                 // not pass any flags at all.
1379                 //
1380                 // More modern versions of GCC (and also clang) enable ASLR
1381                 // by default. With these compilers, however you can turn it
1382                 // off if you want using "--disable-dynamicbase" or
1383                 // "--no-dynamicbase".
1384                 //
1385                 // The strategy below is to try using "--disable-dynamicbase";
1386                 // if this succeeds, then assume we're working with more
1387                 // modern compilers and act accordingly. If it fails, assume
1388                 // an ancient compiler with ancient defaults.
1389                 var dbopt string
1390                 var heopt string
1391                 dbon := "--dynamicbase"
1392                 heon := "--high-entropy-va"
1393                 dboff := "--disable-dynamicbase"
1394                 heoff := "--disable-high-entropy-va"
1395                 if val {
1396                         dbopt = dbon
1397                         heopt = heon
1398                 } else {
1399                         // Test to see whether "--disable-dynamicbase" works.
1400                         newer := linkerFlagSupported(ctxt.Arch, argv[0], "", "-Wl,"+dboff)
1401                         if newer {
1402                                 // Newer compiler, which supports both on/off options.
1403                                 dbopt = dboff
1404                                 heopt = heoff
1405                         } else {
1406                                 // older toolchain: we have to say nothing in order to
1407                                 // get a no-ASLR binary.
1408                                 dbopt = ""
1409                                 heopt = ""
1410                         }
1411                 }
1412                 if dbopt != "" {
1413                         argv = append(argv, "-Wl,"+dbopt)
1414                 }
1415                 // enable high-entropy ASLR on 64-bit.
1416                 if ctxt.Arch.PtrSize >= 8 && heopt != "" {
1417                         argv = append(argv, "-Wl,"+heopt)
1418                 }
1419                 return argv
1420         }
1421
1422         switch ctxt.BuildMode {
1423         case BuildModeExe:
1424                 if ctxt.HeadType == objabi.Hdarwin {
1425                         if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() {
1426                                 argv = append(argv, "-Wl,-no_pie")
1427                         }
1428                 }
1429                 if *flagRace && ctxt.HeadType == objabi.Hwindows {
1430                         // Current windows/amd64 race detector tsan support
1431                         // library can't handle PIE mode (see #53539 for more details).
1432                         // For now, explicitly disable PIE (since some compilers
1433                         // default to it) if -race is in effect.
1434                         argv = addASLRargs(argv, false)
1435                 }
1436         case BuildModePIE:
1437                 switch ctxt.HeadType {
1438                 case objabi.Hdarwin, objabi.Haix:
1439                 case objabi.Hwindows:
1440                         if *flagAslr && *flagRace {
1441                                 // Current windows/amd64 race detector tsan support
1442                                 // library can't handle PIE mode (see #53539 for more details).
1443                                 // Disable alsr if -race in effect.
1444                                 *flagAslr = false
1445                         }
1446                         argv = addASLRargs(argv, *flagAslr)
1447                 default:
1448                         // ELF.
1449                         if ctxt.UseRelro() {
1450                                 argv = append(argv, "-Wl,-z,relro")
1451                         }
1452                         argv = append(argv, "-pie")
1453                 }
1454         case BuildModeCShared:
1455                 if ctxt.HeadType == objabi.Hdarwin {
1456                         argv = append(argv, "-dynamiclib")
1457                 } else {
1458                         if ctxt.UseRelro() {
1459                                 argv = append(argv, "-Wl,-z,relro")
1460                         }
1461                         argv = append(argv, "-shared")
1462                         if ctxt.HeadType == objabi.Hwindows {
1463                                 argv = addASLRargs(argv, *flagAslr)
1464                         } else {
1465                                 // Pass -z nodelete to mark the shared library as
1466                                 // non-closeable: a dlclose will do nothing.
1467                                 argv = append(argv, "-Wl,-z,nodelete")
1468                                 // Only pass Bsymbolic on non-Windows.
1469                                 argv = append(argv, "-Wl,-Bsymbolic")
1470                         }
1471                 }
1472         case BuildModeShared:
1473                 if ctxt.UseRelro() {
1474                         argv = append(argv, "-Wl,-z,relro")
1475                 }
1476                 argv = append(argv, "-shared")
1477         case BuildModePlugin:
1478                 if ctxt.HeadType == objabi.Hdarwin {
1479                         argv = append(argv, "-dynamiclib")
1480                 } else {
1481                         if ctxt.UseRelro() {
1482                                 argv = append(argv, "-Wl,-z,relro")
1483                         }
1484                         argv = append(argv, "-shared")
1485                 }
1486         }
1487
1488         var altLinker string
1489         if ctxt.IsELF && ctxt.DynlinkingGo() {
1490                 // We force all symbol resolution to be done at program startup
1491                 // because lazy PLT resolution can use large amounts of stack at
1492                 // times we cannot allow it to do so.
1493                 argv = append(argv, "-Wl,-z,now")
1494
1495                 // Do not let the host linker generate COPY relocations. These
1496                 // can move symbols out of sections that rely on stable offsets
1497                 // from the beginning of the section (like sym.STYPE).
1498                 argv = append(argv, "-Wl,-z,nocopyreloc")
1499
1500                 if buildcfg.GOOS == "android" {
1501                         // Use lld to avoid errors from default linker (issue #38838)
1502                         altLinker = "lld"
1503                 }
1504
1505                 if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && buildcfg.GOOS == "linux" {
1506                         // On ARM, the GNU linker will generate COPY relocations
1507                         // even with -znocopyreloc set.
1508                         // https://sourceware.org/bugzilla/show_bug.cgi?id=19962
1509                         //
1510                         // On ARM64, the GNU linker will fail instead of
1511                         // generating COPY relocations.
1512                         //
1513                         // In both cases, switch to gold.
1514                         altLinker = "gold"
1515
1516                         // If gold is not installed, gcc will silently switch
1517                         // back to ld.bfd. So we parse the version information
1518                         // and provide a useful error if gold is missing.
1519                         name, args := flagExtld[0], flagExtld[1:]
1520                         args = append(args, "-fuse-ld=gold", "-Wl,--version")
1521                         cmd := exec.Command(name, args...)
1522                         if out, err := cmd.CombinedOutput(); err == nil {
1523                                 if !bytes.Contains(out, []byte("GNU gold")) {
1524                                         log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
1525                                 }
1526                         }
1527                 }
1528         }
1529         if ctxt.Arch.Family == sys.ARM64 && buildcfg.GOOS == "freebsd" {
1530                 // Switch to ld.bfd on freebsd/arm64.
1531                 altLinker = "bfd"
1532
1533                 // Provide a useful error if ld.bfd is missing.
1534                 name, args := flagExtld[0], flagExtld[1:]
1535                 args = append(args, "-fuse-ld=bfd", "-Wl,--version")
1536                 cmd := exec.Command(name, args...)
1537                 if out, err := cmd.CombinedOutput(); err == nil {
1538                         if !bytes.Contains(out, []byte("GNU ld")) {
1539                                 log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
1540                         }
1541                 }
1542         }
1543         if altLinker != "" {
1544                 argv = append(argv, "-fuse-ld="+altLinker)
1545         }
1546
1547         if ctxt.IsELF && len(buildinfo) > 0 {
1548                 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
1549         }
1550
1551         // On Windows, given -o foo, GCC will append ".exe" to produce
1552         // "foo.exe".  We have decided that we want to honor the -o
1553         // option. To make this work, we append a '.' so that GCC
1554         // will decide that the file already has an extension. We
1555         // only want to do this when producing a Windows output file
1556         // on a Windows host.
1557         outopt := *flagOutfile
1558         if buildcfg.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
1559                 outopt += "."
1560         }
1561         argv = append(argv, "-o")
1562         argv = append(argv, outopt)
1563
1564         if rpath.val != "" {
1565                 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
1566         }
1567
1568         if *flagInterpreter != "" {
1569                 // Many linkers support both -I and the --dynamic-linker flags
1570                 // to set the ELF interpreter, but lld only supports
1571                 // --dynamic-linker so prefer that (ld on very old Solaris only
1572                 // supports -I but that seems less important).
1573                 argv = append(argv, fmt.Sprintf("-Wl,--dynamic-linker,%s", *flagInterpreter))
1574         }
1575
1576         // Force global symbols to be exported for dlopen, etc.
1577         if ctxt.IsELF {
1578                 argv = append(argv, "-rdynamic")
1579         }
1580         if ctxt.HeadType == objabi.Haix {
1581                 fileName := xcoffCreateExportFile(ctxt)
1582                 argv = append(argv, "-Wl,-bE:"+fileName)
1583         }
1584
1585         const unusedArguments = "-Qunused-arguments"
1586         if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, unusedArguments) {
1587                 argv = append(argv, unusedArguments)
1588         }
1589
1590         const compressDWARF = "-Wl,--compress-debug-sections=zlib"
1591         if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
1592                 argv = append(argv, compressDWARF)
1593         }
1594
1595         argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
1596         argv = append(argv, hostobjCopy()...)
1597         if ctxt.HeadType == objabi.Haix {
1598                 // We want to have C files after Go files to remove
1599                 // trampolines csects made by ld.
1600                 argv = append(argv, "-nostartfiles")
1601                 argv = append(argv, "/lib/crt0_64.o")
1602
1603                 extld := ctxt.extld()
1604                 name, args := extld[0], extld[1:]
1605                 // Get starting files.
1606                 getPathFile := func(file string) string {
1607                         args := append(args, "-maix64", "--print-file-name="+file)
1608                         out, err := exec.Command(name, args...).CombinedOutput()
1609                         if err != nil {
1610                                 log.Fatalf("running %s failed: %v\n%s", extld, err, out)
1611                         }
1612                         return strings.Trim(string(out), "\n")
1613                 }
1614                 // Since GCC version 11, the 64-bit version of GCC starting files
1615                 // are now suffixed by "_64". Even under "-maix64" multilib directory
1616                 // "crtcxa.o" is 32-bit.
1617                 crtcxa := getPathFile("crtcxa_64.o")
1618                 if !filepath.IsAbs(crtcxa) {
1619                         crtcxa = getPathFile("crtcxa.o")
1620                 }
1621                 crtdbase := getPathFile("crtdbase_64.o")
1622                 if !filepath.IsAbs(crtdbase) {
1623                         crtdbase = getPathFile("crtdbase.o")
1624                 }
1625                 argv = append(argv, crtcxa)
1626                 argv = append(argv, crtdbase)
1627         }
1628
1629         if ctxt.linkShared {
1630                 seenDirs := make(map[string]bool)
1631                 seenLibs := make(map[string]bool)
1632                 addshlib := func(path string) {
1633                         dir, base := filepath.Split(path)
1634                         if !seenDirs[dir] {
1635                                 argv = append(argv, "-L"+dir)
1636                                 if !rpath.set {
1637                                         argv = append(argv, "-Wl,-rpath="+dir)
1638                                 }
1639                                 seenDirs[dir] = true
1640                         }
1641                         base = strings.TrimSuffix(base, ".so")
1642                         base = strings.TrimPrefix(base, "lib")
1643                         if !seenLibs[base] {
1644                                 argv = append(argv, "-l"+base)
1645                                 seenLibs[base] = true
1646                         }
1647                 }
1648                 for _, shlib := range ctxt.Shlibs {
1649                         addshlib(shlib.Path)
1650                         for _, dep := range shlib.Deps {
1651                                 if dep == "" {
1652                                         continue
1653                                 }
1654                                 libpath := findshlib(ctxt, dep)
1655                                 if libpath != "" {
1656                                         addshlib(libpath)
1657                                 }
1658                         }
1659                 }
1660         }
1661
1662         // clang, unlike GCC, passes -rdynamic to the linker
1663         // even when linking with -static, causing a linker
1664         // error when using GNU ld. So take out -rdynamic if
1665         // we added it. We do it in this order, rather than
1666         // only adding -rdynamic later, so that -extldflags
1667         // can override -rdynamic without using -static.
1668         // Similarly for -Wl,--dynamic-linker.
1669         checkStatic := func(arg string) {
1670                 if ctxt.IsELF && arg == "-static" {
1671                         for i := range argv {
1672                                 if argv[i] == "-rdynamic" || strings.HasPrefix(argv[i], "-Wl,--dynamic-linker,") {
1673                                         argv[i] = "-static"
1674                                 }
1675                         }
1676                 }
1677         }
1678
1679         for _, p := range ldflag {
1680                 argv = append(argv, p)
1681                 checkStatic(p)
1682         }
1683
1684         // When building a program with the default -buildmode=exe the
1685         // gc compiler generates code requires DT_TEXTREL in a
1686         // position independent executable (PIE). On systems where the
1687         // toolchain creates PIEs by default, and where DT_TEXTREL
1688         // does not work, the resulting programs will not run. See
1689         // issue #17847. To avoid this problem pass -no-pie to the
1690         // toolchain if it is supported.
1691         if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
1692                 // GCC uses -no-pie, clang uses -nopie.
1693                 for _, nopie := range []string{"-no-pie", "-nopie"} {
1694                         if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
1695                                 argv = append(argv, nopie)
1696                                 break
1697                         }
1698                 }
1699         }
1700
1701         for _, p := range flagExtldflags {
1702                 argv = append(argv, p)
1703                 checkStatic(p)
1704         }
1705         if ctxt.HeadType == objabi.Hwindows {
1706                 // Determine which linker we're using. Add in the extldflags in
1707                 // case used has specified "-fuse-ld=...".
1708                 extld := ctxt.extld()
1709                 name, args := extld[0], extld[1:]
1710                 args = append(args, flagExtldflags...)
1711                 args = append(args, "-Wl,--version")
1712                 cmd := exec.Command(name, args...)
1713                 usingLLD := false
1714                 if out, err := cmd.CombinedOutput(); err == nil {
1715                         if bytes.Contains(out, []byte("LLD ")) {
1716                                 usingLLD = true
1717                         }
1718                 }
1719
1720                 // use gcc linker script to work around gcc bug
1721                 // (see https://golang.org/issue/20183 for details).
1722                 if !usingLLD {
1723                         p := writeGDBLinkerScript()
1724                         argv = append(argv, "-Wl,-T,"+p)
1725                 }
1726                 if *flagRace {
1727                         if p := ctxt.findLibPath("libsynchronization.a"); p != "libsynchronization.a" {
1728                                 argv = append(argv, "-lsynchronization")
1729                         }
1730                 }
1731                 // libmingw32 and libmingwex have some inter-dependencies,
1732                 // so must use linker groups.
1733                 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
1734                 argv = append(argv, peimporteddlls()...)
1735         }
1736
1737         if ctxt.Debugvlog != 0 {
1738                 ctxt.Logf("host link:")
1739                 for _, v := range argv {
1740                         ctxt.Logf(" %q", v)
1741                 }
1742                 ctxt.Logf("\n")
1743         }
1744
1745         out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
1746         if err != nil {
1747                 Exitf("running %s failed: %v\n%s", argv[0], err, out)
1748         }
1749
1750         // Filter out useless linker warnings caused by bugs outside Go.
1751         // See also cmd/go/internal/work/exec.go's gccld method.
1752         var save [][]byte
1753         var skipLines int
1754         for _, line := range bytes.SplitAfter(out, []byte("\n")) {
1755                 // golang.org/issue/26073 - Apple Xcode bug
1756                 if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
1757                         continue
1758                 }
1759
1760                 if skipLines > 0 {
1761                         skipLines--
1762                         continue
1763                 }
1764
1765                 // Remove TOC overflow warning on AIX.
1766                 if bytes.Contains(line, []byte("ld: 0711-783")) {
1767                         skipLines = 2
1768                         continue
1769                 }
1770
1771                 save = append(save, line)
1772         }
1773         out = bytes.Join(save, nil)
1774
1775         if len(out) > 0 {
1776                 // always print external output even if the command is successful, so that we don't
1777                 // swallow linker warnings (see https://golang.org/issue/17935).
1778                 if ctxt.IsDarwin() && ctxt.IsAMD64() {
1779                         const noPieWarning = "ld: warning: -no_pie is deprecated when targeting new OS versions\n"
1780                         if i := bytes.Index(out, []byte(noPieWarning)); i >= 0 {
1781                                 // swallow -no_pie deprecation warning, issue 54482
1782                                 out = append(out[:i], out[i+len(noPieWarning):]...)
1783                         }
1784                 }
1785                 ctxt.Logf("%s", out)
1786         }
1787
1788         if combineDwarf {
1789                 // Find "dsymutils" and "strip" tools using CC --print-prog-name.
1790                 var cc []string
1791                 cc = append(cc, ctxt.extld()...)
1792                 cc = append(cc, hostlinkArchArgs(ctxt.Arch)...)
1793                 cc = append(cc, "--print-prog-name", "dsymutil")
1794                 out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput()
1795                 if err != nil {
1796                         Exitf("%s: finding dsymutil failed: %v\n%s", os.Args[0], err, out)
1797                 }
1798                 dsymutilCmd := strings.TrimSuffix(string(out), "\n")
1799
1800                 cc[len(cc)-1] = "strip"
1801                 out, err = exec.Command(cc[0], cc[1:]...).CombinedOutput()
1802                 if err != nil {
1803                         Exitf("%s: finding strip failed: %v\n%s", os.Args[0], err, out)
1804                 }
1805                 stripCmd := strings.TrimSuffix(string(out), "\n")
1806
1807                 dsym := filepath.Join(*flagTmpdir, "go.dwarf")
1808                 if out, err := exec.Command(dsymutilCmd, "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
1809                         Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
1810                 }
1811                 // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil).
1812                 // They contain temporary file paths and make the build not reproducible.
1813                 if out, err := exec.Command(stripCmd, "-S", *flagOutfile).CombinedOutput(); err != nil {
1814                         Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
1815                 }
1816                 // Skip combining if `dsymutil` didn't generate a file. See #11994.
1817                 if _, err := os.Stat(dsym); os.IsNotExist(err) {
1818                         return
1819                 }
1820                 // For os.Rename to work reliably, must be in same directory as outfile.
1821                 combinedOutput := *flagOutfile + "~"
1822                 exef, err := os.Open(*flagOutfile)
1823                 if err != nil {
1824                         Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1825                 }
1826                 defer exef.Close()
1827                 exem, err := macho.NewFile(exef)
1828                 if err != nil {
1829                         Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
1830                 }
1831                 if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
1832                         Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1833                 }
1834                 os.Remove(*flagOutfile)
1835                 if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
1836                         Exitf("%s: %v", os.Args[0], err)
1837                 }
1838         }
1839         if ctxt.NeedCodeSign() {
1840                 err := machoCodeSign(ctxt, *flagOutfile)
1841                 if err != nil {
1842                         Exitf("%s: code signing failed: %v", os.Args[0], err)
1843                 }
1844         }
1845 }
1846
1847 var createTrivialCOnce sync.Once
1848
1849 func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
1850         createTrivialCOnce.Do(func() {
1851                 src := filepath.Join(*flagTmpdir, "trivial.c")
1852                 if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
1853                         Errorf(nil, "WriteFile trivial.c failed: %v", err)
1854                 }
1855         })
1856
1857         flagsWithNextArgSkip := []string{
1858                 "-F",
1859                 "-l",
1860                 "-L",
1861                 "-framework",
1862                 "-Wl,-framework",
1863                 "-Wl,-rpath",
1864                 "-Wl,-undefined",
1865         }
1866         flagsWithNextArgKeep := []string{
1867                 "-arch",
1868                 "-isysroot",
1869                 "--sysroot",
1870                 "-target",
1871         }
1872         prefixesToKeep := []string{
1873                 "-f",
1874                 "-m",
1875                 "-p",
1876                 "-Wl,",
1877                 "-arch",
1878                 "-isysroot",
1879                 "--sysroot",
1880                 "-target",
1881         }
1882
1883         flags := hostlinkArchArgs(arch)
1884         keep := false
1885         skip := false
1886         for _, f := range append(flagExtldflags, ldflag...) {
1887                 if keep {
1888                         flags = append(flags, f)
1889                         keep = false
1890                 } else if skip {
1891                         skip = false
1892                 } else if f == "" || f[0] != '-' {
1893                 } else if contains(flagsWithNextArgSkip, f) {
1894                         skip = true
1895                 } else if contains(flagsWithNextArgKeep, f) {
1896                         flags = append(flags, f)
1897                         keep = true
1898                 } else {
1899                         for _, p := range prefixesToKeep {
1900                                 if strings.HasPrefix(f, p) {
1901                                         flags = append(flags, f)
1902                                         break
1903                                 }
1904                         }
1905                 }
1906         }
1907
1908         if altLinker != "" {
1909                 flags = append(flags, "-fuse-ld="+altLinker)
1910         }
1911         flags = append(flags, flag, "trivial.c")
1912
1913         cmd := exec.Command(linker, flags...)
1914         cmd.Dir = *flagTmpdir
1915         cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
1916         out, err := cmd.CombinedOutput()
1917         // GCC says "unrecognized command line option ‘-no-pie’"
1918         // clang says "unknown argument: '-no-pie'"
1919         return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
1920 }
1921
1922 // hostlinkArchArgs returns arguments to pass to the external linker
1923 // based on the architecture.
1924 func hostlinkArchArgs(arch *sys.Arch) []string {
1925         switch arch.Family {
1926         case sys.I386:
1927                 return []string{"-m32"}
1928         case sys.AMD64:
1929                 if buildcfg.GOOS == "darwin" {
1930                         return []string{"-arch", "x86_64", "-m64"}
1931                 }
1932                 return []string{"-m64"}
1933         case sys.S390X:
1934                 return []string{"-m64"}
1935         case sys.ARM:
1936                 return []string{"-marm"}
1937         case sys.ARM64:
1938                 if buildcfg.GOOS == "darwin" {
1939                         return []string{"-arch", "arm64"}
1940                 }
1941         case sys.Loong64:
1942                 return []string{"-mabi=lp64d"}
1943         case sys.MIPS64:
1944                 return []string{"-mabi=64"}
1945         case sys.MIPS:
1946                 return []string{"-mabi=32"}
1947         case sys.PPC64:
1948                 if buildcfg.GOOS == "aix" {
1949                         return []string{"-maix64"}
1950                 } else {
1951                         return []string{"-m64"}
1952                 }
1953
1954         }
1955         return nil
1956 }
1957
1958 var wantHdr = objabi.HeaderString()
1959
1960 // ldobj loads an input object. If it is a host object (an object
1961 // compiled by a non-Go compiler) it returns the Hostobj pointer. If
1962 // it is a Go object, it returns nil.
1963 func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
1964         pkg := objabi.PathToPrefix(lib.Pkg)
1965
1966         eof := f.Offset() + length
1967         start := f.Offset()
1968         c1 := bgetc(f)
1969         c2 := bgetc(f)
1970         c3 := bgetc(f)
1971         c4 := bgetc(f)
1972         f.MustSeek(start, 0)
1973
1974         unit := &sym.CompilationUnit{Lib: lib}
1975         lib.Units = append(lib.Units, unit)
1976
1977         magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
1978         if magic == 0x7f454c46 { // \x7F E L F
1979                 ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
1980                         textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags)
1981                         if err != nil {
1982                                 Errorf(nil, "%v", err)
1983                                 return
1984                         }
1985                         ehdr.Flags = flags
1986                         ctxt.Textp = append(ctxt.Textp, textp...)
1987                 }
1988                 return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
1989         }
1990
1991         if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
1992                 ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
1993                         textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
1994                         if err != nil {
1995                                 Errorf(nil, "%v", err)
1996                                 return
1997                         }
1998                         ctxt.Textp = append(ctxt.Textp, textp...)
1999                 }
2000                 return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
2001         }
2002
2003         switch c1<<8 | c2 {
2004         case 0x4c01, // 386
2005                 0x6486, // amd64
2006                 0xc401, // arm
2007                 0x64aa: // arm64
2008                 ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
2009                         textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
2010                         if err != nil {
2011                                 Errorf(nil, "%v", err)
2012                                 return
2013                         }
2014                         if len(rsrc) != 0 {
2015                                 setpersrc(ctxt, rsrc)
2016                         }
2017                         ctxt.Textp = append(ctxt.Textp, textp...)
2018                 }
2019                 return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
2020         }
2021
2022         if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
2023                 ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
2024                         textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
2025                         if err != nil {
2026                                 Errorf(nil, "%v", err)
2027                                 return
2028                         }
2029                         ctxt.Textp = append(ctxt.Textp, textp...)
2030                 }
2031                 return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
2032         }
2033
2034         if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' {
2035                 // An unrecognized object is just passed to the external linker.
2036                 // If we try to read symbols from this object, we will
2037                 // report an error at that time.
2038                 unknownObjFormat = true
2039                 return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file)
2040         }
2041
2042         /* check the header */
2043         line, err := f.ReadString('\n')
2044         if err != nil {
2045                 Errorf(nil, "truncated object file: %s: %v", pn, err)
2046                 return nil
2047         }
2048
2049         if !strings.HasPrefix(line, "go object ") {
2050                 if strings.HasSuffix(pn, ".go") {
2051                         Exitf("%s: uncompiled .go source file", pn)
2052                         return nil
2053                 }
2054
2055                 if line == ctxt.Arch.Name {
2056                         // old header format: just $GOOS
2057                         Errorf(nil, "%s: stale object file", pn)
2058                         return nil
2059                 }
2060
2061                 Errorf(nil, "%s: not an object file: @%d %q", pn, start, line)
2062                 return nil
2063         }
2064
2065         // First, check that the basic GOOS, GOARCH, and Version match.
2066         if line != wantHdr {
2067                 Errorf(nil, "%s: linked object header mismatch:\nhave %q\nwant %q\n", pn, line, wantHdr)
2068         }
2069
2070         // Skip over exports and other info -- ends with \n!\n.
2071         //
2072         // Note: It's possible for "\n!\n" to appear within the binary
2073         // package export data format. To avoid truncating the package
2074         // definition prematurely (issue 21703), we keep track of
2075         // how many "$$" delimiters we've seen.
2076
2077         import0 := f.Offset()
2078
2079         c1 = '\n' // the last line ended in \n
2080         c2 = bgetc(f)
2081         c3 = bgetc(f)
2082         markers := 0
2083         for {
2084                 if c1 == '\n' {
2085                         if markers%2 == 0 && c2 == '!' && c3 == '\n' {
2086                                 break
2087                         }
2088                         if c2 == '$' && c3 == '$' {
2089                                 markers++
2090                         }
2091                 }
2092
2093                 c1 = c2
2094                 c2 = c3
2095                 c3 = bgetc(f)
2096                 if c3 == -1 {
2097                         Errorf(nil, "truncated object file: %s", pn)
2098                         return nil
2099                 }
2100         }
2101
2102         import1 := f.Offset()
2103
2104         f.MustSeek(import0, 0)
2105         ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
2106         f.MustSeek(import1, 0)
2107
2108         fingerprint := ctxt.loader.Preload(ctxt.IncVersion(), f, lib, unit, eof-f.Offset())
2109         if !fingerprint.IsZero() { // Assembly objects don't have fingerprints. Ignore them.
2110                 // Check fingerprint, to ensure the importing and imported packages
2111                 // have consistent view of symbol indices.
2112                 // Normally the go command should ensure this. But in case something
2113                 // goes wrong, it could lead to obscure bugs like run-time crash.
2114                 // Check it here to be sure.
2115                 if lib.Fingerprint.IsZero() { // Not yet imported. Update its fingerprint.
2116                         lib.Fingerprint = fingerprint
2117                 }
2118                 checkFingerprint(lib, fingerprint, lib.Srcref, lib.Fingerprint)
2119         }
2120
2121         addImports(ctxt, lib, pn)
2122         return nil
2123 }
2124
2125 // symbolsAreUnresolved scans through the loader's list of unresolved
2126 // symbols and checks to see whether any of them match the names of the
2127 // symbols in 'want'. Return value is a list of bools, with list[K] set
2128 // to true if there is an unresolved reference to the symbol in want[K].
2129 func symbolsAreUnresolved(ctxt *Link, want []string) []bool {
2130         returnAllUndefs := -1
2131         undefs := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
2132         seen := make(map[loader.Sym]struct{})
2133         rval := make([]bool, len(want))
2134         wantm := make(map[string]int)
2135         for k, w := range want {
2136                 wantm[w] = k
2137         }
2138         count := 0
2139         for _, s := range undefs {
2140                 if _, ok := seen[s]; ok {
2141                         continue
2142                 }
2143                 seen[s] = struct{}{}
2144                 if k, ok := wantm[ctxt.loader.SymName(s)]; ok {
2145                         rval[k] = true
2146                         count++
2147                         if count == len(want) {
2148                                 return rval
2149                         }
2150                 }
2151         }
2152         return rval
2153 }
2154
2155 // hostObject reads a single host object file (compare to "hostArchive").
2156 // This is used as part of internal linking when we need to pull in
2157 // files such as "crt?.o".
2158 func hostObject(ctxt *Link, objname string, path string) {
2159         if ctxt.Debugvlog > 1 {
2160                 ctxt.Logf("hostObject(%s)\n", path)
2161         }
2162         objlib := sym.Library{
2163                 Pkg: objname,
2164         }
2165         f, err := bio.Open(path)
2166         if err != nil {
2167                 Exitf("cannot open host object %q file %s: %v", objname, path, err)
2168         }
2169         defer f.Close()
2170         h := ldobj(ctxt, f, &objlib, 0, path, path)
2171         if h.ld == nil {
2172                 Exitf("unrecognized object file format in %s", path)
2173         }
2174         f.MustSeek(h.off, 0)
2175         h.ld(ctxt, f, h.pkg, h.length, h.pn)
2176 }
2177
2178 func checkFingerprint(lib *sym.Library, libfp goobj.FingerprintType, src string, srcfp goobj.FingerprintType) {
2179         if libfp != srcfp {
2180                 Exitf("fingerprint mismatch: %s has %x, import from %s expecting %x", lib, libfp, src, srcfp)
2181         }
2182 }
2183
2184 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
2185         data := make([]byte, sym.Size)
2186         sect := f.Sections[sym.Section]
2187         if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
2188                 Errorf(nil, "reading %s from non-data section", sym.Name)
2189         }
2190         n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
2191         if uint64(n) != sym.Size {
2192                 Errorf(nil, "reading contents of %s: %v", sym.Name, err)
2193         }
2194         return data
2195 }
2196
2197 func readwithpad(r io.Reader, sz int32) ([]byte, error) {
2198         data := make([]byte, Rnd(int64(sz), 4))
2199         _, err := io.ReadFull(r, data)
2200         if err != nil {
2201                 return nil, err
2202         }
2203         data = data[:sz]
2204         return data, nil
2205 }
2206
2207 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
2208         for _, sect := range f.Sections {
2209                 if sect.Type != elf.SHT_NOTE {
2210                         continue
2211                 }
2212                 r := sect.Open()
2213                 for {
2214                         var namesize, descsize, noteType int32
2215                         err := binary.Read(r, f.ByteOrder, &namesize)
2216                         if err != nil {
2217                                 if err == io.EOF {
2218                                         break
2219                                 }
2220                                 return nil, fmt.Errorf("read namesize failed: %v", err)
2221                         }
2222                         err = binary.Read(r, f.ByteOrder, &descsize)
2223                         if err != nil {
2224                                 return nil, fmt.Errorf("read descsize failed: %v", err)
2225                         }
2226                         err = binary.Read(r, f.ByteOrder, &noteType)
2227                         if err != nil {
2228                                 return nil, fmt.Errorf("read type failed: %v", err)
2229                         }
2230                         noteName, err := readwithpad(r, namesize)
2231                         if err != nil {
2232                                 return nil, fmt.Errorf("read name failed: %v", err)
2233                         }
2234                         desc, err := readwithpad(r, descsize)
2235                         if err != nil {
2236                                 return nil, fmt.Errorf("read desc failed: %v", err)
2237                         }
2238                         if string(name) == string(noteName) && typ == noteType {
2239                                 return desc, nil
2240                         }
2241                 }
2242         }
2243         return nil, nil
2244 }
2245
2246 func findshlib(ctxt *Link, shlib string) string {
2247         if filepath.IsAbs(shlib) {
2248                 return shlib
2249         }
2250         for _, libdir := range ctxt.Libdir {
2251                 libpath := filepath.Join(libdir, shlib)
2252                 if _, err := os.Stat(libpath); err == nil {
2253                         return libpath
2254                 }
2255         }
2256         Errorf(nil, "cannot find shared library: %s", shlib)
2257         return ""
2258 }
2259
2260 func ldshlibsyms(ctxt *Link, shlib string) {
2261         var libpath string
2262         if filepath.IsAbs(shlib) {
2263                 libpath = shlib
2264                 shlib = filepath.Base(shlib)
2265         } else {
2266                 libpath = findshlib(ctxt, shlib)
2267                 if libpath == "" {
2268                         return
2269                 }
2270         }
2271         for _, processedlib := range ctxt.Shlibs {
2272                 if processedlib.Path == libpath {
2273                         return
2274                 }
2275         }
2276         if ctxt.Debugvlog > 1 {
2277                 ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
2278         }
2279
2280         f, err := elf.Open(libpath)
2281         if err != nil {
2282                 Errorf(nil, "cannot open shared library: %s", libpath)
2283                 return
2284         }
2285         // Keep the file open as decodetypeGcprog needs to read from it.
2286         // TODO: fix. Maybe mmap the file.
2287         //defer f.Close()
2288
2289         hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
2290         if err != nil {
2291                 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
2292                 return
2293         }
2294
2295         depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
2296         if err != nil {
2297                 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
2298                 return
2299         }
2300         var deps []string
2301         for _, dep := range strings.Split(string(depsbytes), "\n") {
2302                 if dep == "" {
2303                         continue
2304                 }
2305                 if !filepath.IsAbs(dep) {
2306                         // If the dep can be interpreted as a path relative to the shlib
2307                         // in which it was found, do that. Otherwise, we will leave it
2308                         // to be resolved by libdir lookup.
2309                         abs := filepath.Join(filepath.Dir(libpath), dep)
2310                         if _, err := os.Stat(abs); err == nil {
2311                                 dep = abs
2312                         }
2313                 }
2314                 deps = append(deps, dep)
2315         }
2316
2317         syms, err := f.DynamicSymbols()
2318         if err != nil {
2319                 Errorf(nil, "cannot read symbols from shared library: %s", libpath)
2320                 return
2321         }
2322
2323         for _, elfsym := range syms {
2324                 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
2325                         continue
2326                 }
2327
2328                 // Symbols whose names start with "type:" are compiler generated,
2329                 // so make functions with that prefix internal.
2330                 ver := 0
2331                 symname := elfsym.Name // (unmangled) symbol name
2332                 if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type:") {
2333                         ver = abiInternalVer
2334                 } else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
2335                         // Demangle the ABI name. Keep in sync with symtab.go:mangleABIName.
2336                         if strings.HasSuffix(elfsym.Name, ".abiinternal") {
2337                                 ver = sym.SymVerABIInternal
2338                                 symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
2339                         } else if strings.HasSuffix(elfsym.Name, ".abi0") {
2340                                 ver = 0
2341                                 symname = strings.TrimSuffix(elfsym.Name, ".abi0")
2342                         }
2343                 }
2344
2345                 l := ctxt.loader
2346                 s := l.LookupOrCreateSym(symname, ver)
2347
2348                 // Because loadlib above loads all .a files before loading
2349                 // any shared libraries, any non-dynimport symbols we find
2350                 // that duplicate symbols already loaded should be ignored
2351                 // (the symbols from the .a files "win").
2352                 if l.SymType(s) != 0 && l.SymType(s) != sym.SDYNIMPORT {
2353                         continue
2354                 }
2355                 su := l.MakeSymbolUpdater(s)
2356                 su.SetType(sym.SDYNIMPORT)
2357                 l.SetSymElfType(s, elf.ST_TYPE(elfsym.Info))
2358                 su.SetSize(int64(elfsym.Size))
2359                 if elfsym.Section != elf.SHN_UNDEF {
2360                         // Set .File for the library that actually defines the symbol.
2361                         l.SetSymPkg(s, libpath)
2362
2363                         // The decodetype_* functions in decodetype.go need access to
2364                         // the type data.
2365                         sname := l.SymName(s)
2366                         if strings.HasPrefix(sname, "type:") && !strings.HasPrefix(sname, "type:.") {
2367                                 su.SetData(readelfsymboldata(ctxt, f, &elfsym))
2368                         }
2369                 }
2370
2371                 if symname != elfsym.Name {
2372                         l.SetSymExtname(s, elfsym.Name)
2373                 }
2374         }
2375         ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f})
2376 }
2377
2378 func addsection(ldr *loader.Loader, arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
2379         sect := ldr.NewSection()
2380         sect.Rwx = uint8(rwx)
2381         sect.Name = name
2382         sect.Seg = seg
2383         sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
2384         seg.Sections = append(seg.Sections, sect)
2385         return sect
2386 }
2387
2388 func usage() {
2389         fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
2390         objabi.Flagprint(os.Stderr)
2391         Exit(2)
2392 }
2393
2394 type SymbolType int8 // TODO: after genasmsym is gone, maybe rename to plan9typeChar or something
2395
2396 const (
2397         // see also https://9p.io/magic/man2html/1/nm
2398         TextSym      SymbolType = 'T'
2399         DataSym      SymbolType = 'D'
2400         BSSSym       SymbolType = 'B'
2401         UndefinedSym SymbolType = 'U'
2402         TLSSym       SymbolType = 't'
2403         FrameSym     SymbolType = 'm'
2404         ParamSym     SymbolType = 'p'
2405         AutoSym      SymbolType = 'a'
2406
2407         // Deleted auto (not a real sym, just placeholder for type)
2408         DeletedAutoSym = 'x'
2409 )
2410
2411 // defineInternal defines a symbol used internally by the go runtime.
2412 func (ctxt *Link) defineInternal(p string, t sym.SymKind) loader.Sym {
2413         s := ctxt.loader.CreateSymForUpdate(p, 0)
2414         s.SetType(t)
2415         s.SetSpecial(true)
2416         s.SetLocal(true)
2417         return s.Sym()
2418 }
2419
2420 func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) loader.Sym {
2421         s := ctxt.defineInternal(p, t)
2422         ctxt.loader.SetSymValue(s, v)
2423         return s
2424 }
2425
2426 func datoff(ldr *loader.Loader, s loader.Sym, addr int64) int64 {
2427         if uint64(addr) >= Segdata.Vaddr {
2428                 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
2429         }
2430         if uint64(addr) >= Segtext.Vaddr {
2431                 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
2432         }
2433         ldr.Errorf(s, "invalid datoff %#x", addr)
2434         return 0
2435 }
2436
2437 func Entryvalue(ctxt *Link) int64 {
2438         a := *flagEntrySymbol
2439         if a[0] >= '0' && a[0] <= '9' {
2440                 return atolwhex(a)
2441         }
2442         ldr := ctxt.loader
2443         s := ldr.Lookup(a, 0)
2444         if s == 0 {
2445                 Errorf(nil, "missing entry symbol %q", a)
2446                 return 0
2447         }
2448         st := ldr.SymType(s)
2449         if st == 0 {
2450                 return *FlagTextAddr
2451         }
2452         if !ctxt.IsAIX() && st != sym.STEXT {
2453                 ldr.Errorf(s, "entry not text")
2454         }
2455         return ldr.SymValue(s)
2456 }
2457
2458 func (ctxt *Link) callgraph() {
2459         if !*FlagC {
2460                 return
2461         }
2462
2463         ldr := ctxt.loader
2464         for _, s := range ctxt.Textp {
2465                 relocs := ldr.Relocs(s)
2466                 for i := 0; i < relocs.Count(); i++ {
2467                         r := relocs.At(i)
2468                         rs := r.Sym()
2469                         if rs == 0 {
2470                                 continue
2471                         }
2472                         if r.Type().IsDirectCall() && ldr.SymType(rs) == sym.STEXT {
2473                                 ctxt.Logf("%s calls %s\n", ldr.SymName(s), ldr.SymName(rs))
2474                         }
2475                 }
2476         }
2477 }
2478
2479 func Rnd(v int64, r int64) int64 {
2480         if r <= 0 {
2481                 return v
2482         }
2483         v += r - 1
2484         c := v % r
2485         if c < 0 {
2486                 c += r
2487         }
2488         v -= c
2489         return v
2490 }
2491
2492 func bgetc(r *bio.Reader) int {
2493         c, err := r.ReadByte()
2494         if err != nil {
2495                 if err != io.EOF {
2496                         log.Fatalf("reading input: %v", err)
2497                 }
2498                 return -1
2499         }
2500         return int(c)
2501 }
2502
2503 type markKind uint8 // for postorder traversal
2504 const (
2505         _ markKind = iota
2506         visiting
2507         visited
2508 )
2509
2510 func postorder(libs []*sym.Library) []*sym.Library {
2511         order := make([]*sym.Library, 0, len(libs)) // hold the result
2512         mark := make(map[*sym.Library]markKind, len(libs))
2513         for _, lib := range libs {
2514                 dfs(lib, mark, &order)
2515         }
2516         return order
2517 }
2518
2519 func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
2520         if mark[lib] == visited {
2521                 return
2522         }
2523         if mark[lib] == visiting {
2524                 panic("found import cycle while visiting " + lib.Pkg)
2525         }
2526         mark[lib] = visiting
2527         for _, i := range lib.Imports {
2528                 dfs(i, mark, order)
2529         }
2530         mark[lib] = visited
2531         *order = append(*order, lib)
2532 }
2533
2534 func ElfSymForReloc(ctxt *Link, s loader.Sym) int32 {
2535         // If putelfsym created a local version of this symbol, use that in all
2536         // relocations.
2537         les := ctxt.loader.SymLocalElfSym(s)
2538         if les != 0 {
2539                 return les
2540         } else {
2541                 return ctxt.loader.SymElfSym(s)
2542         }
2543 }
2544
2545 func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, elfRelocTyp uint32) {
2546         if ldr.SymGot(s) >= 0 {
2547                 return
2548         }
2549
2550         Adddynsym(ldr, target, syms, s)
2551         got := ldr.MakeSymbolUpdater(syms.GOT)
2552         ldr.SetGot(s, int32(got.Size()))
2553         got.AddUint(target.Arch, 0)
2554
2555         if target.IsElf() {
2556                 if target.Arch.PtrSize == 8 {
2557                         rela := ldr.MakeSymbolUpdater(syms.Rela)
2558                         rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
2559                         rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
2560                         rela.AddUint64(target.Arch, 0)
2561                 } else {
2562                         rel := ldr.MakeSymbolUpdater(syms.Rel)
2563                         rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
2564                         rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp))
2565                 }
2566         } else if target.IsDarwin() {
2567                 leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
2568                 leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
2569                 if target.IsPIE() && target.IsInternal() {
2570                         // Mach-O relocations are a royal pain to lay out.
2571                         // They use a compact stateful bytecode representation.
2572                         // Here we record what are needed and encode them later.
2573                         MachoAddBind(int64(ldr.SymGot(s)), s)
2574                 }
2575         } else {
2576                 ldr.Errorf(s, "addgotsym: unsupported binary format")
2577         }
2578 }