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