1
2
3
4
5 package ld
6
7 import (
8 "cmd/internal/notsha256"
9 "cmd/internal/objabi"
10 "cmd/internal/sys"
11 "cmd/link/internal/loader"
12 "cmd/link/internal/sym"
13 "debug/elf"
14 "encoding/binary"
15 "encoding/hex"
16 "fmt"
17 "internal/buildcfg"
18 "os"
19 "path/filepath"
20 "runtime"
21 "sort"
22 "strings"
23 )
24
25
63
64
67
68
76 type elfNote struct {
77 nNamesz uint32
78 nDescsz uint32
79 nType uint32
80 }
81
82
83
84
85
86
89 const (
90 ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
91 )
92
93
96
97
98
99
100
101
102
103
106 type ElfEhdr elf.Header64
107
108
111 type ElfShdr struct {
112 elf.Section64
113 shnum elf.SectionIndex
114 }
115
116
119 type ElfPhdr elf.ProgHeader
120
121
122
123
124
125
128
129
130
131
132
133
134
135
138 const (
139 ELF64HDRSIZE = 64
140 ELF64PHDRSIZE = 56
141 ELF64SHDRSIZE = 64
142 ELF64RELSIZE = 16
143 ELF64RELASIZE = 24
144 ELF64SYMSIZE = 24
145 ELF32HDRSIZE = 52
146 ELF32PHDRSIZE = 32
147 ELF32SHDRSIZE = 40
148 ELF32SYMSIZE = 16
149 ELF32RELSIZE = 8
150 )
151
152
157
158 var elfstrdat, elfshstrdat []byte
159
160
166 const (
167 ELFRESERVE = 4096
168 )
169
170
175 const (
176 NSECT = 400
177 )
178
179 var (
180 Nelfsym = 1
181
182 elf64 bool
183
184
185 elfRelType string
186
187 ehdr ElfEhdr
188 phdr [NSECT]*ElfPhdr
189 shdr [NSECT]*ElfShdr
190
191 interp string
192 )
193
194
195
196
197 type ELFArch struct {
198
199
200 Androiddynld string
201 Linuxdynld string
202 LinuxdynldMusl string
203 Freebsddynld string
204 Netbsddynld string
205 Openbsddynld string
206 Dragonflydynld string
207 Solarisdynld string
208
209 Reloc1 func(*Link, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int, int64) bool
210 RelocSize uint32
211 SetupPLT func(ctxt *Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
212
213
214
215
216 DynamicReadOnly bool
217 }
218
219 type Elfstring struct {
220 s string
221 off int
222 }
223
224 var elfstr [100]Elfstring
225
226 var nelfstr int
227
228 var buildinfo []byte
229
230
234 func Elfinit(ctxt *Link) {
235 ctxt.IsELF = true
236
237 if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) {
238 elfRelType = ".rela"
239 } else {
240 elfRelType = ".rel"
241 }
242
243 switch ctxt.Arch.Family {
244
245 case sys.PPC64, sys.S390X:
246 if ctxt.Arch.ByteOrder == binary.BigEndian && ctxt.HeadType != objabi.Hopenbsd {
247 ehdr.Flags = 1
248 } else {
249 ehdr.Flags = 2
250 }
251 fallthrough
252 case sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.RISCV64:
253 if ctxt.Arch.Family == sys.MIPS64 {
254 ehdr.Flags = 0x20000004
255 }
256 if ctxt.Arch.Family == sys.Loong64 {
257 ehdr.Flags = 0x43
258 }
259 if ctxt.Arch.Family == sys.RISCV64 {
260 ehdr.Flags = 0x4
261 }
262 elf64 = true
263
264 ehdr.Phoff = ELF64HDRSIZE
265 ehdr.Shoff = ELF64HDRSIZE
266 ehdr.Ehsize = ELF64HDRSIZE
267 ehdr.Phentsize = ELF64PHDRSIZE
268 ehdr.Shentsize = ELF64SHDRSIZE
269
270
271 case sys.ARM, sys.MIPS:
272 if ctxt.Arch.Family == sys.ARM {
273
274 if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd {
275
276
277
278
279
280
281
282
283 ehdr.Flags = 0x5000002
284 }
285 } else if ctxt.Arch.Family == sys.MIPS {
286 ehdr.Flags = 0x50001004
287 }
288 fallthrough
289 default:
290 ehdr.Phoff = ELF32HDRSIZE
291
292 ehdr.Shoff = ELF32HDRSIZE
293 ehdr.Ehsize = ELF32HDRSIZE
294 ehdr.Phentsize = ELF32PHDRSIZE
295 ehdr.Shentsize = ELF32SHDRSIZE
296 }
297 }
298
299
300
301
302
303
304 func fixElfPhdr(e *ElfPhdr) {
305 frag := int(e.Vaddr & (e.Align - 1))
306
307 e.Off -= uint64(frag)
308 e.Vaddr -= uint64(frag)
309 e.Paddr -= uint64(frag)
310 e.Filesz += uint64(frag)
311 e.Memsz += uint64(frag)
312 }
313
314 func elf64phdr(out *OutBuf, e *ElfPhdr) {
315 if e.Type == elf.PT_LOAD {
316 fixElfPhdr(e)
317 }
318
319 out.Write32(uint32(e.Type))
320 out.Write32(uint32(e.Flags))
321 out.Write64(e.Off)
322 out.Write64(e.Vaddr)
323 out.Write64(e.Paddr)
324 out.Write64(e.Filesz)
325 out.Write64(e.Memsz)
326 out.Write64(e.Align)
327 }
328
329 func elf32phdr(out *OutBuf, e *ElfPhdr) {
330 if e.Type == elf.PT_LOAD {
331 fixElfPhdr(e)
332 }
333
334 out.Write32(uint32(e.Type))
335 out.Write32(uint32(e.Off))
336 out.Write32(uint32(e.Vaddr))
337 out.Write32(uint32(e.Paddr))
338 out.Write32(uint32(e.Filesz))
339 out.Write32(uint32(e.Memsz))
340 out.Write32(uint32(e.Flags))
341 out.Write32(uint32(e.Align))
342 }
343
344 func elf64shdr(out *OutBuf, e *ElfShdr) {
345 out.Write32(e.Name)
346 out.Write32(uint32(e.Type))
347 out.Write64(uint64(e.Flags))
348 out.Write64(e.Addr)
349 out.Write64(e.Off)
350 out.Write64(e.Size)
351 out.Write32(e.Link)
352 out.Write32(e.Info)
353 out.Write64(e.Addralign)
354 out.Write64(e.Entsize)
355 }
356
357 func elf32shdr(out *OutBuf, e *ElfShdr) {
358 out.Write32(e.Name)
359 out.Write32(uint32(e.Type))
360 out.Write32(uint32(e.Flags))
361 out.Write32(uint32(e.Addr))
362 out.Write32(uint32(e.Off))
363 out.Write32(uint32(e.Size))
364 out.Write32(e.Link)
365 out.Write32(e.Info)
366 out.Write32(uint32(e.Addralign))
367 out.Write32(uint32(e.Entsize))
368 }
369
370 func elfwriteshdrs(out *OutBuf) uint32 {
371 if elf64 {
372 for i := 0; i < int(ehdr.Shnum); i++ {
373 elf64shdr(out, shdr[i])
374 }
375 return uint32(ehdr.Shnum) * ELF64SHDRSIZE
376 }
377
378 for i := 0; i < int(ehdr.Shnum); i++ {
379 elf32shdr(out, shdr[i])
380 }
381 return uint32(ehdr.Shnum) * ELF32SHDRSIZE
382 }
383
384 func elfsetstring(ctxt *Link, s loader.Sym, str string, off int) {
385 if nelfstr >= len(elfstr) {
386 ctxt.Errorf(s, "too many elf strings")
387 errorexit()
388 }
389
390 elfstr[nelfstr].s = str
391 elfstr[nelfstr].off = off
392 nelfstr++
393 }
394
395 func elfwritephdrs(out *OutBuf) uint32 {
396 if elf64 {
397 for i := 0; i < int(ehdr.Phnum); i++ {
398 elf64phdr(out, phdr[i])
399 }
400 return uint32(ehdr.Phnum) * ELF64PHDRSIZE
401 }
402
403 for i := 0; i < int(ehdr.Phnum); i++ {
404 elf32phdr(out, phdr[i])
405 }
406 return uint32(ehdr.Phnum) * ELF32PHDRSIZE
407 }
408
409 func newElfPhdr() *ElfPhdr {
410 e := new(ElfPhdr)
411 if ehdr.Phnum >= NSECT {
412 Errorf(nil, "too many phdrs")
413 } else {
414 phdr[ehdr.Phnum] = e
415 ehdr.Phnum++
416 }
417 if elf64 {
418 ehdr.Shoff += ELF64PHDRSIZE
419 } else {
420 ehdr.Shoff += ELF32PHDRSIZE
421 }
422 return e
423 }
424
425 func newElfShdr(name int64) *ElfShdr {
426 e := new(ElfShdr)
427 e.Name = uint32(name)
428 e.shnum = elf.SectionIndex(ehdr.Shnum)
429 if ehdr.Shnum >= NSECT {
430 Errorf(nil, "too many shdrs")
431 } else {
432 shdr[ehdr.Shnum] = e
433 ehdr.Shnum++
434 }
435
436 return e
437 }
438
439 func getElfEhdr() *ElfEhdr {
440 return &ehdr
441 }
442
443 func elf64writehdr(out *OutBuf) uint32 {
444 out.Write(ehdr.Ident[:])
445 out.Write16(uint16(ehdr.Type))
446 out.Write16(uint16(ehdr.Machine))
447 out.Write32(uint32(ehdr.Version))
448 out.Write64(ehdr.Entry)
449 out.Write64(ehdr.Phoff)
450 out.Write64(ehdr.Shoff)
451 out.Write32(ehdr.Flags)
452 out.Write16(ehdr.Ehsize)
453 out.Write16(ehdr.Phentsize)
454 out.Write16(ehdr.Phnum)
455 out.Write16(ehdr.Shentsize)
456 out.Write16(ehdr.Shnum)
457 out.Write16(ehdr.Shstrndx)
458 return ELF64HDRSIZE
459 }
460
461 func elf32writehdr(out *OutBuf) uint32 {
462 out.Write(ehdr.Ident[:])
463 out.Write16(uint16(ehdr.Type))
464 out.Write16(uint16(ehdr.Machine))
465 out.Write32(uint32(ehdr.Version))
466 out.Write32(uint32(ehdr.Entry))
467 out.Write32(uint32(ehdr.Phoff))
468 out.Write32(uint32(ehdr.Shoff))
469 out.Write32(ehdr.Flags)
470 out.Write16(ehdr.Ehsize)
471 out.Write16(ehdr.Phentsize)
472 out.Write16(ehdr.Phnum)
473 out.Write16(ehdr.Shentsize)
474 out.Write16(ehdr.Shnum)
475 out.Write16(ehdr.Shstrndx)
476 return ELF32HDRSIZE
477 }
478
479 func elfwritehdr(out *OutBuf) uint32 {
480 if elf64 {
481 return elf64writehdr(out)
482 }
483 return elf32writehdr(out)
484 }
485
486
487 func elfhash(name string) uint32 {
488 var h uint32
489 for i := 0; i < len(name); i++ {
490 h = (h << 4) + uint32(name[i])
491 if g := h & 0xf0000000; g != 0 {
492 h ^= g >> 24
493 }
494 h &= 0x0fffffff
495 }
496 return h
497 }
498
499 func elfWriteDynEntSym(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym) {
500 Elfwritedynentsymplus(ctxt, s, tag, t, 0)
501 }
502
503 func Elfwritedynent(arch *sys.Arch, s *loader.SymbolBuilder, tag elf.DynTag, val uint64) {
504 if elf64 {
505 s.AddUint64(arch, uint64(tag))
506 s.AddUint64(arch, val)
507 } else {
508 s.AddUint32(arch, uint32(tag))
509 s.AddUint32(arch, uint32(val))
510 }
511 }
512
513 func Elfwritedynentsymplus(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym, add int64) {
514 if elf64 {
515 s.AddUint64(ctxt.Arch, uint64(tag))
516 } else {
517 s.AddUint32(ctxt.Arch, uint32(tag))
518 }
519 s.AddAddrPlus(ctxt.Arch, t, add)
520 }
521
522 func elfwritedynentsymsize(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym) {
523 if elf64 {
524 s.AddUint64(ctxt.Arch, uint64(tag))
525 } else {
526 s.AddUint32(ctxt.Arch, uint32(tag))
527 }
528 s.AddSize(ctxt.Arch, t)
529 }
530
531 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
532 interp = p
533 n := len(interp) + 1
534 sh.Addr = startva + resoff - uint64(n)
535 sh.Off = resoff - uint64(n)
536 sh.Size = uint64(n)
537
538 return n
539 }
540
541 func elfwriteinterp(out *OutBuf) int {
542 sh := elfshname(".interp")
543 out.SeekSet(int64(sh.Off))
544 out.WriteString(interp)
545 out.Write8(0)
546 return int(sh.Size)
547 }
548
549
550 const (
551
552 MIPS_FPABI_NONE = 0
553
554 MIPS_FPABI_ANY = 1
555
556 MIPS_FPABI_SINGLE = 2
557
558 MIPS_FPABI_SOFT = 3
559
560
561 MIPS_FPABI_HIST = 4
562
563 MIPS_FPABI_FPXX = 5
564
565 MIPS_FPABI_FP64 = 6
566
567 MIPS_FPABI_FP64A = 7
568 )
569
570 func elfMipsAbiFlags(sh *ElfShdr, startva uint64, resoff uint64) int {
571 n := 24
572 sh.Addr = startva + resoff - uint64(n)
573 sh.Off = resoff - uint64(n)
574 sh.Size = uint64(n)
575 sh.Type = uint32(elf.SHT_MIPS_ABIFLAGS)
576 sh.Flags = uint64(elf.SHF_ALLOC)
577
578 return n
579 }
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607 func elfWriteMipsAbiFlags(ctxt *Link) int {
608 sh := elfshname(".MIPS.abiflags")
609 ctxt.Out.SeekSet(int64(sh.Off))
610 ctxt.Out.Write16(0)
611 ctxt.Out.Write8(32)
612 ctxt.Out.Write8(1)
613 ctxt.Out.Write8(1)
614 ctxt.Out.Write8(1)
615 ctxt.Out.Write8(0)
616 if buildcfg.GOMIPS == "softfloat" {
617 ctxt.Out.Write8(MIPS_FPABI_SOFT)
618 } else {
619
620
621
622
623
624
625
626 ctxt.Out.Write8(MIPS_FPABI_ANY)
627 }
628 ctxt.Out.Write32(0)
629 ctxt.Out.Write32(0)
630 ctxt.Out.Write32(0)
631 ctxt.Out.Write32(0)
632 return int(sh.Size)
633 }
634
635 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sizes ...int) int {
636 n := resoff % 4
637
638
639 for _, sz := range sizes {
640 n += 3*4 + uint64(sz)
641 }
642
643 sh.Type = uint32(elf.SHT_NOTE)
644 sh.Flags = uint64(elf.SHF_ALLOC)
645 sh.Addralign = 4
646 sh.Addr = startva + resoff - n
647 sh.Off = resoff - n
648 sh.Size = n - resoff%4
649
650 return int(n)
651 }
652
653 func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
654 sh := elfshname(str)
655
656
657 out.SeekSet(int64(sh.Off))
658
659 out.Write32(namesz)
660 out.Write32(descsz)
661 out.Write32(tag)
662
663 return sh
664 }
665
666
667 const (
668 ELF_NOTE_NETBSD_NAMESZ = 7
669 ELF_NOTE_NETBSD_DESCSZ = 4
670 ELF_NOTE_NETBSD_TAG = 1
671 ELF_NOTE_NETBSD_VERSION = 700000000
672 )
673
674 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
675
676 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
677 n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
678 return elfnote(sh, startva, resoff, n)
679 }
680
681 func elfwritenetbsdsig(out *OutBuf) int {
682
683 sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
684
685 if sh == nil {
686 return 0
687 }
688
689
690 out.Write(ELF_NOTE_NETBSD_NAME)
691 out.Write8(0)
692 out.Write32(ELF_NOTE_NETBSD_VERSION)
693
694 return int(sh.Size)
695 }
696
697
698
699
700
701 func elfnetbsdpax(sh *ElfShdr, startva uint64, resoff uint64) int {
702 n := int(Rnd(4, 4) + Rnd(4, 4))
703 return elfnote(sh, startva, resoff, n)
704 }
705
706 func elfwritenetbsdpax(out *OutBuf) int {
707 sh := elfwritenotehdr(out, ".note.netbsd.pax", 4 , 4 , 0x03 )
708 if sh == nil {
709 return 0
710 }
711 out.Write([]byte("PaX\x00"))
712 out.Write32(0x20)
713 return int(sh.Size)
714 }
715
716
717 const (
718 ELF_NOTE_OPENBSD_NAMESZ = 8
719 ELF_NOTE_OPENBSD_DESCSZ = 4
720 ELF_NOTE_OPENBSD_TAG = 1
721 ELF_NOTE_OPENBSD_VERSION = 0
722 )
723
724 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
725
726 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
727 n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
728 return elfnote(sh, startva, resoff, n)
729 }
730
731 func elfwriteopenbsdsig(out *OutBuf) int {
732
733 sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
734
735 if sh == nil {
736 return 0
737 }
738
739
740 out.Write(ELF_NOTE_OPENBSD_NAME)
741
742 out.Write32(ELF_NOTE_OPENBSD_VERSION)
743
744 return int(sh.Size)
745 }
746
747
748 const (
749 ELF_NOTE_FREEBSD_NAMESZ = 8
750 ELF_NOTE_FREEBSD_DESCSZ = 4
751 ELF_NOTE_FREEBSD_ABI_TAG = 1
752 ELF_NOTE_FREEBSD_NOINIT_TAG = 2
753 ELF_NOTE_FREEBSD_FEATURE_CTL_TAG = 4
754 ELF_NOTE_FREEBSD_VERSION = 1203000
755 ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE = 0x1
756 )
757
758 const ELF_NOTE_FREEBSD_NAME = "FreeBSD\x00"
759
760 func elffreebsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
761 n := ELF_NOTE_FREEBSD_NAMESZ + ELF_NOTE_FREEBSD_DESCSZ
762
763 return elfnote(sh, startva, resoff, n, n, n)
764 }
765
766
767
768
769
770
771
772 func elfwritefreebsdsig(out *OutBuf) int {
773 sh := elfshname(".note.tag")
774 if sh == nil {
775 return 0
776 }
777 out.SeekSet(int64(sh.Off))
778
779
780 out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
781 out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
782 out.Write32(ELF_NOTE_FREEBSD_ABI_TAG)
783 out.WriteString(ELF_NOTE_FREEBSD_NAME)
784 out.Write32(ELF_NOTE_FREEBSD_VERSION)
785
786
787 out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
788 out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
789 out.Write32(ELF_NOTE_FREEBSD_NOINIT_TAG)
790 out.WriteString(ELF_NOTE_FREEBSD_NAME)
791 out.Write32(0)
792
793
794 out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
795 out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
796 out.Write32(ELF_NOTE_FREEBSD_FEATURE_CTL_TAG)
797 out.WriteString(ELF_NOTE_FREEBSD_NAME)
798 if *flagRace {
799
800 out.Write32(ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE)
801 } else {
802 out.Write32(0)
803 }
804
805 return int(sh.Size)
806 }
807
808 func addbuildinfo(val string) {
809 if val == "gobuildid" {
810 buildID := *flagBuildid
811 if buildID == "" {
812 Exitf("-B gobuildid requires a Go build ID supplied via -buildid")
813 }
814
815 hashedBuildID := notsha256.Sum256([]byte(buildID))
816 buildinfo = hashedBuildID[:20]
817
818 return
819 }
820
821 if !strings.HasPrefix(val, "0x") {
822 Exitf("-B argument must start with 0x: %s", val)
823 }
824
825 ov := val
826 val = val[2:]
827
828 const maxLen = 32
829 if hex.DecodedLen(len(val)) > maxLen {
830 Exitf("-B option too long (max %d digits): %s", maxLen, ov)
831 }
832
833 b, err := hex.DecodeString(val)
834 if err != nil {
835 if err == hex.ErrLength {
836 Exitf("-B argument must have even number of digits: %s", ov)
837 }
838 if inv, ok := err.(hex.InvalidByteError); ok {
839 Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
840 }
841 Exitf("-B argument contains invalid hex: %s", ov)
842 }
843
844 buildinfo = b
845 }
846
847
848 const (
849 ELF_NOTE_BUILDINFO_NAMESZ = 4
850 ELF_NOTE_BUILDINFO_TAG = 3
851 )
852
853 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
854
855 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
856 n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
857 return elfnote(sh, startva, resoff, n)
858 }
859
860 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
861 n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
862 return elfnote(sh, startva, resoff, n)
863 }
864
865 func elfwritebuildinfo(out *OutBuf) int {
866 sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
867 if sh == nil {
868 return 0
869 }
870
871 out.Write(ELF_NOTE_BUILDINFO_NAME)
872 out.Write(buildinfo)
873 var zero = make([]byte, 4)
874 out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
875
876 return int(sh.Size)
877 }
878
879 func elfwritegobuildid(out *OutBuf) int {
880 sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
881 if sh == nil {
882 return 0
883 }
884
885 out.Write(ELF_NOTE_GO_NAME)
886 out.Write([]byte(*flagBuildid))
887 var zero = make([]byte, 4)
888 out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
889
890 return int(sh.Size)
891 }
892
893
894 const (
895 ELF_NOTE_GOPKGLIST_TAG = 1
896 ELF_NOTE_GOABIHASH_TAG = 2
897 ELF_NOTE_GODEPS_TAG = 3
898 ELF_NOTE_GOBUILDID_TAG = 4
899 )
900
901 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
902
903 var elfverneed int
904
905 type Elfaux struct {
906 next *Elfaux
907 num int
908 vers string
909 }
910
911 type Elflib struct {
912 next *Elflib
913 aux *Elfaux
914 file string
915 }
916
917 func addelflib(list **Elflib, file string, vers string) *Elfaux {
918 var lib *Elflib
919
920 for lib = *list; lib != nil; lib = lib.next {
921 if lib.file == file {
922 goto havelib
923 }
924 }
925 lib = new(Elflib)
926 lib.next = *list
927 lib.file = file
928 *list = lib
929
930 havelib:
931 for aux := lib.aux; aux != nil; aux = aux.next {
932 if aux.vers == vers {
933 return aux
934 }
935 }
936 aux := new(Elfaux)
937 aux.next = lib.aux
938 aux.vers = vers
939 lib.aux = aux
940
941 return aux
942 }
943
944 func elfdynhash(ctxt *Link) {
945 if !ctxt.IsELF {
946 return
947 }
948
949 nsym := Nelfsym
950 ldr := ctxt.loader
951 s := ldr.CreateSymForUpdate(".hash", 0)
952 s.SetType(sym.SELFROSECT)
953
954 i := nsym
955 nbucket := 1
956 for i > 0 {
957 nbucket++
958 i >>= 1
959 }
960
961 var needlib *Elflib
962 need := make([]*Elfaux, nsym)
963 chain := make([]uint32, nsym)
964 buckets := make([]uint32, nbucket)
965
966 for _, sy := range ldr.DynidSyms() {
967
968 dynid := ldr.SymDynid(sy)
969 if ldr.SymDynimpvers(sy) != "" {
970 need[dynid] = addelflib(&needlib, ldr.SymDynimplib(sy), ldr.SymDynimpvers(sy))
971 }
972
973 name := ldr.SymExtname(sy)
974 hc := elfhash(name)
975
976 b := hc % uint32(nbucket)
977 chain[dynid] = buckets[b]
978 buckets[b] = uint32(dynid)
979 }
980
981
982 if ctxt.Arch.Family == sys.S390X {
983 s.AddUint64(ctxt.Arch, uint64(nbucket))
984 s.AddUint64(ctxt.Arch, uint64(nsym))
985 for i := 0; i < nbucket; i++ {
986 s.AddUint64(ctxt.Arch, uint64(buckets[i]))
987 }
988 for i := 0; i < nsym; i++ {
989 s.AddUint64(ctxt.Arch, uint64(chain[i]))
990 }
991 } else {
992 s.AddUint32(ctxt.Arch, uint32(nbucket))
993 s.AddUint32(ctxt.Arch, uint32(nsym))
994 for i := 0; i < nbucket; i++ {
995 s.AddUint32(ctxt.Arch, buckets[i])
996 }
997 for i := 0; i < nsym; i++ {
998 s.AddUint32(ctxt.Arch, chain[i])
999 }
1000 }
1001
1002 dynstr := ldr.CreateSymForUpdate(".dynstr", 0)
1003
1004
1005 gnuVersionR := ldr.CreateSymForUpdate(".gnu.version_r", 0)
1006 s = gnuVersionR
1007 i = 2
1008 nfile := 0
1009 for l := needlib; l != nil; l = l.next {
1010 nfile++
1011
1012
1013 s.AddUint16(ctxt.Arch, 1)
1014 j := 0
1015 for x := l.aux; x != nil; x = x.next {
1016 j++
1017 }
1018 s.AddUint16(ctxt.Arch, uint16(j))
1019 s.AddUint32(ctxt.Arch, uint32(dynstr.Addstring(l.file)))
1020 s.AddUint32(ctxt.Arch, 16)
1021 if l.next != nil {
1022 s.AddUint32(ctxt.Arch, 16+uint32(j)*16)
1023 } else {
1024 s.AddUint32(ctxt.Arch, 0)
1025 }
1026
1027 for x := l.aux; x != nil; x = x.next {
1028 x.num = i
1029 i++
1030
1031
1032 s.AddUint32(ctxt.Arch, elfhash(x.vers))
1033 s.AddUint16(ctxt.Arch, 0)
1034 s.AddUint16(ctxt.Arch, uint16(x.num))
1035 s.AddUint32(ctxt.Arch, uint32(dynstr.Addstring(x.vers)))
1036 if x.next != nil {
1037 s.AddUint32(ctxt.Arch, 16)
1038 } else {
1039 s.AddUint32(ctxt.Arch, 0)
1040 }
1041 }
1042 }
1043
1044
1045 gnuVersion := ldr.CreateSymForUpdate(".gnu.version", 0)
1046 s = gnuVersion
1047
1048 for i := 0; i < nsym; i++ {
1049 if i == 0 {
1050 s.AddUint16(ctxt.Arch, 0)
1051 } else if need[i] == nil {
1052 s.AddUint16(ctxt.Arch, 1)
1053 } else {
1054 s.AddUint16(ctxt.Arch, uint16(need[i].num))
1055 }
1056 }
1057
1058 s = ldr.CreateSymForUpdate(".dynamic", 0)
1059 if ctxt.BuildMode == BuildModePIE {
1060
1061 const DTFLAGS_1_PIE = 0x08000000
1062 Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS_1, uint64(DTFLAGS_1_PIE))
1063 }
1064 elfverneed = nfile
1065 if elfverneed != 0 {
1066 elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym())
1067 Elfwritedynent(ctxt.Arch, s, elf.DT_VERNEEDNUM, uint64(nfile))
1068 elfWriteDynEntSym(ctxt, s, elf.DT_VERSYM, gnuVersion.Sym())
1069 }
1070
1071 sy := ldr.CreateSymForUpdate(elfRelType+".plt", 0)
1072 if sy.Size() > 0 {
1073 if elfRelType == ".rela" {
1074 Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_RELA))
1075 } else {
1076 Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_REL))
1077 }
1078 elfwritedynentsymsize(ctxt, s, elf.DT_PLTRELSZ, sy.Sym())
1079 elfWriteDynEntSym(ctxt, s, elf.DT_JMPREL, sy.Sym())
1080 }
1081
1082 Elfwritedynent(ctxt.Arch, s, elf.DT_NULL, 0)
1083 }
1084
1085 func elfphload(seg *sym.Segment) *ElfPhdr {
1086 ph := newElfPhdr()
1087 ph.Type = elf.PT_LOAD
1088 if seg.Rwx&4 != 0 {
1089 ph.Flags |= elf.PF_R
1090 }
1091 if seg.Rwx&2 != 0 {
1092 ph.Flags |= elf.PF_W
1093 }
1094 if seg.Rwx&1 != 0 {
1095 ph.Flags |= elf.PF_X
1096 }
1097 ph.Vaddr = seg.Vaddr
1098 ph.Paddr = seg.Vaddr
1099 ph.Memsz = seg.Length
1100 ph.Off = seg.Fileoff
1101 ph.Filesz = seg.Filelen
1102 ph.Align = uint64(*FlagRound)
1103
1104 return ph
1105 }
1106
1107 func elfphrelro(seg *sym.Segment) {
1108 ph := newElfPhdr()
1109 ph.Type = elf.PT_GNU_RELRO
1110 ph.Vaddr = seg.Vaddr
1111 ph.Paddr = seg.Vaddr
1112 ph.Memsz = seg.Length
1113 ph.Off = seg.Fileoff
1114 ph.Filesz = seg.Filelen
1115 ph.Align = uint64(*FlagRound)
1116 }
1117
1118 func elfshname(name string) *ElfShdr {
1119 for i := 0; i < nelfstr; i++ {
1120 if name != elfstr[i].s {
1121 continue
1122 }
1123 off := elfstr[i].off
1124 for i = 0; i < int(ehdr.Shnum); i++ {
1125 sh := shdr[i]
1126 if sh.Name == uint32(off) {
1127 return sh
1128 }
1129 }
1130 return newElfShdr(int64(off))
1131 }
1132 Exitf("cannot find elf name %s", name)
1133 return nil
1134 }
1135
1136
1137
1138 func elfshnamedup(name string) *ElfShdr {
1139 for i := 0; i < nelfstr; i++ {
1140 if name == elfstr[i].s {
1141 off := elfstr[i].off
1142 return newElfShdr(int64(off))
1143 }
1144 }
1145
1146 Errorf(nil, "cannot find elf name %s", name)
1147 errorexit()
1148 return nil
1149 }
1150
1151 func elfshalloc(sect *sym.Section) *ElfShdr {
1152 sh := elfshname(sect.Name)
1153 sect.Elfsect = sh
1154 return sh
1155 }
1156
1157 func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
1158 var sh *ElfShdr
1159
1160 if sect.Name == ".text" {
1161 if sect.Elfsect == nil {
1162 sect.Elfsect = elfshnamedup(sect.Name)
1163 }
1164 sh = sect.Elfsect.(*ElfShdr)
1165 } else {
1166 sh = elfshalloc(sect)
1167 }
1168
1169
1170
1171 if sh.Type == uint32(elf.SHT_NOTE) {
1172 if linkmode != LinkExternal {
1173
1174
1175
1176
1177
1178
1179
1180 Errorf(nil, "sh.Type == SHT_NOTE in elfshbits when linking internally")
1181 }
1182 sh.Addralign = uint64(sect.Align)
1183 sh.Size = sect.Length
1184 sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1185 return sh
1186 }
1187 if sh.Type > 0 {
1188 return sh
1189 }
1190
1191 if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
1192 switch sect.Name {
1193 case ".init_array":
1194 sh.Type = uint32(elf.SHT_INIT_ARRAY)
1195 default:
1196 sh.Type = uint32(elf.SHT_PROGBITS)
1197 }
1198 } else {
1199 sh.Type = uint32(elf.SHT_NOBITS)
1200 }
1201 sh.Flags = uint64(elf.SHF_ALLOC)
1202 if sect.Rwx&1 != 0 {
1203 sh.Flags |= uint64(elf.SHF_EXECINSTR)
1204 }
1205 if sect.Rwx&2 != 0 {
1206 sh.Flags |= uint64(elf.SHF_WRITE)
1207 }
1208 if sect.Name == ".tbss" {
1209 sh.Flags |= uint64(elf.SHF_TLS)
1210 sh.Type = uint32(elf.SHT_NOBITS)
1211 }
1212 if linkmode != LinkExternal {
1213 sh.Addr = sect.Vaddr
1214 }
1215
1216 if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
1217 sh.Flags = 0
1218 sh.Addr = 0
1219 if sect.Compressed {
1220 sh.Flags |= uint64(elf.SHF_COMPRESSED)
1221 }
1222 }
1223
1224 sh.Addralign = uint64(sect.Align)
1225 sh.Size = sect.Length
1226 if sect.Name != ".tbss" {
1227 sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1228 }
1229
1230 return sh
1231 }
1232
1233 func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
1234
1235
1236 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1237 return nil
1238 }
1239 if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
1240 return nil
1241 }
1242 if sect.Elfsect.(*ElfShdr).Type == uint32(elf.SHT_NOTE) {
1243 return nil
1244 }
1245
1246 typ := elf.SHT_REL
1247 if elfRelType == ".rela" {
1248 typ = elf.SHT_RELA
1249 }
1250
1251 sh := elfshname(elfRelType + sect.Name)
1252
1253
1254
1255 if sect.Name == ".text" {
1256 if sh.Info != 0 && sh.Info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
1257 sh = elfshnamedup(elfRelType + sect.Name)
1258 }
1259 }
1260
1261 sh.Type = uint32(typ)
1262 sh.Entsize = uint64(arch.RegSize) * 2
1263 if typ == elf.SHT_RELA {
1264 sh.Entsize += uint64(arch.RegSize)
1265 }
1266 sh.Link = uint32(elfshname(".symtab").shnum)
1267 sh.Info = uint32(sect.Elfsect.(*ElfShdr).shnum)
1268 sh.Off = sect.Reloff
1269 sh.Size = sect.Rellen
1270 sh.Addralign = uint64(arch.RegSize)
1271 return sh
1272 }
1273
1274 func elfrelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) {
1275
1276
1277 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1278 return
1279 }
1280 if sect.Name == ".shstrtab" {
1281 return
1282 }
1283
1284 ldr := ctxt.loader
1285 for i, s := range syms {
1286 if !ldr.AttrReachable(s) {
1287 panic("should never happen")
1288 }
1289 if uint64(ldr.SymValue(s)) >= sect.Vaddr {
1290 syms = syms[i:]
1291 break
1292 }
1293 }
1294
1295 eaddr := sect.Vaddr + sect.Length
1296 for _, s := range syms {
1297 if !ldr.AttrReachable(s) {
1298 continue
1299 }
1300 if ldr.SymValue(s) >= int64(eaddr) {
1301 break
1302 }
1303
1304
1305
1306 relocs := ldr.Relocs(s)
1307 for ri := 0; ri < relocs.Count(); ri++ {
1308 r := relocs.At(ri)
1309 rr, ok := extreloc(ctxt, ldr, s, r)
1310 if !ok {
1311 continue
1312 }
1313 if rr.Xsym == 0 {
1314 ldr.Errorf(s, "missing xsym in relocation")
1315 continue
1316 }
1317 esr := ElfSymForReloc(ctxt, rr.Xsym)
1318 if esr == 0 {
1319 ldr.Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Sym()), ldr.SymName(rr.Xsym), ldr.SymType(r.Sym()), ldr.SymType(r.Sym()).String())
1320 }
1321 if !ldr.AttrReachable(rr.Xsym) {
1322 ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(rr.Xsym))
1323 }
1324 if !thearch.ELF.Reloc1(ctxt, out, ldr, s, rr, ri, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) {
1325 ldr.Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), r.Siz(), ldr.SymName(r.Sym()))
1326 }
1327 }
1328 }
1329
1330
1331 if uint64(out.Offset()) != sect.Reloff+sect.Rellen {
1332 panic(fmt.Sprintf("elfrelocsect: size mismatch %d != %d + %d", out.Offset(), sect.Reloff, sect.Rellen))
1333 }
1334 }
1335
1336 func elfEmitReloc(ctxt *Link) {
1337 for ctxt.Out.Offset()&7 != 0 {
1338 ctxt.Out.Write8(0)
1339 }
1340
1341 sizeExtRelocs(ctxt, thearch.ELF.RelocSize)
1342 relocSect, wg := relocSectFn(ctxt, elfrelocsect)
1343
1344 for _, sect := range Segtext.Sections {
1345 if sect.Name == ".text" {
1346 relocSect(ctxt, sect, ctxt.Textp)
1347 } else {
1348 relocSect(ctxt, sect, ctxt.datap)
1349 }
1350 }
1351
1352 for _, sect := range Segrodata.Sections {
1353 relocSect(ctxt, sect, ctxt.datap)
1354 }
1355 for _, sect := range Segrelrodata.Sections {
1356 relocSect(ctxt, sect, ctxt.datap)
1357 }
1358 for _, sect := range Segdata.Sections {
1359 relocSect(ctxt, sect, ctxt.datap)
1360 }
1361 for i := 0; i < len(Segdwarf.Sections); i++ {
1362 sect := Segdwarf.Sections[i]
1363 si := dwarfp[i]
1364 if si.secSym() != loader.Sym(sect.Sym) ||
1365 ctxt.loader.SymSect(si.secSym()) != sect {
1366 panic("inconsistency between dwarfp and Segdwarf")
1367 }
1368 relocSect(ctxt, sect, si.syms)
1369 }
1370 wg.Wait()
1371 }
1372
1373 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
1374 ldr := ctxt.loader
1375 s := ldr.CreateSymForUpdate(sectionName, 0)
1376 s.SetType(sym.SELFROSECT)
1377
1378 s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
1379
1380 s.AddUint32(ctxt.Arch, uint32(len(desc)))
1381
1382 s.AddUint32(ctxt.Arch, tag)
1383
1384 s.AddBytes(ELF_NOTE_GO_NAME)
1385 for len(s.Data())%4 != 0 {
1386 s.AddUint8(0)
1387 }
1388
1389 s.AddBytes(desc)
1390 for len(s.Data())%4 != 0 {
1391 s.AddUint8(0)
1392 }
1393 s.SetSize(int64(len(s.Data())))
1394 s.SetAlign(4)
1395 }
1396
1397 func (ctxt *Link) doelf() {
1398 ldr := ctxt.loader
1399
1400
1401
1402 addshstr := func(s string) int {
1403 off := len(elfshstrdat)
1404 elfshstrdat = append(elfshstrdat, s...)
1405 elfshstrdat = append(elfshstrdat, 0)
1406 return off
1407 }
1408
1409 shstrtabAddstring := func(s string) {
1410 off := addshstr(s)
1411 elfsetstring(ctxt, 0, s, int(off))
1412 }
1413
1414 shstrtabAddstring("")
1415 shstrtabAddstring(".text")
1416 shstrtabAddstring(".noptrdata")
1417 shstrtabAddstring(".data")
1418 shstrtabAddstring(".bss")
1419 shstrtabAddstring(".noptrbss")
1420 shstrtabAddstring(".go.fuzzcntrs")
1421 shstrtabAddstring(".go.buildinfo")
1422 if ctxt.IsMIPS() {
1423 shstrtabAddstring(".MIPS.abiflags")
1424 shstrtabAddstring(".gnu.attributes")
1425 }
1426
1427
1428
1429
1430 if !*FlagD || ctxt.IsExternal() {
1431 shstrtabAddstring(".tbss")
1432 }
1433 if ctxt.IsNetbsd() {
1434 shstrtabAddstring(".note.netbsd.ident")
1435 if *flagRace {
1436 shstrtabAddstring(".note.netbsd.pax")
1437 }
1438 }
1439 if ctxt.IsOpenbsd() {
1440 shstrtabAddstring(".note.openbsd.ident")
1441 }
1442 if ctxt.IsFreebsd() {
1443 shstrtabAddstring(".note.tag")
1444 }
1445 if len(buildinfo) > 0 {
1446 shstrtabAddstring(".note.gnu.build-id")
1447 }
1448 if *flagBuildid != "" {
1449 shstrtabAddstring(".note.go.buildid")
1450 }
1451 shstrtabAddstring(".elfdata")
1452 shstrtabAddstring(".rodata")
1453
1454 relro_prefix := ""
1455 if ctxt.UseRelro() {
1456 shstrtabAddstring(".data.rel.ro")
1457 relro_prefix = ".data.rel.ro"
1458 }
1459 shstrtabAddstring(relro_prefix + ".typelink")
1460 shstrtabAddstring(relro_prefix + ".itablink")
1461 shstrtabAddstring(relro_prefix + ".gosymtab")
1462 shstrtabAddstring(relro_prefix + ".gopclntab")
1463
1464 if ctxt.IsExternal() {
1465 *FlagD = true
1466
1467 shstrtabAddstring(elfRelType + ".text")
1468 shstrtabAddstring(elfRelType + ".rodata")
1469 shstrtabAddstring(elfRelType + relro_prefix + ".typelink")
1470 shstrtabAddstring(elfRelType + relro_prefix + ".itablink")
1471 shstrtabAddstring(elfRelType + relro_prefix + ".gosymtab")
1472 shstrtabAddstring(elfRelType + relro_prefix + ".gopclntab")
1473 shstrtabAddstring(elfRelType + ".noptrdata")
1474 shstrtabAddstring(elfRelType + ".data")
1475 if ctxt.UseRelro() {
1476 shstrtabAddstring(elfRelType + ".data.rel.ro")
1477 }
1478 shstrtabAddstring(elfRelType + ".go.buildinfo")
1479 if ctxt.IsMIPS() {
1480 shstrtabAddstring(elfRelType + ".MIPS.abiflags")
1481 shstrtabAddstring(elfRelType + ".gnu.attributes")
1482 }
1483
1484
1485 shstrtabAddstring(".note.GNU-stack")
1486
1487 if ctxt.IsShared() {
1488 shstrtabAddstring(".note.go.abihash")
1489 shstrtabAddstring(".note.go.pkg-list")
1490 shstrtabAddstring(".note.go.deps")
1491 }
1492 }
1493
1494 hasinitarr := ctxt.linkShared
1495
1496
1497 switch ctxt.BuildMode {
1498 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
1499 hasinitarr = true
1500 }
1501
1502 if hasinitarr {
1503 shstrtabAddstring(".init_array")
1504 shstrtabAddstring(elfRelType + ".init_array")
1505 }
1506
1507 if !*FlagS {
1508 shstrtabAddstring(".symtab")
1509 shstrtabAddstring(".strtab")
1510 }
1511 if !*FlagW {
1512 dwarfaddshstrings(ctxt, shstrtabAddstring)
1513 }
1514
1515 shstrtabAddstring(".shstrtab")
1516
1517 if !*FlagD {
1518 shstrtabAddstring(".interp")
1519 shstrtabAddstring(".hash")
1520 shstrtabAddstring(".got")
1521 if ctxt.IsPPC64() {
1522 shstrtabAddstring(".glink")
1523 }
1524 shstrtabAddstring(".got.plt")
1525 shstrtabAddstring(".dynamic")
1526 shstrtabAddstring(".dynsym")
1527 shstrtabAddstring(".dynstr")
1528 shstrtabAddstring(elfRelType)
1529 shstrtabAddstring(elfRelType + ".plt")
1530
1531 shstrtabAddstring(".plt")
1532 shstrtabAddstring(".gnu.version")
1533 shstrtabAddstring(".gnu.version_r")
1534
1535
1536 dynsym := ldr.CreateSymForUpdate(".dynsym", 0)
1537
1538 dynsym.SetType(sym.SELFROSECT)
1539 if elf64 {
1540 dynsym.SetSize(dynsym.Size() + ELF64SYMSIZE)
1541 } else {
1542 dynsym.SetSize(dynsym.Size() + ELF32SYMSIZE)
1543 }
1544
1545
1546 dynstr := ldr.CreateSymForUpdate(".dynstr", 0)
1547
1548 dynstr.SetType(sym.SELFROSECT)
1549 if dynstr.Size() == 0 {
1550 dynstr.Addstring("")
1551 }
1552
1553
1554 s := ldr.CreateSymForUpdate(elfRelType, 0)
1555 s.SetType(sym.SELFROSECT)
1556
1557
1558 got := ldr.CreateSymForUpdate(".got", 0)
1559 got.SetType(sym.SELFGOT)
1560
1561
1562 if ctxt.IsPPC64() {
1563 s := ldr.CreateSymForUpdate(".glink", 0)
1564 s.SetType(sym.SELFRXSECT)
1565 }
1566
1567
1568 hash := ldr.CreateSymForUpdate(".hash", 0)
1569 hash.SetType(sym.SELFROSECT)
1570
1571 gotplt := ldr.CreateSymForUpdate(".got.plt", 0)
1572 gotplt.SetType(sym.SELFSECT)
1573
1574 plt := ldr.CreateSymForUpdate(".plt", 0)
1575 if ctxt.IsPPC64() {
1576
1577
1578 plt.SetType(sym.SELFSECT)
1579 } else {
1580 plt.SetType(sym.SELFRXSECT)
1581 }
1582
1583 s = ldr.CreateSymForUpdate(elfRelType+".plt", 0)
1584 s.SetType(sym.SELFROSECT)
1585
1586 s = ldr.CreateSymForUpdate(".gnu.version", 0)
1587 s.SetType(sym.SELFROSECT)
1588
1589 s = ldr.CreateSymForUpdate(".gnu.version_r", 0)
1590 s.SetType(sym.SELFROSECT)
1591
1592
1593 dynamic := ldr.CreateSymForUpdate(".dynamic", 0)
1594 if thearch.ELF.DynamicReadOnly {
1595 dynamic.SetType(sym.SELFROSECT)
1596 } else {
1597 dynamic.SetType(sym.SELFSECT)
1598 }
1599
1600 if ctxt.IsS390X() {
1601
1602 gotplt = got
1603 }
1604 thearch.ELF.SetupPLT(ctxt, ctxt.loader, plt, gotplt, dynamic.Sym())
1605
1606
1609 elfWriteDynEntSym(ctxt, dynamic, elf.DT_HASH, hash.Sym())
1610
1611 elfWriteDynEntSym(ctxt, dynamic, elf.DT_SYMTAB, dynsym.Sym())
1612 if elf64 {
1613 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF64SYMSIZE)
1614 } else {
1615 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF32SYMSIZE)
1616 }
1617 elfWriteDynEntSym(ctxt, dynamic, elf.DT_STRTAB, dynstr.Sym())
1618 elfwritedynentsymsize(ctxt, dynamic, elf.DT_STRSZ, dynstr.Sym())
1619 if elfRelType == ".rela" {
1620 rela := ldr.LookupOrCreateSym(".rela", 0)
1621 elfWriteDynEntSym(ctxt, dynamic, elf.DT_RELA, rela)
1622 elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELASZ, rela)
1623 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELAENT, ELF64RELASIZE)
1624 } else {
1625 rel := ldr.LookupOrCreateSym(".rel", 0)
1626 elfWriteDynEntSym(ctxt, dynamic, elf.DT_REL, rel)
1627 elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELSZ, rel)
1628 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELENT, ELF32RELSIZE)
1629 }
1630
1631 if rpath.val != "" {
1632 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
1633 }
1634
1635 if ctxt.IsPPC64() {
1636 elfWriteDynEntSym(ctxt, dynamic, elf.DT_PLTGOT, plt.Sym())
1637 } else {
1638 elfWriteDynEntSym(ctxt, dynamic, elf.DT_PLTGOT, gotplt.Sym())
1639 }
1640
1641 if ctxt.IsPPC64() {
1642 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_PPC64_OPT, 0)
1643 }
1644
1645
1646
1647
1648
1649
1650 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_DEBUG, 0)
1651 }
1652
1653 if ctxt.IsShared() {
1654
1655
1656 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
1657 sb := ldr.MakeSymbolUpdater(s)
1658 ldr.SetAttrLocal(s, true)
1659 sb.SetType(sym.SRODATA)
1660 ldr.SetAttrSpecial(s, true)
1661 sb.SetReachable(true)
1662 sb.SetSize(notsha256.Size)
1663
1664 sort.Sort(byPkg(ctxt.Library))
1665 h := notsha256.New()
1666 for _, l := range ctxt.Library {
1667 h.Write(l.Fingerprint[:])
1668 }
1669 addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
1670 addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
1671 var deplist []string
1672 for _, shlib := range ctxt.Shlibs {
1673 deplist = append(deplist, filepath.Base(shlib.Path))
1674 }
1675 addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
1676 }
1677
1678 if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
1679 addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
1680 }
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691 if ctxt.IsMIPS() {
1692 gnuattributes := ldr.CreateSymForUpdate(".gnu.attributes", 0)
1693 gnuattributes.SetType(sym.SELFROSECT)
1694 gnuattributes.SetReachable(true)
1695 gnuattributes.AddUint8('A')
1696 gnuattributes.AddUint32(ctxt.Arch, 15)
1697 gnuattributes.AddBytes([]byte("gnu\x00"))
1698 gnuattributes.AddUint8(1)
1699 gnuattributes.AddUint32(ctxt.Arch, 7)
1700 gnuattributes.AddUint8(4)
1701 if buildcfg.GOMIPS == "softfloat" {
1702 gnuattributes.AddUint8(MIPS_FPABI_SOFT)
1703 } else {
1704
1705
1706
1707 gnuattributes.AddUint8(MIPS_FPABI_ANY)
1708 }
1709 }
1710 }
1711
1712
1713 func shsym(sh *ElfShdr, ldr *loader.Loader, s loader.Sym) {
1714 if s == 0 {
1715 panic("bad symbol in shsym2")
1716 }
1717 addr := ldr.SymValue(s)
1718 if sh.Flags&uint64(elf.SHF_ALLOC) != 0 {
1719 sh.Addr = uint64(addr)
1720 }
1721 sh.Off = uint64(datoff(ldr, s, addr))
1722 sh.Size = uint64(ldr.SymSize(s))
1723 }
1724
1725 func phsh(ph *ElfPhdr, sh *ElfShdr) {
1726 ph.Vaddr = sh.Addr
1727 ph.Paddr = ph.Vaddr
1728 ph.Off = sh.Off
1729 ph.Filesz = sh.Size
1730 ph.Memsz = sh.Size
1731 ph.Align = sh.Addralign
1732 }
1733
1734 func Asmbelfsetup() {
1735
1736 elfshname("")
1737
1738 for _, sect := range Segtext.Sections {
1739
1740
1741 if sect.Name == ".text" {
1742 if sect.Elfsect == nil {
1743 sect.Elfsect = elfshnamedup(sect.Name)
1744 }
1745 } else {
1746 elfshalloc(sect)
1747 }
1748 }
1749 for _, sect := range Segrodata.Sections {
1750 elfshalloc(sect)
1751 }
1752 for _, sect := range Segrelrodata.Sections {
1753 elfshalloc(sect)
1754 }
1755 for _, sect := range Segdata.Sections {
1756 elfshalloc(sect)
1757 }
1758 for _, sect := range Segdwarf.Sections {
1759 elfshalloc(sect)
1760 }
1761 }
1762
1763 func asmbElf(ctxt *Link) {
1764 var symo int64
1765 symo = int64(Segdwarf.Fileoff + Segdwarf.Filelen)
1766 symo = Rnd(symo, int64(ctxt.Arch.PtrSize))
1767 ctxt.Out.SeekSet(symo)
1768 if *FlagS {
1769 ctxt.Out.Write(elfshstrdat)
1770 } else {
1771 ctxt.Out.SeekSet(symo)
1772 asmElfSym(ctxt)
1773 ctxt.Out.Write(elfstrdat)
1774 ctxt.Out.Write(elfshstrdat)
1775 if ctxt.IsExternal() {
1776 elfEmitReloc(ctxt)
1777 }
1778 }
1779 ctxt.Out.SeekSet(0)
1780
1781 ldr := ctxt.loader
1782 eh := getElfEhdr()
1783 switch ctxt.Arch.Family {
1784 default:
1785 Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
1786 case sys.MIPS, sys.MIPS64:
1787 eh.Machine = uint16(elf.EM_MIPS)
1788 case sys.Loong64:
1789 eh.Machine = uint16(elf.EM_LOONGARCH)
1790 case sys.ARM:
1791 eh.Machine = uint16(elf.EM_ARM)
1792 case sys.AMD64:
1793 eh.Machine = uint16(elf.EM_X86_64)
1794 case sys.ARM64:
1795 eh.Machine = uint16(elf.EM_AARCH64)
1796 case sys.I386:
1797 eh.Machine = uint16(elf.EM_386)
1798 case sys.PPC64:
1799 eh.Machine = uint16(elf.EM_PPC64)
1800 case sys.RISCV64:
1801 eh.Machine = uint16(elf.EM_RISCV)
1802 case sys.S390X:
1803 eh.Machine = uint16(elf.EM_S390)
1804 }
1805
1806 elfreserve := int64(ELFRESERVE)
1807
1808 numtext := int64(0)
1809 for _, sect := range Segtext.Sections {
1810 if sect.Name == ".text" {
1811 numtext++
1812 }
1813 }
1814
1815
1816
1817
1818
1819
1820 if numtext > 4 {
1821 elfreserve += elfreserve + numtext*64*2
1822 }
1823
1824 startva := *FlagTextAddr - int64(HEADR)
1825 resoff := elfreserve
1826
1827 var pph *ElfPhdr
1828 var pnote *ElfPhdr
1829 getpnote := func() *ElfPhdr {
1830 if pnote == nil {
1831 pnote = newElfPhdr()
1832 pnote.Type = elf.PT_NOTE
1833 pnote.Flags = elf.PF_R
1834 }
1835 return pnote
1836 }
1837 if *flagRace && ctxt.IsNetbsd() {
1838 sh := elfshname(".note.netbsd.pax")
1839 resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff)))
1840 phsh(getpnote(), sh)
1841 }
1842 if ctxt.LinkMode == LinkExternal {
1843
1844 eh.Phoff = 0
1845
1846 eh.Phentsize = 0
1847
1848 if ctxt.BuildMode == BuildModeShared {
1849 sh := elfshname(".note.go.pkg-list")
1850 sh.Type = uint32(elf.SHT_NOTE)
1851 sh = elfshname(".note.go.abihash")
1852 sh.Type = uint32(elf.SHT_NOTE)
1853 sh.Flags = uint64(elf.SHF_ALLOC)
1854 sh = elfshname(".note.go.deps")
1855 sh.Type = uint32(elf.SHT_NOTE)
1856 }
1857
1858 if *flagBuildid != "" {
1859 sh := elfshname(".note.go.buildid")
1860 sh.Type = uint32(elf.SHT_NOTE)
1861 sh.Flags = uint64(elf.SHF_ALLOC)
1862 }
1863
1864 goto elfobj
1865 }
1866
1867
1868 pph = newElfPhdr()
1869
1870 pph.Type = elf.PT_PHDR
1871 pph.Flags = elf.PF_R
1872 pph.Off = uint64(eh.Ehsize)
1873 pph.Vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off
1874 pph.Paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off
1875 pph.Align = uint64(*FlagRound)
1876
1877
1881 {
1882 o := int64(Segtext.Vaddr - pph.Vaddr)
1883 Segtext.Vaddr -= uint64(o)
1884 Segtext.Length += uint64(o)
1885 o = int64(Segtext.Fileoff - pph.Off)
1886 Segtext.Fileoff -= uint64(o)
1887 Segtext.Filelen += uint64(o)
1888 }
1889
1890 if !*FlagD {
1891
1892 sh := elfshname(".interp")
1893
1894 sh.Type = uint32(elf.SHT_PROGBITS)
1895 sh.Flags = uint64(elf.SHF_ALLOC)
1896 sh.Addralign = 1
1897
1898 if interpreter == "" && buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH && buildcfg.GO_LDSO != "" {
1899 interpreter = buildcfg.GO_LDSO
1900 }
1901
1902 if interpreter == "" {
1903 switch ctxt.HeadType {
1904 case objabi.Hlinux:
1905 if buildcfg.GOOS == "android" {
1906 interpreter = thearch.ELF.Androiddynld
1907 if interpreter == "" {
1908 Exitf("ELF interpreter not set")
1909 }
1910 } else {
1911 interpreter = thearch.ELF.Linuxdynld
1912
1913
1914
1915 if _, err := os.Stat(interpreter); err != nil {
1916 if musl := thearch.ELF.LinuxdynldMusl; musl != "" {
1917 if _, err := os.Stat(musl); err == nil {
1918 interpreter = musl
1919 }
1920 }
1921 }
1922 }
1923
1924 case objabi.Hfreebsd:
1925 interpreter = thearch.ELF.Freebsddynld
1926
1927 case objabi.Hnetbsd:
1928 interpreter = thearch.ELF.Netbsddynld
1929
1930 case objabi.Hopenbsd:
1931 interpreter = thearch.ELF.Openbsddynld
1932
1933 case objabi.Hdragonfly:
1934 interpreter = thearch.ELF.Dragonflydynld
1935
1936 case objabi.Hsolaris:
1937 interpreter = thearch.ELF.Solarisdynld
1938 }
1939 }
1940
1941 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
1942
1943 ph := newElfPhdr()
1944 ph.Type = elf.PT_INTERP
1945 ph.Flags = elf.PF_R
1946 phsh(ph, sh)
1947 }
1948
1949 if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd || ctxt.HeadType == objabi.Hfreebsd {
1950 var sh *ElfShdr
1951 switch ctxt.HeadType {
1952 case objabi.Hnetbsd:
1953 sh = elfshname(".note.netbsd.ident")
1954 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
1955
1956 case objabi.Hopenbsd:
1957 sh = elfshname(".note.openbsd.ident")
1958 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
1959
1960 case objabi.Hfreebsd:
1961 sh = elfshname(".note.tag")
1962 resoff -= int64(elffreebsdsig(sh, uint64(startva), uint64(resoff)))
1963 }
1964
1965 pnotei := newElfPhdr()
1966 pnotei.Type = elf.PT_NOTE
1967 pnotei.Flags = elf.PF_R
1968 phsh(pnotei, sh)
1969 }
1970
1971 if len(buildinfo) > 0 {
1972 sh := elfshname(".note.gnu.build-id")
1973 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
1974 phsh(getpnote(), sh)
1975 }
1976
1977 if *flagBuildid != "" {
1978 sh := elfshname(".note.go.buildid")
1979 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
1980 phsh(getpnote(), sh)
1981 }
1982
1983
1984
1985 elfphload(&Segtext)
1986 if len(Segrodata.Sections) > 0 {
1987 elfphload(&Segrodata)
1988 }
1989 if len(Segrelrodata.Sections) > 0 {
1990 elfphload(&Segrelrodata)
1991 elfphrelro(&Segrelrodata)
1992 }
1993 elfphload(&Segdata)
1994
1995
1996 if !*FlagD {
1997 sh := elfshname(".dynsym")
1998 sh.Type = uint32(elf.SHT_DYNSYM)
1999 sh.Flags = uint64(elf.SHF_ALLOC)
2000 if elf64 {
2001 sh.Entsize = ELF64SYMSIZE
2002 } else {
2003 sh.Entsize = ELF32SYMSIZE
2004 }
2005 sh.Addralign = uint64(ctxt.Arch.RegSize)
2006 sh.Link = uint32(elfshname(".dynstr").shnum)
2007
2008
2009 s := ldr.Lookup(".dynsym", 0)
2010 i := uint32(0)
2011 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2012 i++
2013 if !ldr.AttrLocal(sub) {
2014 break
2015 }
2016 }
2017 sh.Info = i
2018 shsym(sh, ldr, s)
2019
2020 sh = elfshname(".dynstr")
2021 sh.Type = uint32(elf.SHT_STRTAB)
2022 sh.Flags = uint64(elf.SHF_ALLOC)
2023 sh.Addralign = 1
2024 shsym(sh, ldr, ldr.Lookup(".dynstr", 0))
2025
2026 if elfverneed != 0 {
2027 sh := elfshname(".gnu.version")
2028 sh.Type = uint32(elf.SHT_GNU_VERSYM)
2029 sh.Flags = uint64(elf.SHF_ALLOC)
2030 sh.Addralign = 2
2031 sh.Link = uint32(elfshname(".dynsym").shnum)
2032 sh.Entsize = 2
2033 shsym(sh, ldr, ldr.Lookup(".gnu.version", 0))
2034
2035 sh = elfshname(".gnu.version_r")
2036 sh.Type = uint32(elf.SHT_GNU_VERNEED)
2037 sh.Flags = uint64(elf.SHF_ALLOC)
2038 sh.Addralign = uint64(ctxt.Arch.RegSize)
2039 sh.Info = uint32(elfverneed)
2040 sh.Link = uint32(elfshname(".dynstr").shnum)
2041 shsym(sh, ldr, ldr.Lookup(".gnu.version_r", 0))
2042 }
2043
2044 if elfRelType == ".rela" {
2045 sh := elfshname(".rela.plt")
2046 sh.Type = uint32(elf.SHT_RELA)
2047 sh.Flags = uint64(elf.SHF_ALLOC)
2048 sh.Entsize = ELF64RELASIZE
2049 sh.Addralign = uint64(ctxt.Arch.RegSize)
2050 sh.Link = uint32(elfshname(".dynsym").shnum)
2051 sh.Info = uint32(elfshname(".plt").shnum)
2052 shsym(sh, ldr, ldr.Lookup(".rela.plt", 0))
2053
2054 sh = elfshname(".rela")
2055 sh.Type = uint32(elf.SHT_RELA)
2056 sh.Flags = uint64(elf.SHF_ALLOC)
2057 sh.Entsize = ELF64RELASIZE
2058 sh.Addralign = 8
2059 sh.Link = uint32(elfshname(".dynsym").shnum)
2060 shsym(sh, ldr, ldr.Lookup(".rela", 0))
2061 } else {
2062 sh := elfshname(".rel.plt")
2063 sh.Type = uint32(elf.SHT_REL)
2064 sh.Flags = uint64(elf.SHF_ALLOC)
2065 sh.Entsize = ELF32RELSIZE
2066 sh.Addralign = 4
2067 sh.Link = uint32(elfshname(".dynsym").shnum)
2068 shsym(sh, ldr, ldr.Lookup(".rel.plt", 0))
2069
2070 sh = elfshname(".rel")
2071 sh.Type = uint32(elf.SHT_REL)
2072 sh.Flags = uint64(elf.SHF_ALLOC)
2073 sh.Entsize = ELF32RELSIZE
2074 sh.Addralign = 4
2075 sh.Link = uint32(elfshname(".dynsym").shnum)
2076 shsym(sh, ldr, ldr.Lookup(".rel", 0))
2077 }
2078
2079 if elf.Machine(eh.Machine) == elf.EM_PPC64 {
2080 sh := elfshname(".glink")
2081 sh.Type = uint32(elf.SHT_PROGBITS)
2082 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR)
2083 sh.Addralign = 4
2084 shsym(sh, ldr, ldr.Lookup(".glink", 0))
2085 }
2086
2087 sh = elfshname(".plt")
2088 sh.Type = uint32(elf.SHT_PROGBITS)
2089 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR)
2090 if elf.Machine(eh.Machine) == elf.EM_X86_64 {
2091 sh.Entsize = 16
2092 } else if elf.Machine(eh.Machine) == elf.EM_S390 {
2093 sh.Entsize = 32
2094 } else if elf.Machine(eh.Machine) == elf.EM_PPC64 {
2095
2096
2097 sh.Type = uint32(elf.SHT_NOBITS)
2098
2099 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2100 sh.Entsize = 8
2101 } else {
2102 sh.Entsize = 4
2103 }
2104 sh.Addralign = sh.Entsize
2105 shsym(sh, ldr, ldr.Lookup(".plt", 0))
2106
2107
2108
2109 if elf.Machine(eh.Machine) != elf.EM_PPC64 {
2110 sh := elfshname(".got")
2111 sh.Type = uint32(elf.SHT_PROGBITS)
2112 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2113 sh.Entsize = uint64(ctxt.Arch.RegSize)
2114 sh.Addralign = uint64(ctxt.Arch.RegSize)
2115 shsym(sh, ldr, ldr.Lookup(".got", 0))
2116
2117 sh = elfshname(".got.plt")
2118 sh.Type = uint32(elf.SHT_PROGBITS)
2119 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2120 sh.Entsize = uint64(ctxt.Arch.RegSize)
2121 sh.Addralign = uint64(ctxt.Arch.RegSize)
2122 shsym(sh, ldr, ldr.Lookup(".got.plt", 0))
2123 }
2124
2125 sh = elfshname(".hash")
2126 sh.Type = uint32(elf.SHT_HASH)
2127 sh.Flags = uint64(elf.SHF_ALLOC)
2128 sh.Entsize = 4
2129 sh.Addralign = uint64(ctxt.Arch.RegSize)
2130 sh.Link = uint32(elfshname(".dynsym").shnum)
2131 shsym(sh, ldr, ldr.Lookup(".hash", 0))
2132
2133
2134 sh = elfshname(".dynamic")
2135
2136 sh.Type = uint32(elf.SHT_DYNAMIC)
2137 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2138 sh.Entsize = 2 * uint64(ctxt.Arch.RegSize)
2139 sh.Addralign = uint64(ctxt.Arch.RegSize)
2140 sh.Link = uint32(elfshname(".dynstr").shnum)
2141 shsym(sh, ldr, ldr.Lookup(".dynamic", 0))
2142 ph := newElfPhdr()
2143 ph.Type = elf.PT_DYNAMIC
2144 ph.Flags = elf.PF_R + elf.PF_W
2145 phsh(ph, sh)
2146
2147
2150 tlssize := uint64(0)
2151 for _, sect := range Segdata.Sections {
2152 if sect.Name == ".tbss" {
2153 tlssize = sect.Length
2154 }
2155 }
2156 if tlssize != 0 {
2157 ph := newElfPhdr()
2158 ph.Type = elf.PT_TLS
2159 ph.Flags = elf.PF_R
2160 ph.Memsz = tlssize
2161 ph.Align = uint64(ctxt.Arch.RegSize)
2162 }
2163 }
2164
2165 if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd {
2166 ph := newElfPhdr()
2167 ph.Type = elf.PT_GNU_STACK
2168 ph.Flags = elf.PF_W + elf.PF_R
2169 ph.Align = uint64(ctxt.Arch.RegSize)
2170 } else if ctxt.HeadType == objabi.Hsolaris {
2171 ph := newElfPhdr()
2172 ph.Type = elf.PT_SUNWSTACK
2173 ph.Flags = elf.PF_W + elf.PF_R
2174 }
2175
2176 elfobj:
2177 sh := elfshname(".shstrtab")
2178 eh.Shstrndx = uint16(sh.shnum)
2179
2180 if ctxt.IsMIPS() {
2181 sh = elfshname(".MIPS.abiflags")
2182 sh.Type = uint32(elf.SHT_MIPS_ABIFLAGS)
2183 sh.Flags = uint64(elf.SHF_ALLOC)
2184 sh.Addralign = 8
2185 resoff -= int64(elfMipsAbiFlags(sh, uint64(startva), uint64(resoff)))
2186
2187 ph := newElfPhdr()
2188 ph.Type = elf.PT_MIPS_ABIFLAGS
2189 ph.Flags = elf.PF_R
2190 phsh(ph, sh)
2191
2192 sh = elfshname(".gnu.attributes")
2193 sh.Type = uint32(elf.SHT_GNU_ATTRIBUTES)
2194 sh.Addralign = 1
2195 ldr := ctxt.loader
2196 shsym(sh, ldr, ldr.Lookup(".gnu.attributes", 0))
2197 }
2198
2199
2200 if !*FlagS {
2201 elfshname(".symtab")
2202 elfshname(".strtab")
2203 }
2204 elfshname(".shstrtab")
2205
2206 for _, sect := range Segtext.Sections {
2207 elfshbits(ctxt.LinkMode, sect)
2208 }
2209 for _, sect := range Segrodata.Sections {
2210 elfshbits(ctxt.LinkMode, sect)
2211 }
2212 for _, sect := range Segrelrodata.Sections {
2213 elfshbits(ctxt.LinkMode, sect)
2214 }
2215 for _, sect := range Segdata.Sections {
2216 elfshbits(ctxt.LinkMode, sect)
2217 }
2218 for _, sect := range Segdwarf.Sections {
2219 elfshbits(ctxt.LinkMode, sect)
2220 }
2221
2222 if ctxt.LinkMode == LinkExternal {
2223 for _, sect := range Segtext.Sections {
2224 elfshreloc(ctxt.Arch, sect)
2225 }
2226 for _, sect := range Segrodata.Sections {
2227 elfshreloc(ctxt.Arch, sect)
2228 }
2229 for _, sect := range Segrelrodata.Sections {
2230 elfshreloc(ctxt.Arch, sect)
2231 }
2232 for _, sect := range Segdata.Sections {
2233 elfshreloc(ctxt.Arch, sect)
2234 }
2235 for _, si := range dwarfp {
2236 sect := ldr.SymSect(si.secSym())
2237 elfshreloc(ctxt.Arch, sect)
2238 }
2239
2240 sh := elfshname(".note.GNU-stack")
2241
2242 sh.Type = uint32(elf.SHT_PROGBITS)
2243 sh.Addralign = 1
2244 sh.Flags = 0
2245 }
2246
2247 var shstroff uint64
2248 if !*FlagS {
2249 sh := elfshname(".symtab")
2250 sh.Type = uint32(elf.SHT_SYMTAB)
2251 sh.Off = uint64(symo)
2252 sh.Size = uint64(symSize)
2253 sh.Addralign = uint64(ctxt.Arch.RegSize)
2254 sh.Entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
2255 sh.Link = uint32(elfshname(".strtab").shnum)
2256 sh.Info = uint32(elfglobalsymndx)
2257
2258 sh = elfshname(".strtab")
2259 sh.Type = uint32(elf.SHT_STRTAB)
2260 sh.Off = uint64(symo) + uint64(symSize)
2261 sh.Size = uint64(len(elfstrdat))
2262 sh.Addralign = 1
2263 shstroff = sh.Off + sh.Size
2264 } else {
2265 shstroff = uint64(symo)
2266 }
2267
2268 sh = elfshname(".shstrtab")
2269 sh.Type = uint32(elf.SHT_STRTAB)
2270 sh.Off = shstroff
2271 sh.Size = uint64(len(elfshstrdat))
2272 sh.Addralign = 1
2273
2274
2275 copy(eh.Ident[:], elf.ELFMAG)
2276
2277 var osabi elf.OSABI
2278 switch ctxt.HeadType {
2279 case objabi.Hfreebsd:
2280 osabi = elf.ELFOSABI_FREEBSD
2281 case objabi.Hnetbsd:
2282 osabi = elf.ELFOSABI_NETBSD
2283 case objabi.Hopenbsd:
2284 osabi = elf.ELFOSABI_OPENBSD
2285 case objabi.Hdragonfly:
2286 osabi = elf.ELFOSABI_NONE
2287 }
2288 eh.Ident[elf.EI_OSABI] = byte(osabi)
2289
2290 if elf64 {
2291 eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS64)
2292 } else {
2293 eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS32)
2294 }
2295 if ctxt.Arch.ByteOrder == binary.BigEndian {
2296 eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2MSB)
2297 } else {
2298 eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2LSB)
2299 }
2300 eh.Ident[elf.EI_VERSION] = byte(elf.EV_CURRENT)
2301
2302 if ctxt.LinkMode == LinkExternal {
2303 eh.Type = uint16(elf.ET_REL)
2304 } else if ctxt.BuildMode == BuildModePIE {
2305 eh.Type = uint16(elf.ET_DYN)
2306 } else {
2307 eh.Type = uint16(elf.ET_EXEC)
2308 }
2309
2310 if ctxt.LinkMode != LinkExternal {
2311 eh.Entry = uint64(Entryvalue(ctxt))
2312 }
2313
2314 eh.Version = uint32(elf.EV_CURRENT)
2315
2316 if pph != nil {
2317 pph.Filesz = uint64(eh.Phnum) * uint64(eh.Phentsize)
2318 pph.Memsz = pph.Filesz
2319 }
2320
2321 ctxt.Out.SeekSet(0)
2322 a := int64(0)
2323 a += int64(elfwritehdr(ctxt.Out))
2324 a += int64(elfwritephdrs(ctxt.Out))
2325 a += int64(elfwriteshdrs(ctxt.Out))
2326 if !*FlagD {
2327 a += int64(elfwriteinterp(ctxt.Out))
2328 }
2329 if ctxt.IsMIPS() {
2330 a += int64(elfWriteMipsAbiFlags(ctxt))
2331 }
2332
2333 if ctxt.LinkMode != LinkExternal {
2334 if ctxt.HeadType == objabi.Hnetbsd {
2335 a += int64(elfwritenetbsdsig(ctxt.Out))
2336 }
2337 if ctxt.HeadType == objabi.Hopenbsd {
2338 a += int64(elfwriteopenbsdsig(ctxt.Out))
2339 }
2340 if ctxt.HeadType == objabi.Hfreebsd {
2341 a += int64(elfwritefreebsdsig(ctxt.Out))
2342 }
2343 if len(buildinfo) > 0 {
2344 a += int64(elfwritebuildinfo(ctxt.Out))
2345 }
2346 if *flagBuildid != "" {
2347 a += int64(elfwritegobuildid(ctxt.Out))
2348 }
2349 }
2350 if *flagRace && ctxt.IsNetbsd() {
2351 a += int64(elfwritenetbsdpax(ctxt.Out))
2352 }
2353
2354 if a > elfreserve {
2355 Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
2356 }
2357
2358
2359
2360 if a > int64(HEADR) {
2361 Errorf(nil, "HEADR too small: %d > %d with %d text sections", a, HEADR, numtext)
2362 }
2363 }
2364
2365 func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
2366 ldr.SetSymDynid(s, int32(Nelfsym))
2367 Nelfsym++
2368 d := ldr.MakeSymbolUpdater(syms.DynSym)
2369 name := ldr.SymExtname(s)
2370 dstru := ldr.MakeSymbolUpdater(syms.DynStr)
2371 st := ldr.SymType(s)
2372 cgoeStatic := ldr.AttrCgoExportStatic(s)
2373 cgoeDynamic := ldr.AttrCgoExportDynamic(s)
2374 cgoexp := (cgoeStatic || cgoeDynamic)
2375
2376 d.AddUint32(target.Arch, uint32(dstru.Addstring(name)))
2377
2378 if elf64 {
2379
2380
2381 var t uint8
2382
2383 if cgoexp && st == sym.STEXT {
2384 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2385 } else {
2386 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT)
2387 }
2388 d.AddUint8(t)
2389
2390
2391 d.AddUint8(0)
2392
2393
2394 if st == sym.SDYNIMPORT {
2395 d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF))
2396 } else {
2397 d.AddUint16(target.Arch, 1)
2398 }
2399
2400
2401 if st == sym.SDYNIMPORT {
2402 d.AddUint64(target.Arch, 0)
2403 } else {
2404 d.AddAddrPlus(target.Arch, s, 0)
2405 }
2406
2407
2408 d.AddUint64(target.Arch, uint64(len(ldr.Data(s))))
2409
2410 dil := ldr.SymDynimplib(s)
2411
2412 if !cgoeDynamic && dil != "" && !seenlib[dil] {
2413 du := ldr.MakeSymbolUpdater(syms.Dynamic)
2414 Elfwritedynent(target.Arch, du, elf.DT_NEEDED, uint64(dstru.Addstring(dil)))
2415 seenlib[dil] = true
2416 }
2417 } else {
2418
2419
2420 if st == sym.SDYNIMPORT {
2421 d.AddUint32(target.Arch, 0)
2422 } else {
2423 d.AddAddrPlus(target.Arch, s, 0)
2424 }
2425
2426
2427 d.AddUint32(target.Arch, uint32(len(ldr.Data(s))))
2428
2429
2430 var t uint8
2431
2432
2433 if target.Arch.Family == sys.I386 && cgoexp && st == sym.STEXT {
2434 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2435 } else if target.Arch.Family == sys.ARM && cgoeDynamic && st == sym.STEXT {
2436 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2437 } else {
2438 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT)
2439 }
2440 d.AddUint8(t)
2441 d.AddUint8(0)
2442
2443
2444 if st == sym.SDYNIMPORT {
2445 d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF))
2446 } else {
2447 d.AddUint16(target.Arch, 1)
2448 }
2449 }
2450 }
2451
View as plain text