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