]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/ld/lib.go
all: make copyright headers consistent with one space after period
[gostls13.git] / src / cmd / link / internal / ld / lib.go
1 // Inferno utils/8l/asm.c
2 // http://code.google.com/p/inferno-os/source/browse/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         "bufio"
35         "bytes"
36         "cmd/internal/bio"
37         "cmd/internal/obj"
38         "cmd/internal/sys"
39         "crypto/sha1"
40         "debug/elf"
41         "encoding/binary"
42         "fmt"
43         "io"
44         "io/ioutil"
45         "log"
46         "os"
47         "os/exec"
48         "path/filepath"
49         "runtime"
50         "strings"
51         "sync"
52 )
53
54 // Data layout and relocation.
55
56 // Derived from Inferno utils/6l/l.h
57 // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
58 //
59 //      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
60 //      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
61 //      Portions Copyright © 1997-1999 Vita Nuova Limited
62 //      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
63 //      Portions Copyright © 2004,2006 Bruce Ellis
64 //      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
65 //      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
66 //      Portions Copyright © 2009 The Go Authors. All rights reserved.
67 //
68 // Permission is hereby granted, free of charge, to any person obtaining a copy
69 // of this software and associated documentation files (the "Software"), to deal
70 // in the Software without restriction, including without limitation the rights
71 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
72 // copies of the Software, and to permit persons to whom the Software is
73 // furnished to do so, subject to the following conditions:
74 //
75 // The above copyright notice and this permission notice shall be included in
76 // all copies or substantial portions of the Software.
77 //
78 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
79 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
81 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
82 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
83 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
84 // THE SOFTWARE.
85
86 type Arch struct {
87         Funcalign        int
88         Maxalign         int
89         Minalign         int
90         Dwarfregsp       int
91         Dwarfreglr       int
92         Linuxdynld       string
93         Freebsddynld     string
94         Netbsddynld      string
95         Openbsddynld     string
96         Dragonflydynld   string
97         Solarisdynld     string
98         Adddynrel        func(*LSym, *Reloc)
99         Archinit         func()
100         Archreloc        func(*Reloc, *LSym, *int64) int
101         Archrelocvariant func(*Reloc, *LSym, int64) int64
102         Asmb             func()
103         Elfreloc1        func(*Reloc, int64) int
104         Elfsetupplt      func()
105         Gentext          func()
106         Machoreloc1      func(*Reloc, int64) int
107         PEreloc1         func(*Reloc, int64) bool
108         Wput             func(uint16)
109         Lput             func(uint32)
110         Vput             func(uint64)
111         Append16         func(b []byte, v uint16) []byte
112         Append32         func(b []byte, v uint32) []byte
113         Append64         func(b []byte, v uint64) []byte
114 }
115
116 type Rpath struct {
117         set bool
118         val string
119 }
120
121 func (r *Rpath) Set(val string) error {
122         r.set = true
123         r.val = val
124         return nil
125 }
126
127 func (r *Rpath) String() string {
128         return r.val
129 }
130
131 var (
132         Thearch Arch
133         Debug   [128]int
134         Lcsize  int32
135         rpath   Rpath
136         Spsize  int32
137         Symsize int32
138 )
139
140 // Terrible but standard terminology.
141 // A segment describes a block of file to load into memory.
142 // A section further describes the pieces of that block for
143 // use in debuggers and such.
144
145 const (
146         MINFUNC = 16 // minimum size for a function
147 )
148
149 type Segment struct {
150         Rwx     uint8  // permission as usual unix bits (5 = r-x etc)
151         Vaddr   uint64 // virtual address
152         Length  uint64 // length in memory
153         Fileoff uint64 // file offset
154         Filelen uint64 // length on disk
155         Sect    *Section
156 }
157
158 type Section struct {
159         Rwx     uint8
160         Extnum  int16
161         Align   int32
162         Name    string
163         Vaddr   uint64
164         Length  uint64
165         Next    *Section
166         Seg     *Segment
167         Elfsect *ElfShdr
168         Reloff  uint64
169         Rellen  uint64
170 }
171
172 // DynlinkingGo returns whether we are producing Go code that can live
173 // in separate shared libraries linked together at runtime.
174 func DynlinkingGo() bool {
175         return Buildmode == BuildmodeShared || Linkshared
176 }
177
178 // UseRelro returns whether to make use of "read only relocations" aka
179 // relro.
180 func UseRelro() bool {
181         switch Buildmode {
182         case BuildmodeCShared, BuildmodeShared, BuildmodePIE:
183                 return Iself
184         default:
185                 return Linkshared
186         }
187 }
188
189 var (
190         SysArch            *sys.Arch
191         outfile            string
192         dynexp             []*LSym
193         dynlib             []string
194         ldflag             []string
195         havedynamic        int
196         Funcalign          int
197         iscgo              bool
198         elfglobalsymndx    int
199         flag_dumpdep       bool
200         flag_installsuffix string
201         flag_race          int
202         flag_msan          int
203         Buildmode          BuildMode
204         Linkshared         bool
205         tracksym           string
206         interpreter        string
207         tmpdir             string
208         extld              string
209         extldflags         string
210         extar              string
211         libgccfile         string
212         debug_s            int // backup old value of debug['s']
213         Ctxt               *Link
214         HEADR              int32
215         HEADTYPE           int32
216         INITRND            int32
217         INITTEXT           int64
218         INITDAT            int64
219         INITENTRY          string /* entry point */
220         nerrors            int
221         Linkmode           int
222         liveness           int64
223 )
224
225 var (
226         Segtext   Segment
227         Segrodata Segment
228         Segdata   Segment
229         Segdwarf  Segment
230 )
231
232 /* set by call to mywhatsys() */
233
234 /* whence for ldpkg */
235 const (
236         FileObj = 0 + iota
237         ArchiveObj
238         Pkgdef
239 )
240
241 var (
242         headstring string
243         // buffered output
244         Bso *bufio.Writer
245 )
246
247 // TODO(dfc) outBuf duplicates bio.Writer
248 type outBuf struct {
249         w   *bufio.Writer
250         f   *os.File
251         off int64
252 }
253
254 func (w *outBuf) Write(p []byte) (n int, err error) {
255         n, err = w.w.Write(p)
256         w.off += int64(n)
257         return n, err
258 }
259
260 func (w *outBuf) WriteString(s string) (n int, err error) {
261         n, err = coutbuf.w.WriteString(s)
262         w.off += int64(n)
263         return n, err
264 }
265
266 var coutbuf outBuf
267
268 const pkgname = "__.PKGDEF"
269
270 var (
271         // Set if we see an object compiled by the host compiler that is not
272         // from a package that is known to support internal linking mode.
273         externalobj = false
274         goroot      string
275         goarch      string
276         goos        string
277         theline     string
278 )
279
280 func Lflag(arg string) {
281         Ctxt.Libdir = append(Ctxt.Libdir, arg)
282 }
283
284 // A BuildMode indicates the sort of object we are building:
285 //   "exe": build a main package and everything it imports into an executable.
286 //   "c-shared": build a main package, plus all packages that it imports, into a
287 //     single C shared library. The only callable symbols will be those functions
288 //     marked as exported.
289 //   "shared": combine all packages passed on the command line, and their
290 //     dependencies, into a single shared library that will be used when
291 //     building with the -linkshared option.
292 type BuildMode uint8
293
294 const (
295         BuildmodeUnset BuildMode = iota
296         BuildmodeExe
297         BuildmodePIE
298         BuildmodeCArchive
299         BuildmodeCShared
300         BuildmodeShared
301 )
302
303 func (mode *BuildMode) Set(s string) error {
304         goos := obj.Getgoos()
305         goarch := obj.Getgoarch()
306         badmode := func() error {
307                 return fmt.Errorf("buildmode %s not supported on %s/%s", s, goos, goarch)
308         }
309         switch s {
310         default:
311                 return fmt.Errorf("invalid buildmode: %q", s)
312         case "exe":
313                 *mode = BuildmodeExe
314         case "pie":
315                 switch goos {
316                 case "android", "linux":
317                 default:
318                         return badmode()
319                 }
320                 *mode = BuildmodePIE
321         case "c-archive":
322                 switch goos {
323                 case "darwin", "linux":
324                 case "windows":
325                         switch goarch {
326                         case "amd64", "386":
327                         default:
328                                 return badmode()
329                         }
330                 default:
331                         return badmode()
332                 }
333                 *mode = BuildmodeCArchive
334         case "c-shared":
335                 switch goarch {
336                 case "386", "amd64", "arm", "arm64":
337                 default:
338                         return badmode()
339                 }
340                 *mode = BuildmodeCShared
341         case "shared":
342                 switch goos {
343                 case "linux":
344                         switch goarch {
345                         case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
346                         default:
347                                 return badmode()
348                         }
349                 default:
350                         return badmode()
351                 }
352                 *mode = BuildmodeShared
353         }
354         return nil
355 }
356
357 func (mode *BuildMode) String() string {
358         switch *mode {
359         case BuildmodeUnset:
360                 return "" // avoid showing a default in usage message
361         case BuildmodeExe:
362                 return "exe"
363         case BuildmodePIE:
364                 return "pie"
365         case BuildmodeCArchive:
366                 return "c-archive"
367         case BuildmodeCShared:
368                 return "c-shared"
369         case BuildmodeShared:
370                 return "shared"
371         }
372         return fmt.Sprintf("BuildMode(%d)", uint8(*mode))
373 }
374
375 /*
376  * Unix doesn't like it when we write to a running (or, sometimes,
377  * recently run) binary, so remove the output file before writing it.
378  * On Windows 7, remove() can force a subsequent create() to fail.
379  * S_ISREG() does not exist on Plan 9.
380  */
381 func mayberemoveoutfile() {
382         if fi, err := os.Lstat(outfile); err == nil && !fi.Mode().IsRegular() {
383                 return
384         }
385         os.Remove(outfile)
386 }
387
388 func libinit() {
389         Funcalign = Thearch.Funcalign
390         mywhatsys() // get goroot, goarch, goos
391
392         // add goroot to the end of the libdir list.
393         suffix := ""
394
395         suffixsep := ""
396         if flag_installsuffix != "" {
397                 suffixsep = "_"
398                 suffix = flag_installsuffix
399         } else if flag_race != 0 {
400                 suffixsep = "_"
401                 suffix = "race"
402         } else if flag_msan != 0 {
403                 suffixsep = "_"
404                 suffix = "msan"
405         }
406
407         Lflag(filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s%s%s", goos, goarch, suffixsep, suffix)))
408
409         mayberemoveoutfile()
410         f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
411         if err != nil {
412                 Exitf("cannot create %s: %v", outfile, err)
413         }
414
415         coutbuf.w = bufio.NewWriter(f)
416         coutbuf.f = f
417
418         if INITENTRY == "" {
419                 switch Buildmode {
420                 case BuildmodeCShared, BuildmodeCArchive:
421                         INITENTRY = fmt.Sprintf("_rt0_%s_%s_lib", goarch, goos)
422                 case BuildmodeExe, BuildmodePIE:
423                         INITENTRY = fmt.Sprintf("_rt0_%s_%s", goarch, goos)
424                 case BuildmodeShared:
425                         // No INITENTRY for -buildmode=shared
426                 default:
427                         Diag("unknown INITENTRY for buildmode %v", Buildmode)
428                 }
429         }
430
431         if !DynlinkingGo() {
432                 Linklookup(Ctxt, INITENTRY, 0).Type = obj.SXREF
433         }
434 }
435
436 func Exitf(format string, a ...interface{}) {
437         fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
438         if coutbuf.f != nil {
439                 coutbuf.f.Close()
440                 mayberemoveoutfile()
441         }
442         Exit(2)
443 }
444
445 func errorexit() {
446         if coutbuf.f != nil {
447                 if nerrors != 0 {
448                         Cflush()
449                 }
450                 // For rmtemp run at atexit time on Windows.
451                 if err := coutbuf.f.Close(); err != nil {
452                         Exitf("close: %v", err)
453                 }
454         }
455
456         if nerrors != 0 {
457                 if coutbuf.f != nil {
458                         mayberemoveoutfile()
459                 }
460                 Exit(2)
461         }
462
463         Exit(0)
464 }
465
466 func loadinternal(name string) {
467         found := 0
468         for i := 0; i < len(Ctxt.Libdir); i++ {
469                 if Linkshared {
470                         shlibname := filepath.Join(Ctxt.Libdir[i], name+".shlibname")
471                         if Debug['v'] != 0 {
472                                 fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, shlibname)
473                         }
474                         if _, err := os.Stat(shlibname); err == nil {
475                                 addlibpath(Ctxt, "internal", "internal", "", name, shlibname)
476                                 found = 1
477                                 break
478                         }
479                 }
480                 pname := filepath.Join(Ctxt.Libdir[i], name+".a")
481                 if Debug['v'] != 0 {
482                         fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, pname)
483                 }
484                 if _, err := os.Stat(pname); err == nil {
485                         addlibpath(Ctxt, "internal", "internal", pname, name, "")
486                         found = 1
487                         break
488                 }
489         }
490
491         if found == 0 {
492                 fmt.Fprintf(Bso, "warning: unable to find %s.a\n", name)
493         }
494 }
495
496 func loadlib() {
497         switch Buildmode {
498         case BuildmodeCShared:
499                 s := Linklookup(Ctxt, "runtime.islibrary", 0)
500                 s.Attr |= AttrDuplicateOK
501                 Adduint8(Ctxt, s, 1)
502         case BuildmodeCArchive:
503                 s := Linklookup(Ctxt, "runtime.isarchive", 0)
504                 s.Attr |= AttrDuplicateOK
505                 Adduint8(Ctxt, s, 1)
506         }
507
508         loadinternal("runtime")
509         if SysArch.Family == sys.ARM {
510                 loadinternal("math")
511         }
512         if flag_race != 0 {
513                 loadinternal("runtime/race")
514         }
515         if flag_msan != 0 {
516                 loadinternal("runtime/msan")
517         }
518
519         var i int
520         for i = 0; i < len(Ctxt.Library); i++ {
521                 iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo"
522                 if Ctxt.Library[i].Shlib == "" {
523                         if Debug['v'] > 1 {
524                                 fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
525                         }
526                         objfile(Ctxt.Library[i])
527                 }
528         }
529
530         for i = 0; i < len(Ctxt.Library); i++ {
531                 if Ctxt.Library[i].Shlib != "" {
532                         if Debug['v'] > 1 {
533                                 fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].Shlib, Ctxt.Library[i].Objref)
534                         }
535                         ldshlibsyms(Ctxt.Library[i].Shlib)
536                 }
537         }
538
539         if Linkmode == LinkAuto {
540                 if iscgo && externalobj {
541                         Linkmode = LinkExternal
542                 } else {
543                         Linkmode = LinkInternal
544                 }
545
546                 // Force external linking for android.
547                 if goos == "android" {
548                         Linkmode = LinkExternal
549                 }
550
551                 // Force external linking for PIE executables, as
552                 // internal linking does not support TLS_IE.
553                 if Buildmode == BuildmodePIE {
554                         Linkmode = LinkExternal
555                 }
556
557                 // cgo on Darwin must use external linking
558                 // we can always use external linking, but then there will be circular
559                 // dependency problems when compiling natively (external linking requires
560                 // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be
561                 // compiled using external linking.)
562                 if SysArch.InFamily(sys.ARM, sys.ARM64) && HEADTYPE == obj.Hdarwin && iscgo {
563                         Linkmode = LinkExternal
564                 }
565
566                 // Force external linking for msan.
567                 if flag_msan != 0 {
568                         Linkmode = LinkExternal
569                 }
570         }
571
572         // cmd/7l doesn't support cgo internal linking
573         // This is https://golang.org/issue/10373.
574         if iscgo && goarch == "arm64" {
575                 Linkmode = LinkExternal
576         }
577
578         if Linkmode == LinkExternal && !iscgo {
579                 // This indicates a user requested -linkmode=external.
580                 // The startup code uses an import of runtime/cgo to decide
581                 // whether to initialize the TLS.  So give it one. This could
582                 // be handled differently but it's an unusual case.
583                 loadinternal("runtime/cgo")
584
585                 if i < len(Ctxt.Library) {
586                         if Ctxt.Library[i].Shlib != "" {
587                                 ldshlibsyms(Ctxt.Library[i].Shlib)
588                         } else {
589                                 if DynlinkingGo() {
590                                         Exitf("cannot implicitly include runtime/cgo in a shared library")
591                                 }
592                                 objfile(Ctxt.Library[i])
593                         }
594                 }
595         }
596
597         if Linkmode == LinkInternal {
598                 // Drop all the cgo_import_static declarations.
599                 // Turns out we won't be needing them.
600                 for _, s := range Ctxt.Allsym {
601                         if s.Type == obj.SHOSTOBJ {
602                                 // If a symbol was marked both
603                                 // cgo_import_static and cgo_import_dynamic,
604                                 // then we want to make it cgo_import_dynamic
605                                 // now.
606                                 if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
607                                         s.Type = obj.SDYNIMPORT
608                                 } else {
609                                         s.Type = 0
610                                 }
611                         }
612                 }
613         }
614
615         tlsg := Linklookup(Ctxt, "runtime.tlsg", 0)
616
617         // runtime.tlsg is used for external linking on platforms that do not define
618         // a variable to hold g in assembly (currently only intel).
619         if tlsg.Type == 0 {
620                 tlsg.Type = obj.STLSBSS
621                 tlsg.Size = int64(SysArch.PtrSize)
622         } else if tlsg.Type != obj.SDYNIMPORT {
623                 Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
624         }
625         tlsg.Attr |= AttrReachable
626         Ctxt.Tlsg = tlsg
627
628         moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0)
629         if moduledata.Type != 0 && moduledata.Type != obj.SDYNIMPORT {
630                 // If the module (toolchain-speak for "executable or shared
631                 // library") we are linking contains the runtime package, it
632                 // will define the runtime.firstmoduledata symbol and we
633                 // truncate it back to 0 bytes so we can define its entire
634                 // contents in symtab.go:symtab().
635                 moduledata.Size = 0
636
637                 // In addition, on ARM, the runtime depends on the linker
638                 // recording the value of GOARM.
639                 if SysArch.Family == sys.ARM {
640                         s := Linklookup(Ctxt, "runtime.goarm", 0)
641
642                         s.Type = obj.SRODATA
643                         s.Size = 0
644                         Adduint8(Ctxt, s, uint8(Ctxt.Goarm))
645                 }
646         } else {
647                 // If OTOH the module does not contain the runtime package,
648                 // create a local symbol for the moduledata.
649                 moduledata = Linklookup(Ctxt, "local.moduledata", 0)
650                 moduledata.Attr |= AttrLocal
651         }
652         // In all cases way we mark the moduledata as noptrdata to hide it from
653         // the GC.
654         moduledata.Type = obj.SNOPTRDATA
655         moduledata.Attr |= AttrReachable
656         Ctxt.Moduledata = moduledata
657
658         // Now that we know the link mode, trim the dynexp list.
659         x := AttrCgoExportDynamic
660
661         if Linkmode == LinkExternal {
662                 x = AttrCgoExportStatic
663         }
664         w := 0
665         for i := 0; i < len(dynexp); i++ {
666                 if dynexp[i].Attr&x != 0 {
667                         dynexp[w] = dynexp[i]
668                         w++
669                 }
670         }
671         dynexp = dynexp[:w]
672
673         // In internal link mode, read the host object files.
674         if Linkmode == LinkInternal {
675                 hostobjs()
676
677                 // If we have any undefined symbols in external
678                 // objects, try to read them from the libgcc file.
679                 any := false
680                 for _, s := range Ctxt.Allsym {
681                         for _, r := range s.R {
682                                 if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF && r.Sym.Name != ".got" {
683                                         any = true
684                                         break
685                                 }
686                         }
687                 }
688                 if any {
689                         if libgccfile == "" {
690                                 if extld == "" {
691                                         extld = "gcc"
692                                 }
693                                 args := hostlinkArchArgs()
694                                 args = append(args, "--print-libgcc-file-name")
695                                 if Debug['v'] != 0 {
696                                         fmt.Fprintf(Bso, "%s %v\n", extld, args)
697                                 }
698                                 out, err := exec.Command(extld, args...).Output()
699                                 if err != nil {
700                                         if Debug['v'] != 0 {
701                                                 fmt.Fprintln(Bso, "not using a libgcc file because compiler failed")
702                                                 fmt.Fprintf(Bso, "%v\n%s\n", err, out)
703                                         }
704                                         libgccfile = "none"
705                                 } else {
706                                         libgccfile = strings.TrimSpace(string(out))
707                                 }
708                         }
709
710                         if libgccfile != "none" {
711                                 hostArchive(libgccfile)
712                         }
713                 }
714         } else {
715                 hostlinksetup()
716         }
717
718         // We've loaded all the code now.
719         // If there are no dynamic libraries needed, gcc disables dynamic linking.
720         // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
721         // assumes that a dynamic binary always refers to at least one dynamic library.
722         // Rather than be a source of test cases for glibc, disable dynamic linking
723         // the same way that gcc would.
724         //
725         // Exception: on OS X, programs such as Shark only work with dynamic
726         // binaries, so leave it enabled on OS X (Mach-O) binaries.
727         // Also leave it enabled on Solaris which doesn't support
728         // statically linked binaries.
729         switch Buildmode {
730         case BuildmodeExe, BuildmodePIE:
731                 if havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris {
732                         Debug['d'] = 1
733                 }
734         }
735
736         importcycles()
737 }
738
739 /*
740  * look for the next file in an archive.
741  * adapted from libmach.
742  */
743 func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
744         if off&1 != 0 {
745                 off++
746         }
747         bp.Seek(off, 0)
748         var buf [SAR_HDR]byte
749         if n, err := io.ReadFull(bp, buf[:]); err != nil {
750                 if n == 0 && err != io.EOF {
751                         return -1
752                 }
753                 return 0
754         }
755
756         a.name = artrim(buf[0:16])
757         a.date = artrim(buf[16:28])
758         a.uid = artrim(buf[28:34])
759         a.gid = artrim(buf[34:40])
760         a.mode = artrim(buf[40:48])
761         a.size = artrim(buf[48:58])
762         a.fmag = artrim(buf[58:60])
763
764         arsize := atolwhex(a.size)
765         if arsize&1 != 0 {
766                 arsize++
767         }
768         return arsize + SAR_HDR
769 }
770
771 func objfile(lib *Library) {
772         pkg := pathtoprefix(lib.Pkg)
773
774         if Debug['v'] > 1 {
775                 fmt.Fprintf(Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg)
776         }
777         Bso.Flush()
778         f, err := bio.Open(lib.File)
779         if err != nil {
780                 Exitf("cannot open file %s: %v", lib.File, err)
781         }
782
783         for i := 0; i < len(ARMAG); i++ {
784                 if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
785                         continue
786                 }
787
788                 /* load it as a regular file */
789                 l := f.Seek(0, 2)
790
791                 f.Seek(0, 0)
792                 ldobj(f, pkg, l, lib.File, lib.File, FileObj)
793                 f.Close()
794
795                 return
796         }
797
798         /* process __.PKGDEF */
799         off := f.Offset()
800
801         var arhdr ArHdr
802         l := nextar(f, off, &arhdr)
803         var pname string
804         if l <= 0 {
805                 Diag("%s: short read on archive file symbol header", lib.File)
806                 goto out
807         }
808
809         if !strings.HasPrefix(arhdr.name, pkgname) {
810                 Diag("%s: cannot find package header", lib.File)
811                 goto out
812         }
813
814         if Buildmode == BuildmodeShared {
815                 before := f.Offset()
816                 pkgdefBytes := make([]byte, atolwhex(arhdr.size))
817                 if _, err := io.ReadFull(f, pkgdefBytes); err != nil {
818                         Diag("%s: short read on archive file symbol header: %v", lib.File, err)
819                 }
820                 hash := sha1.Sum(pkgdefBytes)
821                 lib.hash = hash[:]
822                 f.Seek(before, 0)
823         }
824
825         off += l
826
827         ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
828
829         /*
830          * load all the object files from the archive now.
831          * this gives us sequential file access and keeps us
832          * from needing to come back later to pick up more
833          * objects.  it breaks the usual C archive model, but
834          * this is Go, not C.  the common case in Go is that
835          * we need to load all the objects, and then we throw away
836          * the individual symbols that are unused.
837          *
838          * loading every object will also make it possible to
839          * load foreign objects not referenced by __.PKGDEF.
840          */
841         for {
842                 l = nextar(f, off, &arhdr)
843                 if l == 0 {
844                         break
845                 }
846                 if l < 0 {
847                         Exitf("%s: malformed archive", lib.File)
848                 }
849
850                 off += l
851
852                 pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
853                 l = atolwhex(arhdr.size)
854                 ldobj(f, pkg, l, pname, lib.File, ArchiveObj)
855         }
856
857 out:
858         f.Close()
859 }
860
861 type Hostobj struct {
862         ld     func(*bio.Reader, string, int64, string)
863         pkg    string
864         pn     string
865         file   string
866         off    int64
867         length int64
868 }
869
870 var hostobj []Hostobj
871
872 // These packages can use internal linking mode.
873 // Others trigger external mode.
874 var internalpkg = []string{
875         "crypto/x509",
876         "net",
877         "os/user",
878         "runtime/cgo",
879         "runtime/race",
880         "runtime/msan",
881 }
882
883 func ldhostobj(ld func(*bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
884         isinternal := false
885         for i := 0; i < len(internalpkg); i++ {
886                 if pkg == internalpkg[i] {
887                         isinternal = true
888                         break
889                 }
890         }
891
892         // DragonFly declares errno with __thread, which results in a symbol
893         // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
894         // currently know how to handle TLS relocations, hence we have to
895         // force external linking for any libraries that link in code that
896         // uses errno. This can be removed if the Go linker ever supports
897         // these relocation types.
898         if HEADTYPE == obj.Hdragonfly {
899                 if pkg == "net" || pkg == "os/user" {
900                         isinternal = false
901                 }
902         }
903
904         if !isinternal {
905                 externalobj = true
906         }
907
908         hostobj = append(hostobj, Hostobj{})
909         h := &hostobj[len(hostobj)-1]
910         h.ld = ld
911         h.pkg = pkg
912         h.pn = pn
913         h.file = file
914         h.off = f.Offset()
915         h.length = length
916         return h
917 }
918
919 func hostobjs() {
920         var h *Hostobj
921
922         for i := 0; i < len(hostobj); i++ {
923                 h = &hostobj[i]
924                 f, err := bio.Open(h.file)
925                 if err != nil {
926                         Exitf("cannot reopen %s: %v", h.pn, err)
927                 }
928
929                 f.Seek(h.off, 0)
930                 h.ld(f, h.pkg, h.length, h.pn)
931                 f.Close()
932         }
933 }
934
935 // provided by lib9
936
937 func rmtemp() {
938         os.RemoveAll(tmpdir)
939 }
940
941 func hostlinksetup() {
942         if Linkmode != LinkExternal {
943                 return
944         }
945
946         // For external link, record that we need to tell the external linker -s,
947         // and turn off -s internally: the external linker needs the symbol
948         // information for its final link.
949         debug_s = Debug['s']
950         Debug['s'] = 0
951
952         // create temporary directory and arrange cleanup
953         if tmpdir == "" {
954                 dir, err := ioutil.TempDir("", "go-link-")
955                 if err != nil {
956                         log.Fatal(err)
957                 }
958                 tmpdir = dir
959                 AtExit(rmtemp)
960         }
961
962         // change our output to temporary object file
963         coutbuf.f.Close()
964         mayberemoveoutfile()
965
966         p := filepath.Join(tmpdir, "go.o")
967         var err error
968         f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
969         if err != nil {
970                 Exitf("cannot create %s: %v", p, err)
971         }
972
973         coutbuf.w = bufio.NewWriter(f)
974         coutbuf.f = f
975 }
976
977 // hostobjCopy creates a copy of the object files in hostobj in a
978 // temporary directory.
979 func hostobjCopy() (paths []string) {
980         var wg sync.WaitGroup
981         sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
982         for i, h := range hostobj {
983                 h := h
984                 dst := filepath.Join(tmpdir, fmt.Sprintf("%06d.o", i))
985                 paths = append(paths, dst)
986
987                 wg.Add(1)
988                 go func() {
989                         sema <- struct{}{}
990                         defer func() {
991                                 <-sema
992                                 wg.Done()
993                         }()
994                         f, err := os.Open(h.file)
995                         if err != nil {
996                                 Exitf("cannot reopen %s: %v", h.pn, err)
997                         }
998                         if _, err := f.Seek(h.off, 0); err != nil {
999                                 Exitf("cannot seek %s: %v", h.pn, err)
1000                         }
1001
1002                         w, err := os.Create(dst)
1003                         if err != nil {
1004                                 Exitf("cannot create %s: %v", dst, err)
1005                         }
1006                         if _, err := io.CopyN(w, f, h.length); err != nil {
1007                                 Exitf("cannot write %s: %v", dst, err)
1008                         }
1009                         if err := w.Close(); err != nil {
1010                                 Exitf("cannot close %s: %v", dst, err)
1011                         }
1012                 }()
1013         }
1014         wg.Wait()
1015         return paths
1016 }
1017
1018 // archive builds a .a archive from the hostobj object files.
1019 func archive() {
1020         if Buildmode != BuildmodeCArchive {
1021                 return
1022         }
1023
1024         if extar == "" {
1025                 extar = "ar"
1026         }
1027
1028         mayberemoveoutfile()
1029
1030         // Force the buffer to flush here so that external
1031         // tools will see a complete file.
1032         Cflush()
1033         if err := coutbuf.f.Close(); err != nil {
1034                 Exitf("close: %v", err)
1035         }
1036         coutbuf.f = nil
1037
1038         argv := []string{extar, "-q", "-c", "-s", outfile}
1039         argv = append(argv, filepath.Join(tmpdir, "go.o"))
1040         argv = append(argv, hostobjCopy()...)
1041
1042         if Debug['v'] != 0 {
1043                 fmt.Fprintf(Bso, "archive: %s\n", strings.Join(argv, " "))
1044                 Bso.Flush()
1045         }
1046
1047         if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
1048                 Exitf("running %s failed: %v\n%s", argv[0], err, out)
1049         }
1050 }
1051
1052 func hostlink() {
1053         if Linkmode != LinkExternal || nerrors > 0 {
1054                 return
1055         }
1056         if Buildmode == BuildmodeCArchive {
1057                 return
1058         }
1059
1060         if extld == "" {
1061                 extld = "gcc"
1062         }
1063
1064         var argv []string
1065         argv = append(argv, extld)
1066         argv = append(argv, hostlinkArchArgs()...)
1067
1068         if Debug['s'] == 0 && debug_s == 0 {
1069                 argv = append(argv, "-gdwarf-2")
1070         } else {
1071                 argv = append(argv, "-s")
1072         }
1073
1074         if HEADTYPE == obj.Hdarwin {
1075                 argv = append(argv, "-Wl,-no_pie,-headerpad,1144")
1076         }
1077         if HEADTYPE == obj.Hopenbsd {
1078                 argv = append(argv, "-Wl,-nopie")
1079         }
1080         if HEADTYPE == obj.Hwindows {
1081                 if headstring == "windowsgui" {
1082                         argv = append(argv, "-mwindows")
1083                 } else {
1084                         argv = append(argv, "-mconsole")
1085                 }
1086         }
1087
1088         switch Buildmode {
1089         case BuildmodeExe:
1090                 if HEADTYPE == obj.Hdarwin {
1091                         argv = append(argv, "-Wl,-pagezero_size,4000000")
1092                 }
1093         case BuildmodePIE:
1094                 if UseRelro() {
1095                         argv = append(argv, "-Wl,-z,relro")
1096                 }
1097                 argv = append(argv, "-pie")
1098         case BuildmodeCShared:
1099                 if HEADTYPE == obj.Hdarwin {
1100                         argv = append(argv, "-dynamiclib", "-Wl,-read_only_relocs,suppress")
1101                 } else {
1102                         // ELF.
1103                         argv = append(argv, "-Wl,-Bsymbolic")
1104                         if UseRelro() {
1105                                 argv = append(argv, "-Wl,-z,relro")
1106                         }
1107                         // Pass -z nodelete to mark the shared library as
1108                         // non-closeable: a dlclose will do nothing.
1109                         argv = append(argv, "-shared", "-Wl,-z,nodelete")
1110                 }
1111         case BuildmodeShared:
1112                 if UseRelro() {
1113                         argv = append(argv, "-Wl,-z,relro")
1114                 }
1115                 argv = append(argv, "-shared")
1116         }
1117
1118         if Iself && DynlinkingGo() {
1119                 // We force all symbol resolution to be done at program startup
1120                 // because lazy PLT resolution can use large amounts of stack at
1121                 // times we cannot allow it to do so.
1122                 argv = append(argv, "-Wl,-znow")
1123
1124                 // Do not let the host linker generate COPY relocations. These
1125                 // can move symbols out of sections that rely on stable offsets
1126                 // from the beginning of the section (like STYPE).
1127                 argv = append(argv, "-Wl,-znocopyreloc")
1128
1129                 if SysArch.InFamily(sys.ARM, sys.ARM64) {
1130                         // On ARM, the GNU linker will generate COPY relocations
1131                         // even with -znocopyreloc set.
1132                         // https://sourceware.org/bugzilla/show_bug.cgi?id=19962
1133                         //
1134                         // On ARM64, the GNU linker will fail instead of
1135                         // generating COPY relocations.
1136                         //
1137                         // In both cases, switch to gold.
1138                         argv = append(argv, "-fuse-ld=gold")
1139                 }
1140         }
1141
1142         if Iself && len(buildinfo) > 0 {
1143                 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
1144         }
1145
1146         // On Windows, given -o foo, GCC will append ".exe" to produce
1147         // "foo.exe".  We have decided that we want to honor the -o
1148         // option. To make this work, we append a '.' so that GCC
1149         // will decide that the file already has an extension. We
1150         // only want to do this when producing a Windows output file
1151         // on a Windows host.
1152         outopt := outfile
1153         if goos == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
1154                 outopt += "."
1155         }
1156         argv = append(argv, "-o")
1157         argv = append(argv, outopt)
1158
1159         if rpath.val != "" {
1160                 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
1161         }
1162
1163         // Force global symbols to be exported for dlopen, etc.
1164         if Iself {
1165                 argv = append(argv, "-rdynamic")
1166         }
1167
1168         if strings.Contains(argv[0], "clang") {
1169                 argv = append(argv, "-Qunused-arguments")
1170         }
1171
1172         argv = append(argv, filepath.Join(tmpdir, "go.o"))
1173         argv = append(argv, hostobjCopy()...)
1174
1175         if Linkshared {
1176                 seenDirs := make(map[string]bool)
1177                 seenLibs := make(map[string]bool)
1178                 addshlib := func(path string) {
1179                         dir, base := filepath.Split(path)
1180                         if !seenDirs[dir] {
1181                                 argv = append(argv, "-L"+dir)
1182                                 if !rpath.set {
1183                                         argv = append(argv, "-Wl,-rpath="+dir)
1184                                 }
1185                                 seenDirs[dir] = true
1186                         }
1187                         base = strings.TrimSuffix(base, ".so")
1188                         base = strings.TrimPrefix(base, "lib")
1189                         if !seenLibs[base] {
1190                                 argv = append(argv, "-l"+base)
1191                                 seenLibs[base] = true
1192                         }
1193                 }
1194                 for _, shlib := range Ctxt.Shlibs {
1195                         addshlib(shlib.Path)
1196                         for _, dep := range shlib.Deps {
1197                                 if dep == "" {
1198                                         continue
1199                                 }
1200                                 libpath := findshlib(dep)
1201                                 if libpath != "" {
1202                                         addshlib(libpath)
1203                                 }
1204                         }
1205                 }
1206         }
1207
1208         argv = append(argv, ldflag...)
1209
1210         if flag_race != 0 {
1211                 // On a system where the toolchain creates position independent
1212                 // executables by default, tsan initialization can fail. So we pass
1213                 // -no-pie here, but support for that flag is quite new and we test
1214                 // for its support first.
1215                 src := filepath.Join(tmpdir, "trivial.c")
1216                 if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
1217                         Ctxt.Diag("WriteFile trivial.c failed: %v", err)
1218                 }
1219                 cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c")
1220                 cmd.Dir = tmpdir
1221                 out, err := cmd.CombinedOutput()
1222                 supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
1223                 if supported {
1224                         argv = append(argv, "-no-pie")
1225                 }
1226         }
1227
1228         for _, p := range strings.Fields(extldflags) {
1229                 argv = append(argv, p)
1230
1231                 // clang, unlike GCC, passes -rdynamic to the linker
1232                 // even when linking with -static, causing a linker
1233                 // error when using GNU ld. So take out -rdynamic if
1234                 // we added it. We do it in this order, rather than
1235                 // only adding -rdynamic later, so that -extldflags
1236                 // can override -rdynamic without using -static.
1237                 if Iself && p == "-static" {
1238                         for i := range argv {
1239                                 if argv[i] == "-rdynamic" {
1240                                         argv[i] = "-static"
1241                                 }
1242                         }
1243                 }
1244         }
1245         if HEADTYPE == obj.Hwindows {
1246                 argv = append(argv, peimporteddlls()...)
1247         }
1248
1249         if Debug['v'] != 0 {
1250                 fmt.Fprintf(Bso, "host link:")
1251                 for _, v := range argv {
1252                         fmt.Fprintf(Bso, " %q", v)
1253                 }
1254                 fmt.Fprintf(Bso, "\n")
1255                 Bso.Flush()
1256         }
1257
1258         if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
1259                 Exitf("running %s failed: %v\n%s", argv[0], err, out)
1260         } else if Debug['v'] != 0 && len(out) > 0 {
1261                 fmt.Fprintf(Bso, "%s", out)
1262                 Bso.Flush()
1263         }
1264
1265         if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin {
1266                 // Skip combining dwarf on arm.
1267                 if !SysArch.InFamily(sys.ARM, sys.ARM64) {
1268                         dsym := filepath.Join(tmpdir, "go.dwarf")
1269                         if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
1270                                 Ctxt.Cursym = nil
1271                                 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
1272                         }
1273                         // Skip combining if `dsymutil` didn't generate a file. See #11994.
1274                         if _, err := os.Stat(dsym); os.IsNotExist(err) {
1275                                 return
1276                         }
1277                         // For os.Rename to work reliably, must be in same directory as outfile.
1278                         combinedOutput := outfile + "~"
1279                         if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil {
1280                                 Ctxt.Cursym = nil
1281                                 Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1282                         }
1283                         os.Remove(outfile)
1284                         if err := os.Rename(combinedOutput, outfile); err != nil {
1285                                 Ctxt.Cursym = nil
1286                                 Exitf("%s: %v", os.Args[0], err)
1287                         }
1288                 }
1289         }
1290 }
1291
1292 // hostlinkArchArgs returns arguments to pass to the external linker
1293 // based on the architecture.
1294 func hostlinkArchArgs() []string {
1295         switch SysArch.Family {
1296         case sys.I386:
1297                 return []string{"-m32"}
1298         case sys.AMD64, sys.PPC64, sys.S390X:
1299                 return []string{"-m64"}
1300         case sys.ARM:
1301                 return []string{"-marm"}
1302         case sys.ARM64:
1303                 // nothing needed
1304         case '0':
1305                 return []string{"-mabi=64"}
1306         }
1307         return nil
1308 }
1309
1310 // ldobj loads an input object. If it is a host object (an object
1311 // compiled by a non-Go compiler) it returns the Hostobj pointer. If
1312 // it is a Go object, it returns nil.
1313 func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, whence int) *Hostobj {
1314         eof := f.Offset() + length
1315
1316         start := f.Offset()
1317         c1 := bgetc(f)
1318         c2 := bgetc(f)
1319         c3 := bgetc(f)
1320         c4 := bgetc(f)
1321         f.Seek(start, 0)
1322
1323         magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
1324         if magic == 0x7f454c46 { // \x7F E L F
1325                 return ldhostobj(ldelf, f, pkg, length, pn, file)
1326         }
1327
1328         if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
1329                 return ldhostobj(ldmacho, f, pkg, length, pn, file)
1330         }
1331
1332         if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
1333                 return ldhostobj(ldpe, f, pkg, length, pn, file)
1334         }
1335
1336         /* check the header */
1337         line, err := f.ReadString('\n')
1338         if err != nil {
1339                 Diag("truncated object file: %s: %v", pn, err)
1340                 return nil
1341         }
1342
1343         if !strings.HasPrefix(line, "go object ") {
1344                 if strings.HasSuffix(pn, ".go") {
1345                         Exitf("%s: uncompiled .go source file", pn)
1346                         return nil
1347                 }
1348
1349                 if line == SysArch.Name {
1350                         // old header format: just $GOOS
1351                         Diag("%s: stale object file", pn)
1352                         return nil
1353                 }
1354
1355                 Diag("%s: not an object file", pn)
1356                 return nil
1357         }
1358
1359         // First, check that the basic goos, goarch, and version match.
1360         t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion())
1361
1362         line = strings.TrimRight(line, "\n")
1363         if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 {
1364                 Diag("%s: object is [%s] expected [%s]", pn, line[10:], t)
1365                 return nil
1366         }
1367
1368         // Second, check that longer lines match each other exactly,
1369         // so that the Go compiler and write additional information
1370         // that must be the same from run to run.
1371         if len(line) >= len(t)+10 {
1372                 if theline == "" {
1373                         theline = line[10:]
1374                 } else if theline != line[10:] {
1375                         Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline)
1376                         return nil
1377                 }
1378         }
1379
1380         /* skip over exports and other info -- ends with \n!\n */
1381         import0 := f.Offset()
1382
1383         c1 = '\n' // the last line ended in \n
1384         c2 = bgetc(f)
1385         c3 = bgetc(f)
1386         for c1 != '\n' || c2 != '!' || c3 != '\n' {
1387                 c1 = c2
1388                 c2 = c3
1389                 c3 = bgetc(f)
1390                 if c3 == -1 {
1391                         Diag("truncated object file: %s", pn)
1392                         return nil
1393                 }
1394         }
1395
1396         import1 := f.Offset()
1397
1398         f.Seek(import0, 0)
1399         ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n
1400         f.Seek(import1, 0)
1401
1402         LoadObjFile(Ctxt, f, pkg, eof-f.Offset(), pn)
1403         return nil
1404 }
1405
1406 func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte {
1407         data := make([]byte, sym.Size)
1408         sect := f.Sections[sym.Section]
1409         if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
1410                 Diag("reading %s from non-data section", sym.Name)
1411         }
1412         n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
1413         if uint64(n) != sym.Size {
1414                 Diag("reading contents of %s: %v", sym.Name, err)
1415         }
1416         return data
1417 }
1418
1419 func readwithpad(r io.Reader, sz int32) ([]byte, error) {
1420         data := make([]byte, Rnd(int64(sz), 4))
1421         _, err := io.ReadFull(r, data)
1422         if err != nil {
1423                 return nil, err
1424         }
1425         data = data[:sz]
1426         return data, nil
1427 }
1428
1429 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
1430         for _, sect := range f.Sections {
1431                 if sect.Type != elf.SHT_NOTE {
1432                         continue
1433                 }
1434                 r := sect.Open()
1435                 for {
1436                         var namesize, descsize, noteType int32
1437                         err := binary.Read(r, f.ByteOrder, &namesize)
1438                         if err != nil {
1439                                 if err == io.EOF {
1440                                         break
1441                                 }
1442                                 return nil, fmt.Errorf("read namesize failed: %v", err)
1443                         }
1444                         err = binary.Read(r, f.ByteOrder, &descsize)
1445                         if err != nil {
1446                                 return nil, fmt.Errorf("read descsize failed: %v", err)
1447                         }
1448                         err = binary.Read(r, f.ByteOrder, &noteType)
1449                         if err != nil {
1450                                 return nil, fmt.Errorf("read type failed: %v", err)
1451                         }
1452                         noteName, err := readwithpad(r, namesize)
1453                         if err != nil {
1454                                 return nil, fmt.Errorf("read name failed: %v", err)
1455                         }
1456                         desc, err := readwithpad(r, descsize)
1457                         if err != nil {
1458                                 return nil, fmt.Errorf("read desc failed: %v", err)
1459                         }
1460                         if string(name) == string(noteName) && typ == noteType {
1461                                 return desc, nil
1462                         }
1463                 }
1464         }
1465         return nil, nil
1466 }
1467
1468 func findshlib(shlib string) string {
1469         for _, libdir := range Ctxt.Libdir {
1470                 libpath := filepath.Join(libdir, shlib)
1471                 if _, err := os.Stat(libpath); err == nil {
1472                         return libpath
1473                 }
1474         }
1475         Diag("cannot find shared library: %s", shlib)
1476         return ""
1477 }
1478
1479 func ldshlibsyms(shlib string) {
1480         libpath := findshlib(shlib)
1481         if libpath == "" {
1482                 return
1483         }
1484         for _, processedlib := range Ctxt.Shlibs {
1485                 if processedlib.Path == libpath {
1486                         return
1487                 }
1488         }
1489         if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil {
1490                 fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath)
1491                 Ctxt.Bso.Flush()
1492         }
1493
1494         f, err := elf.Open(libpath)
1495         if err != nil {
1496                 Diag("cannot open shared library: %s", libpath)
1497                 return
1498         }
1499
1500         hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
1501         if err != nil {
1502                 Diag("cannot read ABI hash from shared library %s: %v", libpath, err)
1503                 return
1504         }
1505
1506         depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
1507         if err != nil {
1508                 Diag("cannot read dep list from shared library %s: %v", libpath, err)
1509                 return
1510         }
1511         deps := strings.Split(string(depsbytes), "\n")
1512
1513         syms, err := f.DynamicSymbols()
1514         if err != nil {
1515                 Diag("cannot read symbols from shared library: %s", libpath)
1516                 return
1517         }
1518         gcdata_locations := make(map[uint64]*LSym)
1519         for _, elfsym := range syms {
1520                 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
1521                         continue
1522                 }
1523                 lsym := Linklookup(Ctxt, elfsym.Name, 0)
1524                 // Because loadlib above loads all .a files before loading any shared
1525                 // libraries, any symbols we find that duplicate symbols already
1526                 // loaded should be ignored (the symbols from the .a files "win").
1527                 if lsym.Type != 0 {
1528                         continue
1529                 }
1530                 lsym.Type = obj.SDYNIMPORT
1531                 lsym.ElfType = elf.ST_TYPE(elfsym.Info)
1532                 lsym.Size = int64(elfsym.Size)
1533                 if elfsym.Section != elf.SHN_UNDEF {
1534                         // Set .File for the library that actually defines the symbol.
1535                         lsym.File = libpath
1536                         // The decodetype_* functions in decodetype.go need access to
1537                         // the type data.
1538                         if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
1539                                 lsym.P = readelfsymboldata(f, &elfsym)
1540                                 gcdata_locations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
1541                         }
1542                 }
1543         }
1544         gcdata_addresses := make(map[*LSym]uint64)
1545         if SysArch.Family == sys.ARM64 {
1546                 for _, sect := range f.Sections {
1547                         if sect.Type == elf.SHT_RELA {
1548                                 var rela elf.Rela64
1549                                 rdr := sect.Open()
1550                                 for {
1551                                         err := binary.Read(rdr, f.ByteOrder, &rela)
1552                                         if err == io.EOF {
1553                                                 break
1554                                         } else if err != nil {
1555                                                 Diag("reading relocation failed %v", err)
1556                                                 return
1557                                         }
1558                                         t := elf.R_AARCH64(rela.Info & 0xffff)
1559                                         if t != elf.R_AARCH64_RELATIVE {
1560                                                 continue
1561                                         }
1562                                         if lsym, ok := gcdata_locations[rela.Off]; ok {
1563                                                 gcdata_addresses[lsym] = uint64(rela.Addend)
1564                                         }
1565                                 }
1566                         }
1567                 }
1568         }
1569
1570         // We might have overwritten some functions above (this tends to happen for the
1571         // autogenerated type equality/hashing functions) and we don't want to generated
1572         // pcln table entries for these any more so remove them from Textp.
1573         textp := make([]*LSym, 0, len(Ctxt.Textp))
1574         for _, s := range Ctxt.Textp {
1575                 if s.Type != obj.SDYNIMPORT {
1576                         textp = append(textp, s)
1577                 }
1578         }
1579         Ctxt.Textp = textp
1580
1581         Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdata_addresses: gcdata_addresses})
1582 }
1583
1584 func mywhatsys() {
1585         goroot = obj.Getgoroot()
1586         goos = obj.Getgoos()
1587         goarch = obj.Getgoarch()
1588 }
1589
1590 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
1591 /*
1592  * Convert raw string to the prefix that will be used in the symbol table.
1593  * Invalid bytes turn into %xx.  Right now the only bytes that need
1594  * escaping are %, ., and ", but we escape all control characters too.
1595  *
1596  * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
1597  * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
1598  */
1599 func pathtoprefix(s string) string {
1600         slash := strings.LastIndex(s, "/")
1601         for i := 0; i < len(s); i++ {
1602                 c := s[i]
1603                 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
1604                         var buf bytes.Buffer
1605                         for i := 0; i < len(s); i++ {
1606                                 c := s[i]
1607                                 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
1608                                         fmt.Fprintf(&buf, "%%%02x", c)
1609                                         continue
1610                                 }
1611                                 buf.WriteByte(c)
1612                         }
1613                         return buf.String()
1614                 }
1615         }
1616         return s
1617 }
1618
1619 func addsection(seg *Segment, name string, rwx int) *Section {
1620         var l **Section
1621
1622         for l = &seg.Sect; *l != nil; l = &(*l).Next {
1623         }
1624         sect := new(Section)
1625         sect.Rwx = uint8(rwx)
1626         sect.Name = name
1627         sect.Seg = seg
1628         sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
1629         *l = sect
1630         return sect
1631 }
1632
1633 func Le16(b []byte) uint16 {
1634         return uint16(b[0]) | uint16(b[1])<<8
1635 }
1636
1637 func Le32(b []byte) uint32 {
1638         return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
1639 }
1640
1641 func Le64(b []byte) uint64 {
1642         return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32
1643 }
1644
1645 func Be16(b []byte) uint16 {
1646         return uint16(b[0])<<8 | uint16(b[1])
1647 }
1648
1649 func Be32(b []byte) uint32 {
1650         return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
1651 }
1652
1653 type Chain struct {
1654         sym   *LSym
1655         up    *Chain
1656         limit int // limit on entry to sym
1657 }
1658
1659 var morestack *LSym
1660
1661 // TODO: Record enough information in new object files to
1662 // allow stack checks here.
1663
1664 func haslinkregister() bool {
1665         return Ctxt.FixedFrameSize() != 0
1666 }
1667
1668 func callsize() int {
1669         if haslinkregister() {
1670                 return 0
1671         }
1672         return SysArch.RegSize
1673 }
1674
1675 func dostkcheck() {
1676         var ch Chain
1677
1678         morestack = Linklookup(Ctxt, "runtime.morestack", 0)
1679
1680         // Every splitting function ensures that there are at least StackLimit
1681         // bytes available below SP when the splitting prologue finishes.
1682         // If the splitting function calls F, then F begins execution with
1683         // at least StackLimit - callsize() bytes available.
1684         // Check that every function behaves correctly with this amount
1685         // of stack, following direct calls in order to piece together chains
1686         // of non-splitting functions.
1687         ch.up = nil
1688
1689         ch.limit = obj.StackLimit - callsize()
1690
1691         // Check every function, but do the nosplit functions in a first pass,
1692         // to make the printed failure chains as short as possible.
1693         for _, s := range Ctxt.Textp {
1694                 // runtime.racesymbolizethunk is called from gcc-compiled C
1695                 // code running on the operating system thread stack.
1696                 // It uses more than the usual amount of stack but that's okay.
1697                 if s.Name == "runtime.racesymbolizethunk" {
1698                         continue
1699                 }
1700
1701                 if s.Attr.NoSplit() {
1702                         Ctxt.Cursym = s
1703                         ch.sym = s
1704                         stkcheck(&ch, 0)
1705                 }
1706         }
1707
1708         for _, s := range Ctxt.Textp {
1709                 if !s.Attr.NoSplit() {
1710                         Ctxt.Cursym = s
1711                         ch.sym = s
1712                         stkcheck(&ch, 0)
1713                 }
1714         }
1715 }
1716
1717 func stkcheck(up *Chain, depth int) int {
1718         limit := up.limit
1719         s := up.sym
1720
1721         // Don't duplicate work: only need to consider each
1722         // function at top of safe zone once.
1723         top := limit == obj.StackLimit-callsize()
1724         if top {
1725                 if s.Attr.StackCheck() {
1726                         return 0
1727                 }
1728                 s.Attr |= AttrStackCheck
1729         }
1730
1731         if depth > 100 {
1732                 Diag("nosplit stack check too deep")
1733                 stkbroke(up, 0)
1734                 return -1
1735         }
1736
1737         if s.Attr.External() || s.FuncInfo == nil {
1738                 // external function.
1739                 // should never be called directly.
1740                 // only diagnose the direct caller.
1741                 // TODO(mwhudson): actually think about this.
1742                 if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() &&
1743                         Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared {
1744                         Diag("call to external function %s", s.Name)
1745                 }
1746                 return -1
1747         }
1748
1749         if limit < 0 {
1750                 stkbroke(up, limit)
1751                 return -1
1752         }
1753
1754         // morestack looks like it calls functions,
1755         // but it switches the stack pointer first.
1756         if s == morestack {
1757                 return 0
1758         }
1759
1760         var ch Chain
1761         ch.up = up
1762
1763         if !s.Attr.NoSplit() {
1764                 // Ensure we have enough stack to call morestack.
1765                 ch.limit = limit - callsize()
1766                 ch.sym = morestack
1767                 if stkcheck(&ch, depth+1) < 0 {
1768                         return -1
1769                 }
1770                 if !top {
1771                         return 0
1772                 }
1773                 // Raise limit to allow frame.
1774                 locals := int32(0)
1775                 if s.FuncInfo != nil {
1776                         locals = s.FuncInfo.Locals
1777                 }
1778                 limit = int(obj.StackLimit+locals) + int(Ctxt.FixedFrameSize())
1779         }
1780
1781         // Walk through sp adjustments in function, consuming relocs.
1782         ri := 0
1783
1784         endr := len(s.R)
1785         var ch1 Chain
1786         var pcsp Pciter
1787         var r *Reloc
1788         for pciterinit(Ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
1789                 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
1790
1791                 // Check stack size in effect for this span.
1792                 if int32(limit)-pcsp.value < 0 {
1793                         stkbroke(up, int(int32(limit)-pcsp.value))
1794                         return -1
1795                 }
1796
1797                 // Process calls in this span.
1798                 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ {
1799                         r = &s.R[ri]
1800                         switch r.Type {
1801                         // Direct call.
1802                         case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER, obj.R_CALLMIPS:
1803                                 ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
1804                                 ch.sym = r.Sym
1805                                 if stkcheck(&ch, depth+1) < 0 {
1806                                         return -1
1807                                 }
1808
1809                         // Indirect call. Assume it is a call to a splitting function,
1810                         // so we have to make sure it can call morestack.
1811                         // Arrange the data structures to report both calls, so that
1812                         // if there is an error, stkprint shows all the steps involved.
1813                         case obj.R_CALLIND:
1814                                 ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
1815
1816                                 ch.sym = nil
1817                                 ch1.limit = ch.limit - callsize() // for morestack in called prologue
1818                                 ch1.up = &ch
1819                                 ch1.sym = morestack
1820                                 if stkcheck(&ch1, depth+2) < 0 {
1821                                         return -1
1822                                 }
1823                         }
1824                 }
1825         }
1826
1827         return 0
1828 }
1829
1830 func stkbroke(ch *Chain, limit int) {
1831         Diag("nosplit stack overflow")
1832         stkprint(ch, limit)
1833 }
1834
1835 func stkprint(ch *Chain, limit int) {
1836         var name string
1837
1838         if ch.sym != nil {
1839                 name = ch.sym.Name
1840                 if ch.sym.Attr.NoSplit() {
1841                         name += " (nosplit)"
1842                 }
1843         } else {
1844                 name = "function pointer"
1845         }
1846
1847         if ch.up == nil {
1848                 // top of chain.  ch->sym != nil.
1849                 if ch.sym.Attr.NoSplit() {
1850                         fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
1851                 } else {
1852                         fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
1853                 }
1854         } else {
1855                 stkprint(ch.up, ch.limit+callsize())
1856                 if !haslinkregister() {
1857                         fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
1858                 }
1859         }
1860
1861         if ch.limit != limit {
1862                 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
1863         }
1864 }
1865
1866 func Cflush() {
1867         if err := coutbuf.w.Flush(); err != nil {
1868                 Exitf("flushing %s: %v", coutbuf.f.Name(), err)
1869         }
1870 }
1871
1872 func Cpos() int64 {
1873         return coutbuf.off
1874 }
1875
1876 func Cseek(p int64) {
1877         if p == coutbuf.off {
1878                 return
1879         }
1880         Cflush()
1881         if _, err := coutbuf.f.Seek(p, 0); err != nil {
1882                 Exitf("seeking in output [0, 1]: %v", err)
1883         }
1884         coutbuf.off = p
1885 }
1886
1887 func Cwritestring(s string) {
1888         coutbuf.WriteString(s)
1889 }
1890
1891 func Cwrite(p []byte) {
1892         coutbuf.Write(p)
1893 }
1894
1895 func Cput(c uint8) {
1896         coutbuf.w.WriteByte(c)
1897         coutbuf.off++
1898 }
1899
1900 func usage() {
1901         fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
1902         obj.Flagprint(2)
1903         Exit(2)
1904 }
1905
1906 func setheadtype(s string) {
1907         h := headtype(s)
1908         if h < 0 {
1909                 Exitf("unknown header type -H %s", s)
1910         }
1911
1912         headstring = s
1913         HEADTYPE = int32(headtype(s))
1914 }
1915
1916 func setinterp(s string) {
1917         Debug['I'] = 1 // denote cmdline interpreter override
1918         interpreter = s
1919 }
1920
1921 func doversion() {
1922         Exitf("version %s", obj.Getgoversion())
1923 }
1924
1925 func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
1926         // These symbols won't show up in the first loop below because we
1927         // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
1928         s := Linklookup(Ctxt, "runtime.text", 0)
1929         if s.Type == obj.STEXT {
1930                 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
1931         }
1932         s = Linklookup(Ctxt, "runtime.etext", 0)
1933         if s.Type == obj.STEXT {
1934                 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
1935         }
1936
1937         for _, s := range Ctxt.Allsym {
1938                 if s.Attr.Hidden() {
1939                         continue
1940                 }
1941                 if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
1942                         continue
1943                 }
1944                 switch s.Type & obj.SMASK {
1945                 case obj.SCONST,
1946                         obj.SRODATA,
1947                         obj.SSYMTAB,
1948                         obj.SPCLNTAB,
1949                         obj.SINITARR,
1950                         obj.SDATA,
1951                         obj.SNOPTRDATA,
1952                         obj.SELFROSECT,
1953                         obj.SMACHOGOT,
1954                         obj.STYPE,
1955                         obj.SSTRING,
1956                         obj.SGOSTRING,
1957                         obj.SGOSTRINGHDR,
1958                         obj.SGOFUNC,
1959                         obj.SGCBITS,
1960                         obj.STYPERELRO,
1961                         obj.SSTRINGRELRO,
1962                         obj.SGOSTRINGRELRO,
1963                         obj.SGOSTRINGHDRRELRO,
1964                         obj.SGOFUNCRELRO,
1965                         obj.SGCBITSRELRO,
1966                         obj.SRODATARELRO,
1967                         obj.STYPELINK,
1968                         obj.SITABLINK,
1969                         obj.SWINDOWS:
1970                         if !s.Attr.Reachable() {
1971                                 continue
1972                         }
1973                         put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype)
1974
1975                 case obj.SBSS, obj.SNOPTRBSS:
1976                         if !s.Attr.Reachable() {
1977                                 continue
1978                         }
1979                         if len(s.P) > 0 {
1980                                 Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, len(s.P), s.Type, s.Attr.Special())
1981                         }
1982                         put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
1983
1984                 case obj.SFILE:
1985                         put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil)
1986
1987                 case obj.SHOSTOBJ:
1988                         if HEADTYPE == obj.Hwindows || Iself {
1989                                 put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil)
1990                         }
1991
1992                 case obj.SDYNIMPORT:
1993                         if !s.Attr.Reachable() {
1994                                 continue
1995                         }
1996                         put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
1997
1998                 case obj.STLSBSS:
1999                         if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd {
2000                                 put(s, s.Name, 't', Symaddr(s), s.Size, int(s.Version), s.Gotype)
2001                         }
2002                 }
2003         }
2004
2005         var off int32
2006         for _, s := range Ctxt.Textp {
2007                 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
2008
2009                 locals := int32(0)
2010                 if s.FuncInfo != nil {
2011                         locals = s.FuncInfo.Locals
2012                 }
2013                 // NOTE(ality): acid can't produce a stack trace without .frame symbols
2014                 put(nil, ".frame", 'm', int64(locals)+int64(SysArch.PtrSize), 0, 0, nil)
2015
2016                 if s.FuncInfo == nil {
2017                         continue
2018                 }
2019                 for _, a := range s.FuncInfo.Autom {
2020                         // Emit a or p according to actual offset, even if label is wrong.
2021                         // This avoids negative offsets, which cannot be encoded.
2022                         if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM {
2023                                 continue
2024                         }
2025
2026                         // compute offset relative to FP
2027                         if a.Name == obj.A_PARAM {
2028                                 off = a.Aoffset
2029                         } else {
2030                                 off = a.Aoffset - int32(SysArch.PtrSize)
2031                         }
2032
2033                         // FP
2034                         if off >= 0 {
2035                                 put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype)
2036                                 continue
2037                         }
2038
2039                         // SP
2040                         if off <= int32(-SysArch.PtrSize) {
2041                                 put(nil, a.Asym.Name, 'a', -(int64(off) + int64(SysArch.PtrSize)), 0, 0, a.Gotype)
2042                                 continue
2043                         }
2044                 }
2045         }
2046
2047         // Otherwise, off is addressing the saved program counter.
2048         // Something underhanded is going on. Say nothing.
2049         if Debug['v'] != 0 || Debug['n'] != 0 {
2050                 fmt.Fprintf(Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize))
2051         }
2052         Bso.Flush()
2053 }
2054
2055 func Symaddr(s *LSym) int64 {
2056         if !s.Attr.Reachable() {
2057                 Diag("unreachable symbol in symaddr - %s", s.Name)
2058         }
2059         return s.Value
2060 }
2061
2062 func xdefine(p string, t int, v int64) {
2063         s := Linklookup(Ctxt, p, 0)
2064         s.Type = int16(t)
2065         s.Value = v
2066         s.Attr |= AttrReachable
2067         s.Attr |= AttrSpecial
2068         s.Attr |= AttrLocal
2069 }
2070
2071 func datoff(addr int64) int64 {
2072         if uint64(addr) >= Segdata.Vaddr {
2073                 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
2074         }
2075         if uint64(addr) >= Segtext.Vaddr {
2076                 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
2077         }
2078         Diag("datoff %#x", addr)
2079         return 0
2080 }
2081
2082 func Entryvalue() int64 {
2083         a := INITENTRY
2084         if a[0] >= '0' && a[0] <= '9' {
2085                 return atolwhex(a)
2086         }
2087         s := Linklookup(Ctxt, a, 0)
2088         if s.Type == 0 {
2089                 return INITTEXT
2090         }
2091         if s.Type != obj.STEXT {
2092                 Diag("entry not text: %s", s.Name)
2093         }
2094         return s.Value
2095 }
2096
2097 func undefsym(s *LSym) {
2098         var r *Reloc
2099
2100         Ctxt.Cursym = s
2101         for i := 0; i < len(s.R); i++ {
2102                 r = &s.R[i]
2103                 if r.Sym == nil { // happens for some external ARM relocs
2104                         continue
2105                 }
2106                 if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF {
2107                         Diag("undefined: %s", r.Sym.Name)
2108                 }
2109                 if !r.Sym.Attr.Reachable() {
2110                         Diag("use of unreachable symbol: %s", r.Sym.Name)
2111                 }
2112         }
2113 }
2114
2115 func undef() {
2116         for _, s := range Ctxt.Textp {
2117                 undefsym(s)
2118         }
2119         for _, s := range datap {
2120                 undefsym(s)
2121         }
2122         if nerrors > 0 {
2123                 errorexit()
2124         }
2125 }
2126
2127 func callgraph() {
2128         if Debug['c'] == 0 {
2129                 return
2130         }
2131
2132         var i int
2133         var r *Reloc
2134         for _, s := range Ctxt.Textp {
2135                 for i = 0; i < len(s.R); i++ {
2136                         r = &s.R[i]
2137                         if r.Sym == nil {
2138                                 continue
2139                         }
2140                         if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM || r.Type == obj.R_CALLPOWER || r.Type == obj.R_CALLMIPS) && r.Sym.Type == obj.STEXT {
2141                                 fmt.Fprintf(Bso, "%s calls %s\n", s.Name, r.Sym.Name)
2142                         }
2143                 }
2144         }
2145 }
2146
2147 func Diag(format string, args ...interface{}) {
2148         tn := ""
2149         sep := ""
2150         if Ctxt.Cursym != nil {
2151                 tn = Ctxt.Cursym.Name
2152                 sep = ": "
2153         }
2154         fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...))
2155         nerrors++
2156         if Debug['h'] != 0 {
2157                 panic("error")
2158         }
2159         if nerrors > 20 {
2160                 Exitf("too many errors")
2161         }
2162 }
2163
2164 func Rnd(v int64, r int64) int64 {
2165         if r <= 0 {
2166                 return v
2167         }
2168         v += r - 1
2169         c := v % r
2170         if c < 0 {
2171                 c += r
2172         }
2173         v -= c
2174         return v
2175 }
2176
2177 func bgetc(r *bio.Reader) int {
2178         c, err := r.ReadByte()
2179         if err != nil {
2180                 if err != io.EOF {
2181                         log.Fatalf("reading input: %v", err)
2182                 }
2183                 return -1
2184         }
2185         return int(c)
2186 }