]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/ld/lib.go
all: use ":" for compiler generated symbols
[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                                 argv = append(argv, "-Wl,-pagezero_size,4000000")
1428                         }
1429                 }
1430                 if *flagRace && ctxt.HeadType == objabi.Hwindows {
1431                         // Current windows/amd64 race detector tsan support
1432                         // library can't handle PIE mode (see #53539 for more details).
1433                         // For now, explicitly disable PIE (since some compilers
1434                         // default to it) if -race is in effect.
1435                         argv = addASLRargs(argv, false)
1436                 }
1437         case BuildModePIE:
1438                 switch ctxt.HeadType {
1439                 case objabi.Hdarwin, objabi.Haix:
1440                 case objabi.Hwindows:
1441                         if *flagAslr && *flagRace {
1442                                 // Current windows/amd64 race detector tsan support
1443                                 // library can't handle PIE mode (see #53539 for more details).
1444                                 // Disable alsr if -race in effect.
1445                                 *flagAslr = false
1446                         }
1447                         argv = addASLRargs(argv, *flagAslr)
1448                 default:
1449                         // ELF.
1450                         if ctxt.UseRelro() {
1451                                 argv = append(argv, "-Wl,-z,relro")
1452                         }
1453                         argv = append(argv, "-pie")
1454                 }
1455         case BuildModeCShared:
1456                 if ctxt.HeadType == objabi.Hdarwin {
1457                         argv = append(argv, "-dynamiclib")
1458                 } else {
1459                         if ctxt.UseRelro() {
1460                                 argv = append(argv, "-Wl,-z,relro")
1461                         }
1462                         argv = append(argv, "-shared")
1463                         if ctxt.HeadType == objabi.Hwindows {
1464                                 argv = addASLRargs(argv, *flagAslr)
1465                         } else {
1466                                 // Pass -z nodelete to mark the shared library as
1467                                 // non-closeable: a dlclose will do nothing.
1468                                 argv = append(argv, "-Wl,-z,nodelete")
1469                                 // Only pass Bsymbolic on non-Windows.
1470                                 argv = append(argv, "-Wl,-Bsymbolic")
1471                         }
1472                 }
1473         case BuildModeShared:
1474                 if ctxt.UseRelro() {
1475                         argv = append(argv, "-Wl,-z,relro")
1476                 }
1477                 argv = append(argv, "-shared")
1478         case BuildModePlugin:
1479                 if ctxt.HeadType == objabi.Hdarwin {
1480                         argv = append(argv, "-dynamiclib")
1481                 } else {
1482                         if ctxt.UseRelro() {
1483                                 argv = append(argv, "-Wl,-z,relro")
1484                         }
1485                         argv = append(argv, "-shared")
1486                 }
1487         }
1488
1489         var altLinker string
1490         if ctxt.IsELF && ctxt.DynlinkingGo() {
1491                 // We force all symbol resolution to be done at program startup
1492                 // because lazy PLT resolution can use large amounts of stack at
1493                 // times we cannot allow it to do so.
1494                 argv = append(argv, "-Wl,-z,now")
1495
1496                 // Do not let the host linker generate COPY relocations. These
1497                 // can move symbols out of sections that rely on stable offsets
1498                 // from the beginning of the section (like sym.STYPE).
1499                 argv = append(argv, "-Wl,-z,nocopyreloc")
1500
1501                 if buildcfg.GOOS == "android" {
1502                         // Use lld to avoid errors from default linker (issue #38838)
1503                         altLinker = "lld"
1504                 }
1505
1506                 if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && buildcfg.GOOS == "linux" {
1507                         // On ARM, the GNU linker will generate COPY relocations
1508                         // even with -znocopyreloc set.
1509                         // https://sourceware.org/bugzilla/show_bug.cgi?id=19962
1510                         //
1511                         // On ARM64, the GNU linker will fail instead of
1512                         // generating COPY relocations.
1513                         //
1514                         // In both cases, switch to gold.
1515                         altLinker = "gold"
1516
1517                         // If gold is not installed, gcc will silently switch
1518                         // back to ld.bfd. So we parse the version information
1519                         // and provide a useful error if gold is missing.
1520                         name, args := flagExtld[0], flagExtld[1:]
1521                         args = append(args, "-fuse-ld=gold", "-Wl,--version")
1522                         cmd := exec.Command(name, args...)
1523                         if out, err := cmd.CombinedOutput(); err == nil {
1524                                 if !bytes.Contains(out, []byte("GNU gold")) {
1525                                         log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
1526                                 }
1527                         }
1528                 }
1529         }
1530         if ctxt.Arch.Family == sys.ARM64 && buildcfg.GOOS == "freebsd" {
1531                 // Switch to ld.bfd on freebsd/arm64.
1532                 altLinker = "bfd"
1533
1534                 // Provide a useful error if ld.bfd is missing.
1535                 name, args := flagExtld[0], flagExtld[1:]
1536                 args = append(args, "-fuse-ld=bfd", "-Wl,--version")
1537                 cmd := exec.Command(name, args...)
1538                 if out, err := cmd.CombinedOutput(); err == nil {
1539                         if !bytes.Contains(out, []byte("GNU ld")) {
1540                                 log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
1541                         }
1542                 }
1543         }
1544         if altLinker != "" {
1545                 argv = append(argv, "-fuse-ld="+altLinker)
1546         }
1547
1548         if ctxt.IsELF && len(buildinfo) > 0 {
1549                 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
1550         }
1551
1552         // On Windows, given -o foo, GCC will append ".exe" to produce
1553         // "foo.exe".  We have decided that we want to honor the -o
1554         // option. To make this work, we append a '.' so that GCC
1555         // will decide that the file already has an extension. We
1556         // only want to do this when producing a Windows output file
1557         // on a Windows host.
1558         outopt := *flagOutfile
1559         if buildcfg.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
1560                 outopt += "."
1561         }
1562         argv = append(argv, "-o")
1563         argv = append(argv, outopt)
1564
1565         if rpath.val != "" {
1566                 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
1567         }
1568
1569         if *flagInterpreter != "" {
1570                 // Many linkers support both -I and the --dynamic-linker flags
1571                 // to set the ELF interpreter, but lld only supports
1572                 // --dynamic-linker so prefer that (ld on very old Solaris only
1573                 // supports -I but that seems less important).
1574                 argv = append(argv, fmt.Sprintf("-Wl,--dynamic-linker,%s", *flagInterpreter))
1575         }
1576
1577         // Force global symbols to be exported for dlopen, etc.
1578         if ctxt.IsELF {
1579                 argv = append(argv, "-rdynamic")
1580         }
1581         if ctxt.HeadType == objabi.Haix {
1582                 fileName := xcoffCreateExportFile(ctxt)
1583                 argv = append(argv, "-Wl,-bE:"+fileName)
1584         }
1585
1586         const unusedArguments = "-Qunused-arguments"
1587         if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, unusedArguments) {
1588                 argv = append(argv, unusedArguments)
1589         }
1590
1591         const compressDWARF = "-Wl,--compress-debug-sections=zlib"
1592         if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
1593                 argv = append(argv, compressDWARF)
1594         }
1595
1596         argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
1597         argv = append(argv, hostobjCopy()...)
1598         if ctxt.HeadType == objabi.Haix {
1599                 // We want to have C files after Go files to remove
1600                 // trampolines csects made by ld.
1601                 argv = append(argv, "-nostartfiles")
1602                 argv = append(argv, "/lib/crt0_64.o")
1603
1604                 extld := ctxt.extld()
1605                 name, args := extld[0], extld[1:]
1606                 // Get starting files.
1607                 getPathFile := func(file string) string {
1608                         args := append(args, "-maix64", "--print-file-name="+file)
1609                         out, err := exec.Command(name, args...).CombinedOutput()
1610                         if err != nil {
1611                                 log.Fatalf("running %s failed: %v\n%s", extld, err, out)
1612                         }
1613                         return strings.Trim(string(out), "\n")
1614                 }
1615                 // Since GCC version 11, the 64-bit version of GCC starting files
1616                 // are now suffixed by "_64". Even under "-maix64" multilib directory
1617                 // "crtcxa.o" is 32-bit.
1618                 crtcxa := getPathFile("crtcxa_64.o")
1619                 if !filepath.IsAbs(crtcxa) {
1620                         crtcxa = getPathFile("crtcxa.o")
1621                 }
1622                 crtdbase := getPathFile("crtdbase_64.o")
1623                 if !filepath.IsAbs(crtdbase) {
1624                         crtdbase = getPathFile("crtdbase.o")
1625                 }
1626                 argv = append(argv, crtcxa)
1627                 argv = append(argv, crtdbase)
1628         }
1629
1630         if ctxt.linkShared {
1631                 seenDirs := make(map[string]bool)
1632                 seenLibs := make(map[string]bool)
1633                 addshlib := func(path string) {
1634                         dir, base := filepath.Split(path)
1635                         if !seenDirs[dir] {
1636                                 argv = append(argv, "-L"+dir)
1637                                 if !rpath.set {
1638                                         argv = append(argv, "-Wl,-rpath="+dir)
1639                                 }
1640                                 seenDirs[dir] = true
1641                         }
1642                         base = strings.TrimSuffix(base, ".so")
1643                         base = strings.TrimPrefix(base, "lib")
1644                         if !seenLibs[base] {
1645                                 argv = append(argv, "-l"+base)
1646                                 seenLibs[base] = true
1647                         }
1648                 }
1649                 for _, shlib := range ctxt.Shlibs {
1650                         addshlib(shlib.Path)
1651                         for _, dep := range shlib.Deps {
1652                                 if dep == "" {
1653                                         continue
1654                                 }
1655                                 libpath := findshlib(ctxt, dep)
1656                                 if libpath != "" {
1657                                         addshlib(libpath)
1658                                 }
1659                         }
1660                 }
1661         }
1662
1663         // clang, unlike GCC, passes -rdynamic to the linker
1664         // even when linking with -static, causing a linker
1665         // error when using GNU ld. So take out -rdynamic if
1666         // we added it. We do it in this order, rather than
1667         // only adding -rdynamic later, so that -extldflags
1668         // can override -rdynamic without using -static.
1669         // Similarly for -Wl,--dynamic-linker.
1670         checkStatic := func(arg string) {
1671                 if ctxt.IsELF && arg == "-static" {
1672                         for i := range argv {
1673                                 if argv[i] == "-rdynamic" || strings.HasPrefix(argv[i], "-Wl,--dynamic-linker,") {
1674                                         argv[i] = "-static"
1675                                 }
1676                         }
1677                 }
1678         }
1679
1680         for _, p := range ldflag {
1681                 argv = append(argv, p)
1682                 checkStatic(p)
1683         }
1684
1685         // When building a program with the default -buildmode=exe the
1686         // gc compiler generates code requires DT_TEXTREL in a
1687         // position independent executable (PIE). On systems where the
1688         // toolchain creates PIEs by default, and where DT_TEXTREL
1689         // does not work, the resulting programs will not run. See
1690         // issue #17847. To avoid this problem pass -no-pie to the
1691         // toolchain if it is supported.
1692         if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
1693                 // GCC uses -no-pie, clang uses -nopie.
1694                 for _, nopie := range []string{"-no-pie", "-nopie"} {
1695                         if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
1696                                 argv = append(argv, nopie)
1697                                 break
1698                         }
1699                 }
1700         }
1701
1702         for _, p := range flagExtldflags {
1703                 argv = append(argv, p)
1704                 checkStatic(p)
1705         }
1706         if ctxt.HeadType == objabi.Hwindows {
1707                 // Determine which linker we're using. Add in the extldflags in
1708                 // case used has specified "-fuse-ld=...".
1709                 extld := ctxt.extld()
1710                 name, args := extld[0], extld[1:]
1711                 args = append(args, flagExtldflags...)
1712                 args = append(args, "-Wl,--version")
1713                 cmd := exec.Command(name, args...)
1714                 usingLLD := false
1715                 if out, err := cmd.CombinedOutput(); err == nil {
1716                         if bytes.Contains(out, []byte("LLD ")) {
1717                                 usingLLD = true
1718                         }
1719                 }
1720
1721                 // use gcc linker script to work around gcc bug
1722                 // (see https://golang.org/issue/20183 for details).
1723                 if !usingLLD {
1724                         p := writeGDBLinkerScript()
1725                         argv = append(argv, "-Wl,-T,"+p)
1726                 }
1727                 if *flagRace {
1728                         if p := ctxt.findLibPath("libsynchronization.a"); p != "libsynchronization.a" {
1729                                 argv = append(argv, "-lsynchronization")
1730                         }
1731                 }
1732                 // libmingw32 and libmingwex have some inter-dependencies,
1733                 // so must use linker groups.
1734                 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
1735                 argv = append(argv, peimporteddlls()...)
1736         }
1737
1738         if ctxt.Debugvlog != 0 {
1739                 ctxt.Logf("host link:")
1740                 for _, v := range argv {
1741                         ctxt.Logf(" %q", v)
1742                 }
1743                 ctxt.Logf("\n")
1744         }
1745
1746         out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
1747         if err != nil {
1748                 Exitf("running %s failed: %v\n%s", argv[0], err, out)
1749         }
1750
1751         // Filter out useless linker warnings caused by bugs outside Go.
1752         // See also cmd/go/internal/work/exec.go's gccld method.
1753         var save [][]byte
1754         var skipLines int
1755         for _, line := range bytes.SplitAfter(out, []byte("\n")) {
1756                 // golang.org/issue/26073 - Apple Xcode bug
1757                 if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
1758                         continue
1759                 }
1760
1761                 if skipLines > 0 {
1762                         skipLines--
1763                         continue
1764                 }
1765
1766                 // Remove TOC overflow warning on AIX.
1767                 if bytes.Contains(line, []byte("ld: 0711-783")) {
1768                         skipLines = 2
1769                         continue
1770                 }
1771
1772                 save = append(save, line)
1773         }
1774         out = bytes.Join(save, nil)
1775
1776         if len(out) > 0 {
1777                 // always print external output even if the command is successful, so that we don't
1778                 // swallow linker warnings (see https://golang.org/issue/17935).
1779                 ctxt.Logf("%s", out)
1780         }
1781
1782         if combineDwarf {
1783                 // Find "dsymutils" and "strip" tools using CC --print-prog-name.
1784                 var cc []string
1785                 cc = append(cc, ctxt.extld()...)
1786                 cc = append(cc, hostlinkArchArgs(ctxt.Arch)...)
1787                 cc = append(cc, "--print-prog-name", "dsymutil")
1788                 out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput()
1789                 if err != nil {
1790                         Exitf("%s: finding dsymutil failed: %v\n%s", os.Args[0], err, out)
1791                 }
1792                 dsymutilCmd := strings.TrimSuffix(string(out), "\n")
1793
1794                 cc[len(cc)-1] = "strip"
1795                 out, err = exec.Command(cc[0], cc[1:]...).CombinedOutput()
1796                 if err != nil {
1797                         Exitf("%s: finding strip failed: %v\n%s", os.Args[0], err, out)
1798                 }
1799                 stripCmd := strings.TrimSuffix(string(out), "\n")
1800
1801                 dsym := filepath.Join(*flagTmpdir, "go.dwarf")
1802                 if out, err := exec.Command(dsymutilCmd, "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
1803                         Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
1804                 }
1805                 // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil).
1806                 // They contain temporary file paths and make the build not reproducible.
1807                 if out, err := exec.Command(stripCmd, "-S", *flagOutfile).CombinedOutput(); err != nil {
1808                         Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
1809                 }
1810                 // Skip combining if `dsymutil` didn't generate a file. See #11994.
1811                 if _, err := os.Stat(dsym); os.IsNotExist(err) {
1812                         return
1813                 }
1814                 // For os.Rename to work reliably, must be in same directory as outfile.
1815                 combinedOutput := *flagOutfile + "~"
1816                 exef, err := os.Open(*flagOutfile)
1817                 if err != nil {
1818                         Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1819                 }
1820                 defer exef.Close()
1821                 exem, err := macho.NewFile(exef)
1822                 if err != nil {
1823                         Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
1824                 }
1825                 if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
1826                         Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1827                 }
1828                 os.Remove(*flagOutfile)
1829                 if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
1830                         Exitf("%s: %v", os.Args[0], err)
1831                 }
1832         }
1833         if ctxt.NeedCodeSign() {
1834                 err := machoCodeSign(ctxt, *flagOutfile)
1835                 if err != nil {
1836                         Exitf("%s: code signing failed: %v", os.Args[0], err)
1837                 }
1838         }
1839 }
1840
1841 var createTrivialCOnce sync.Once
1842
1843 func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
1844         createTrivialCOnce.Do(func() {
1845                 src := filepath.Join(*flagTmpdir, "trivial.c")
1846                 if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
1847                         Errorf(nil, "WriteFile trivial.c failed: %v", err)
1848                 }
1849         })
1850
1851         flagsWithNextArgSkip := []string{
1852                 "-F",
1853                 "-l",
1854                 "-L",
1855                 "-framework",
1856                 "-Wl,-framework",
1857                 "-Wl,-rpath",
1858                 "-Wl,-undefined",
1859         }
1860         flagsWithNextArgKeep := []string{
1861                 "-arch",
1862                 "-isysroot",
1863                 "--sysroot",
1864                 "-target",
1865         }
1866         prefixesToKeep := []string{
1867                 "-f",
1868                 "-m",
1869                 "-p",
1870                 "-Wl,",
1871                 "-arch",
1872                 "-isysroot",
1873                 "--sysroot",
1874                 "-target",
1875         }
1876
1877         flags := hostlinkArchArgs(arch)
1878         keep := false
1879         skip := false
1880         for _, f := range append(flagExtldflags, ldflag...) {
1881                 if keep {
1882                         flags = append(flags, f)
1883                         keep = false
1884                 } else if skip {
1885                         skip = false
1886                 } else if f == "" || f[0] != '-' {
1887                 } else if contains(flagsWithNextArgSkip, f) {
1888                         skip = true
1889                 } else if contains(flagsWithNextArgKeep, f) {
1890                         flags = append(flags, f)
1891                         keep = true
1892                 } else {
1893                         for _, p := range prefixesToKeep {
1894                                 if strings.HasPrefix(f, p) {
1895                                         flags = append(flags, f)
1896                                         break
1897                                 }
1898                         }
1899                 }
1900         }
1901
1902         if altLinker != "" {
1903                 flags = append(flags, "-fuse-ld="+altLinker)
1904         }
1905         flags = append(flags, flag, "trivial.c")
1906
1907         cmd := exec.Command(linker, flags...)
1908         cmd.Dir = *flagTmpdir
1909         cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
1910         out, err := cmd.CombinedOutput()
1911         // GCC says "unrecognized command line option ‘-no-pie’"
1912         // clang says "unknown argument: '-no-pie'"
1913         return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
1914 }
1915
1916 // hostlinkArchArgs returns arguments to pass to the external linker
1917 // based on the architecture.
1918 func hostlinkArchArgs(arch *sys.Arch) []string {
1919         switch arch.Family {
1920         case sys.I386:
1921                 return []string{"-m32"}
1922         case sys.AMD64:
1923                 if buildcfg.GOOS == "darwin" {
1924                         return []string{"-arch", "x86_64", "-m64"}
1925                 }
1926                 return []string{"-m64"}
1927         case sys.S390X:
1928                 return []string{"-m64"}
1929         case sys.ARM:
1930                 return []string{"-marm"}
1931         case sys.ARM64:
1932                 if buildcfg.GOOS == "darwin" {
1933                         return []string{"-arch", "arm64"}
1934                 }
1935         case sys.Loong64:
1936                 return []string{"-mabi=lp64d"}
1937         case sys.MIPS64:
1938                 return []string{"-mabi=64"}
1939         case sys.MIPS:
1940                 return []string{"-mabi=32"}
1941         case sys.PPC64:
1942                 if buildcfg.GOOS == "aix" {
1943                         return []string{"-maix64"}
1944                 } else {
1945                         return []string{"-m64"}
1946                 }
1947
1948         }
1949         return nil
1950 }
1951
1952 var wantHdr = objabi.HeaderString()
1953
1954 // ldobj loads an input object. If it is a host object (an object
1955 // compiled by a non-Go compiler) it returns the Hostobj pointer. If
1956 // it is a Go object, it returns nil.
1957 func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
1958         pkg := objabi.PathToPrefix(lib.Pkg)
1959
1960         eof := f.Offset() + length
1961         start := f.Offset()
1962         c1 := bgetc(f)
1963         c2 := bgetc(f)
1964         c3 := bgetc(f)
1965         c4 := bgetc(f)
1966         f.MustSeek(start, 0)
1967
1968         unit := &sym.CompilationUnit{Lib: lib}
1969         lib.Units = append(lib.Units, unit)
1970
1971         magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
1972         if magic == 0x7f454c46 { // \x7F E L F
1973                 ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
1974                         textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags)
1975                         if err != nil {
1976                                 Errorf(nil, "%v", err)
1977                                 return
1978                         }
1979                         ehdr.Flags = flags
1980                         ctxt.Textp = append(ctxt.Textp, textp...)
1981                 }
1982                 return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
1983         }
1984
1985         if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
1986                 ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
1987                         textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
1988                         if err != nil {
1989                                 Errorf(nil, "%v", err)
1990                                 return
1991                         }
1992                         ctxt.Textp = append(ctxt.Textp, textp...)
1993                 }
1994                 return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
1995         }
1996
1997         switch c1<<8 | c2 {
1998         case 0x4c01, // 386
1999                 0x6486, // amd64
2000                 0xc401, // arm
2001                 0x64aa: // arm64
2002                 ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
2003                         textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
2004                         if err != nil {
2005                                 Errorf(nil, "%v", err)
2006                                 return
2007                         }
2008                         if len(rsrc) != 0 {
2009                                 setpersrc(ctxt, rsrc)
2010                         }
2011                         ctxt.Textp = append(ctxt.Textp, textp...)
2012                 }
2013                 return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
2014         }
2015
2016         if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
2017                 ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
2018                         textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
2019                         if err != nil {
2020                                 Errorf(nil, "%v", err)
2021                                 return
2022                         }
2023                         ctxt.Textp = append(ctxt.Textp, textp...)
2024                 }
2025                 return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
2026         }
2027
2028         if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' {
2029                 // An unrecognized object is just passed to the external linker.
2030                 // If we try to read symbols from this object, we will
2031                 // report an error at that time.
2032                 unknownObjFormat = true
2033                 return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file)
2034         }
2035
2036         /* check the header */
2037         line, err := f.ReadString('\n')
2038         if err != nil {
2039                 Errorf(nil, "truncated object file: %s: %v", pn, err)
2040                 return nil
2041         }
2042
2043         if !strings.HasPrefix(line, "go object ") {
2044                 if strings.HasSuffix(pn, ".go") {
2045                         Exitf("%s: uncompiled .go source file", pn)
2046                         return nil
2047                 }
2048
2049                 if line == ctxt.Arch.Name {
2050                         // old header format: just $GOOS
2051                         Errorf(nil, "%s: stale object file", pn)
2052                         return nil
2053                 }
2054
2055                 Errorf(nil, "%s: not an object file: @%d %q", pn, start, line)
2056                 return nil
2057         }
2058
2059         // First, check that the basic GOOS, GOARCH, and Version match.
2060         if line != wantHdr {
2061                 Errorf(nil, "%s: linked object header mismatch:\nhave %q\nwant %q\n", pn, line, wantHdr)
2062         }
2063
2064         // Skip over exports and other info -- ends with \n!\n.
2065         //
2066         // Note: It's possible for "\n!\n" to appear within the binary
2067         // package export data format. To avoid truncating the package
2068         // definition prematurely (issue 21703), we keep track of
2069         // how many "$$" delimiters we've seen.
2070
2071         import0 := f.Offset()
2072
2073         c1 = '\n' // the last line ended in \n
2074         c2 = bgetc(f)
2075         c3 = bgetc(f)
2076         markers := 0
2077         for {
2078                 if c1 == '\n' {
2079                         if markers%2 == 0 && c2 == '!' && c3 == '\n' {
2080                                 break
2081                         }
2082                         if c2 == '$' && c3 == '$' {
2083                                 markers++
2084                         }
2085                 }
2086
2087                 c1 = c2
2088                 c2 = c3
2089                 c3 = bgetc(f)
2090                 if c3 == -1 {
2091                         Errorf(nil, "truncated object file: %s", pn)
2092                         return nil
2093                 }
2094         }
2095
2096         import1 := f.Offset()
2097
2098         f.MustSeek(import0, 0)
2099         ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
2100         f.MustSeek(import1, 0)
2101
2102         fingerprint := ctxt.loader.Preload(ctxt.IncVersion(), f, lib, unit, eof-f.Offset())
2103         if !fingerprint.IsZero() { // Assembly objects don't have fingerprints. Ignore them.
2104                 // Check fingerprint, to ensure the importing and imported packages
2105                 // have consistent view of symbol indices.
2106                 // Normally the go command should ensure this. But in case something
2107                 // goes wrong, it could lead to obscure bugs like run-time crash.
2108                 // Check it here to be sure.
2109                 if lib.Fingerprint.IsZero() { // Not yet imported. Update its fingerprint.
2110                         lib.Fingerprint = fingerprint
2111                 }
2112                 checkFingerprint(lib, fingerprint, lib.Srcref, lib.Fingerprint)
2113         }
2114
2115         addImports(ctxt, lib, pn)
2116         return nil
2117 }
2118
2119 // symbolsAreUnresolved scans through the loader's list of unresolved
2120 // symbols and checks to see whether any of them match the names of the
2121 // symbols in 'want'. Return value is a list of bools, with list[K] set
2122 // to true if there is an unresolved reference to the symbol in want[K].
2123 func symbolsAreUnresolved(ctxt *Link, want []string) []bool {
2124         returnAllUndefs := -1
2125         undefs := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
2126         seen := make(map[loader.Sym]struct{})
2127         rval := make([]bool, len(want))
2128         wantm := make(map[string]int)
2129         for k, w := range want {
2130                 wantm[w] = k
2131         }
2132         count := 0
2133         for _, s := range undefs {
2134                 if _, ok := seen[s]; ok {
2135                         continue
2136                 }
2137                 seen[s] = struct{}{}
2138                 if k, ok := wantm[ctxt.loader.SymName(s)]; ok {
2139                         rval[k] = true
2140                         count++
2141                         if count == len(want) {
2142                                 return rval
2143                         }
2144                 }
2145         }
2146         return rval
2147 }
2148
2149 // hostObject reads a single host object file (compare to "hostArchive").
2150 // This is used as part of internal linking when we need to pull in
2151 // files such as "crt?.o".
2152 func hostObject(ctxt *Link, objname string, path string) {
2153         if ctxt.Debugvlog > 1 {
2154                 ctxt.Logf("hostObject(%s)\n", path)
2155         }
2156         objlib := sym.Library{
2157                 Pkg: objname,
2158         }
2159         f, err := bio.Open(path)
2160         if err != nil {
2161                 Exitf("cannot open host object %q file %s: %v", objname, path, err)
2162         }
2163         defer f.Close()
2164         h := ldobj(ctxt, f, &objlib, 0, path, path)
2165         if h.ld == nil {
2166                 Exitf("unrecognized object file format in %s", path)
2167         }
2168         f.MustSeek(h.off, 0)
2169         h.ld(ctxt, f, h.pkg, h.length, h.pn)
2170 }
2171
2172 func checkFingerprint(lib *sym.Library, libfp goobj.FingerprintType, src string, srcfp goobj.FingerprintType) {
2173         if libfp != srcfp {
2174                 Exitf("fingerprint mismatch: %s has %x, import from %s expecting %x", lib, libfp, src, srcfp)
2175         }
2176 }
2177
2178 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
2179         data := make([]byte, sym.Size)
2180         sect := f.Sections[sym.Section]
2181         if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
2182                 Errorf(nil, "reading %s from non-data section", sym.Name)
2183         }
2184         n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
2185         if uint64(n) != sym.Size {
2186                 Errorf(nil, "reading contents of %s: %v", sym.Name, err)
2187         }
2188         return data
2189 }
2190
2191 func readwithpad(r io.Reader, sz int32) ([]byte, error) {
2192         data := make([]byte, Rnd(int64(sz), 4))
2193         _, err := io.ReadFull(r, data)
2194         if err != nil {
2195                 return nil, err
2196         }
2197         data = data[:sz]
2198         return data, nil
2199 }
2200
2201 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
2202         for _, sect := range f.Sections {
2203                 if sect.Type != elf.SHT_NOTE {
2204                         continue
2205                 }
2206                 r := sect.Open()
2207                 for {
2208                         var namesize, descsize, noteType int32
2209                         err := binary.Read(r, f.ByteOrder, &namesize)
2210                         if err != nil {
2211                                 if err == io.EOF {
2212                                         break
2213                                 }
2214                                 return nil, fmt.Errorf("read namesize failed: %v", err)
2215                         }
2216                         err = binary.Read(r, f.ByteOrder, &descsize)
2217                         if err != nil {
2218                                 return nil, fmt.Errorf("read descsize failed: %v", err)
2219                         }
2220                         err = binary.Read(r, f.ByteOrder, &noteType)
2221                         if err != nil {
2222                                 return nil, fmt.Errorf("read type failed: %v", err)
2223                         }
2224                         noteName, err := readwithpad(r, namesize)
2225                         if err != nil {
2226                                 return nil, fmt.Errorf("read name failed: %v", err)
2227                         }
2228                         desc, err := readwithpad(r, descsize)
2229                         if err != nil {
2230                                 return nil, fmt.Errorf("read desc failed: %v", err)
2231                         }
2232                         if string(name) == string(noteName) && typ == noteType {
2233                                 return desc, nil
2234                         }
2235                 }
2236         }
2237         return nil, nil
2238 }
2239
2240 func findshlib(ctxt *Link, shlib string) string {
2241         if filepath.IsAbs(shlib) {
2242                 return shlib
2243         }
2244         for _, libdir := range ctxt.Libdir {
2245                 libpath := filepath.Join(libdir, shlib)
2246                 if _, err := os.Stat(libpath); err == nil {
2247                         return libpath
2248                 }
2249         }
2250         Errorf(nil, "cannot find shared library: %s", shlib)
2251         return ""
2252 }
2253
2254 func ldshlibsyms(ctxt *Link, shlib string) {
2255         var libpath string
2256         if filepath.IsAbs(shlib) {
2257                 libpath = shlib
2258                 shlib = filepath.Base(shlib)
2259         } else {
2260                 libpath = findshlib(ctxt, shlib)
2261                 if libpath == "" {
2262                         return
2263                 }
2264         }
2265         for _, processedlib := range ctxt.Shlibs {
2266                 if processedlib.Path == libpath {
2267                         return
2268                 }
2269         }
2270         if ctxt.Debugvlog > 1 {
2271                 ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
2272         }
2273
2274         f, err := elf.Open(libpath)
2275         if err != nil {
2276                 Errorf(nil, "cannot open shared library: %s", libpath)
2277                 return
2278         }
2279         // Keep the file open as decodetypeGcprog needs to read from it.
2280         // TODO: fix. Maybe mmap the file.
2281         //defer f.Close()
2282
2283         hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
2284         if err != nil {
2285                 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
2286                 return
2287         }
2288
2289         depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
2290         if err != nil {
2291                 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
2292                 return
2293         }
2294         var deps []string
2295         for _, dep := range strings.Split(string(depsbytes), "\n") {
2296                 if dep == "" {
2297                         continue
2298                 }
2299                 if !filepath.IsAbs(dep) {
2300                         // If the dep can be interpreted as a path relative to the shlib
2301                         // in which it was found, do that. Otherwise, we will leave it
2302                         // to be resolved by libdir lookup.
2303                         abs := filepath.Join(filepath.Dir(libpath), dep)
2304                         if _, err := os.Stat(abs); err == nil {
2305                                 dep = abs
2306                         }
2307                 }
2308                 deps = append(deps, dep)
2309         }
2310
2311         syms, err := f.DynamicSymbols()
2312         if err != nil {
2313                 Errorf(nil, "cannot read symbols from shared library: %s", libpath)
2314                 return
2315         }
2316
2317         for _, elfsym := range syms {
2318                 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
2319                         continue
2320                 }
2321
2322                 // Symbols whose names start with "type:" are compiler generated,
2323                 // so make functions with that prefix internal.
2324                 ver := 0
2325                 symname := elfsym.Name // (unmangled) symbol name
2326                 if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type:") {
2327                         ver = abiInternalVer
2328                 } else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
2329                         // Demangle the ABI name. Keep in sync with symtab.go:mangleABIName.
2330                         if strings.HasSuffix(elfsym.Name, ".abiinternal") {
2331                                 ver = sym.SymVerABIInternal
2332                                 symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
2333                         } else if strings.HasSuffix(elfsym.Name, ".abi0") {
2334                                 ver = 0
2335                                 symname = strings.TrimSuffix(elfsym.Name, ".abi0")
2336                         }
2337                 }
2338
2339                 l := ctxt.loader
2340                 s := l.LookupOrCreateSym(symname, ver)
2341
2342                 // Because loadlib above loads all .a files before loading
2343                 // any shared libraries, any non-dynimport symbols we find
2344                 // that duplicate symbols already loaded should be ignored
2345                 // (the symbols from the .a files "win").
2346                 if l.SymType(s) != 0 && l.SymType(s) != sym.SDYNIMPORT {
2347                         continue
2348                 }
2349                 su := l.MakeSymbolUpdater(s)
2350                 su.SetType(sym.SDYNIMPORT)
2351                 l.SetSymElfType(s, elf.ST_TYPE(elfsym.Info))
2352                 su.SetSize(int64(elfsym.Size))
2353                 if elfsym.Section != elf.SHN_UNDEF {
2354                         // Set .File for the library that actually defines the symbol.
2355                         l.SetSymPkg(s, libpath)
2356
2357                         // The decodetype_* functions in decodetype.go need access to
2358                         // the type data.
2359                         sname := l.SymName(s)
2360                         if strings.HasPrefix(sname, "type:") && !strings.HasPrefix(sname, "type:.") {
2361                                 su.SetData(readelfsymboldata(ctxt, f, &elfsym))
2362                         }
2363                 }
2364
2365                 if symname != elfsym.Name {
2366                         l.SetSymExtname(s, elfsym.Name)
2367                 }
2368         }
2369         ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f})
2370 }
2371
2372 func addsection(ldr *loader.Loader, arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
2373         sect := ldr.NewSection()
2374         sect.Rwx = uint8(rwx)
2375         sect.Name = name
2376         sect.Seg = seg
2377         sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
2378         seg.Sections = append(seg.Sections, sect)
2379         return sect
2380 }
2381
2382 func usage() {
2383         fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
2384         objabi.Flagprint(os.Stderr)
2385         Exit(2)
2386 }
2387
2388 type SymbolType int8 // TODO: after genasmsym is gone, maybe rename to plan9typeChar or something
2389
2390 const (
2391         // see also https://9p.io/magic/man2html/1/nm
2392         TextSym      SymbolType = 'T'
2393         DataSym      SymbolType = 'D'
2394         BSSSym       SymbolType = 'B'
2395         UndefinedSym SymbolType = 'U'
2396         TLSSym       SymbolType = 't'
2397         FrameSym     SymbolType = 'm'
2398         ParamSym     SymbolType = 'p'
2399         AutoSym      SymbolType = 'a'
2400
2401         // Deleted auto (not a real sym, just placeholder for type)
2402         DeletedAutoSym = 'x'
2403 )
2404
2405 // defineInternal defines a symbol used internally by the go runtime.
2406 func (ctxt *Link) defineInternal(p string, t sym.SymKind) loader.Sym {
2407         s := ctxt.loader.CreateSymForUpdate(p, 0)
2408         s.SetType(t)
2409         s.SetSpecial(true)
2410         s.SetLocal(true)
2411         return s.Sym()
2412 }
2413
2414 func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) loader.Sym {
2415         s := ctxt.defineInternal(p, t)
2416         ctxt.loader.SetSymValue(s, v)
2417         return s
2418 }
2419
2420 func datoff(ldr *loader.Loader, s loader.Sym, addr int64) int64 {
2421         if uint64(addr) >= Segdata.Vaddr {
2422                 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
2423         }
2424         if uint64(addr) >= Segtext.Vaddr {
2425                 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
2426         }
2427         ldr.Errorf(s, "invalid datoff %#x", addr)
2428         return 0
2429 }
2430
2431 func Entryvalue(ctxt *Link) int64 {
2432         a := *flagEntrySymbol
2433         if a[0] >= '0' && a[0] <= '9' {
2434                 return atolwhex(a)
2435         }
2436         ldr := ctxt.loader
2437         s := ldr.Lookup(a, 0)
2438         st := ldr.SymType(s)
2439         if st == 0 {
2440                 return *FlagTextAddr
2441         }
2442         if !ctxt.IsAIX() && st != sym.STEXT {
2443                 ldr.Errorf(s, "entry not text")
2444         }
2445         return ldr.SymValue(s)
2446 }
2447
2448 func (ctxt *Link) callgraph() {
2449         if !*FlagC {
2450                 return
2451         }
2452
2453         ldr := ctxt.loader
2454         for _, s := range ctxt.Textp {
2455                 relocs := ldr.Relocs(s)
2456                 for i := 0; i < relocs.Count(); i++ {
2457                         r := relocs.At(i)
2458                         rs := r.Sym()
2459                         if rs == 0 {
2460                                 continue
2461                         }
2462                         if r.Type().IsDirectCall() && ldr.SymType(rs) == sym.STEXT {
2463                                 ctxt.Logf("%s calls %s\n", ldr.SymName(s), ldr.SymName(rs))
2464                         }
2465                 }
2466         }
2467 }
2468
2469 func Rnd(v int64, r int64) int64 {
2470         if r <= 0 {
2471                 return v
2472         }
2473         v += r - 1
2474         c := v % r
2475         if c < 0 {
2476                 c += r
2477         }
2478         v -= c
2479         return v
2480 }
2481
2482 func bgetc(r *bio.Reader) int {
2483         c, err := r.ReadByte()
2484         if err != nil {
2485                 if err != io.EOF {
2486                         log.Fatalf("reading input: %v", err)
2487                 }
2488                 return -1
2489         }
2490         return int(c)
2491 }
2492
2493 type markKind uint8 // for postorder traversal
2494 const (
2495         _ markKind = iota
2496         visiting
2497         visited
2498 )
2499
2500 func postorder(libs []*sym.Library) []*sym.Library {
2501         order := make([]*sym.Library, 0, len(libs)) // hold the result
2502         mark := make(map[*sym.Library]markKind, len(libs))
2503         for _, lib := range libs {
2504                 dfs(lib, mark, &order)
2505         }
2506         return order
2507 }
2508
2509 func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
2510         if mark[lib] == visited {
2511                 return
2512         }
2513         if mark[lib] == visiting {
2514                 panic("found import cycle while visiting " + lib.Pkg)
2515         }
2516         mark[lib] = visiting
2517         for _, i := range lib.Imports {
2518                 dfs(i, mark, order)
2519         }
2520         mark[lib] = visited
2521         *order = append(*order, lib)
2522 }
2523
2524 func ElfSymForReloc(ctxt *Link, s loader.Sym) int32 {
2525         // If putelfsym created a local version of this symbol, use that in all
2526         // relocations.
2527         les := ctxt.loader.SymLocalElfSym(s)
2528         if les != 0 {
2529                 return les
2530         } else {
2531                 return ctxt.loader.SymElfSym(s)
2532         }
2533 }
2534
2535 func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, elfRelocTyp uint32) {
2536         if ldr.SymGot(s) >= 0 {
2537                 return
2538         }
2539
2540         Adddynsym(ldr, target, syms, s)
2541         got := ldr.MakeSymbolUpdater(syms.GOT)
2542         ldr.SetGot(s, int32(got.Size()))
2543         got.AddUint(target.Arch, 0)
2544
2545         if target.IsElf() {
2546                 if target.Arch.PtrSize == 8 {
2547                         rela := ldr.MakeSymbolUpdater(syms.Rela)
2548                         rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
2549                         rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
2550                         rela.AddUint64(target.Arch, 0)
2551                 } else {
2552                         rel := ldr.MakeSymbolUpdater(syms.Rel)
2553                         rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
2554                         rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp))
2555                 }
2556         } else if target.IsDarwin() {
2557                 leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
2558                 leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
2559                 if target.IsPIE() && target.IsInternal() {
2560                         // Mach-O relocations are a royal pain to lay out.
2561                         // They use a compact stateful bytecode representation.
2562                         // Here we record what are needed and encode them later.
2563                         MachoAddBind(int64(ldr.SymGot(s)), s)
2564                 }
2565         } else {
2566                 ldr.Errorf(s, "addgotsym: unsupported binary format")
2567         }
2568 }