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
1060 var dtFlags1 elf.DynFlag1
1061 if *flagBindNow {
1062 dtFlags1 |= elf.DF_1_NOW
1063 Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS, uint64(elf.DF_BIND_NOW))
1064 }
1065 if ctxt.BuildMode == BuildModePIE {
1066 dtFlags1 |= elf.DF_1_PIE
1067 }
1068 Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS_1, uint64(dtFlags1))
1069
1070 elfverneed = nfile
1071 if elfverneed != 0 {
1072 elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym())
1073 Elfwritedynent(ctxt.Arch, s, elf.DT_VERNEEDNUM, uint64(nfile))
1074 elfWriteDynEntSym(ctxt, s, elf.DT_VERSYM, gnuVersion.Sym())
1075 }
1076
1077 sy := ldr.CreateSymForUpdate(elfRelType+".plt", 0)
1078 if sy.Size() > 0 {
1079 if elfRelType == ".rela" {
1080 Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_RELA))
1081 } else {
1082 Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_REL))
1083 }
1084 elfwritedynentsymsize(ctxt, s, elf.DT_PLTRELSZ, sy.Sym())
1085 elfWriteDynEntSym(ctxt, s, elf.DT_JMPREL, sy.Sym())
1086 }
1087
1088 Elfwritedynent(ctxt.Arch, s, elf.DT_NULL, 0)
1089 }
1090
1091 func elfphload(seg *sym.Segment) *ElfPhdr {
1092 ph := newElfPhdr()
1093 ph.Type = elf.PT_LOAD
1094 if seg.Rwx&4 != 0 {
1095 ph.Flags |= elf.PF_R
1096 }
1097 if seg.Rwx&2 != 0 {
1098 ph.Flags |= elf.PF_W
1099 }
1100 if seg.Rwx&1 != 0 {
1101 ph.Flags |= elf.PF_X
1102 }
1103 ph.Vaddr = seg.Vaddr
1104 ph.Paddr = seg.Vaddr
1105 ph.Memsz = seg.Length
1106 ph.Off = seg.Fileoff
1107 ph.Filesz = seg.Filelen
1108 ph.Align = uint64(*FlagRound)
1109
1110 return ph
1111 }
1112
1113 func elfphrelro(seg *sym.Segment) {
1114 ph := newElfPhdr()
1115 ph.Type = elf.PT_GNU_RELRO
1116 ph.Flags = elf.PF_R
1117 ph.Vaddr = seg.Vaddr
1118 ph.Paddr = seg.Vaddr
1119 ph.Memsz = seg.Length
1120 ph.Off = seg.Fileoff
1121 ph.Filesz = seg.Filelen
1122 ph.Align = uint64(*FlagRound)
1123 }
1124
1125 func elfshname(name string) *ElfShdr {
1126 for i := 0; i < nelfstr; i++ {
1127 if name != elfstr[i].s {
1128 continue
1129 }
1130 off := elfstr[i].off
1131 for i = 0; i < int(ehdr.Shnum); i++ {
1132 sh := shdr[i]
1133 if sh.Name == uint32(off) {
1134 return sh
1135 }
1136 }
1137 return newElfShdr(int64(off))
1138 }
1139 Exitf("cannot find elf name %s", name)
1140 return nil
1141 }
1142
1143
1144
1145 func elfshnamedup(name string) *ElfShdr {
1146 for i := 0; i < nelfstr; i++ {
1147 if name == elfstr[i].s {
1148 off := elfstr[i].off
1149 return newElfShdr(int64(off))
1150 }
1151 }
1152
1153 Errorf(nil, "cannot find elf name %s", name)
1154 errorexit()
1155 return nil
1156 }
1157
1158 func elfshalloc(sect *sym.Section) *ElfShdr {
1159 sh := elfshname(sect.Name)
1160 sect.Elfsect = sh
1161 return sh
1162 }
1163
1164 func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
1165 var sh *ElfShdr
1166
1167 if sect.Name == ".text" {
1168 if sect.Elfsect == nil {
1169 sect.Elfsect = elfshnamedup(sect.Name)
1170 }
1171 sh = sect.Elfsect.(*ElfShdr)
1172 } else {
1173 sh = elfshalloc(sect)
1174 }
1175
1176
1177
1178 if sh.Type == uint32(elf.SHT_NOTE) {
1179 if linkmode != LinkExternal {
1180
1181
1182
1183
1184
1185
1186
1187 Errorf(nil, "sh.Type == SHT_NOTE in elfshbits when linking internally")
1188 }
1189 sh.Addralign = uint64(sect.Align)
1190 sh.Size = sect.Length
1191 sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1192 return sh
1193 }
1194 if sh.Type > 0 {
1195 return sh
1196 }
1197
1198 if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
1199 switch sect.Name {
1200 case ".init_array":
1201 sh.Type = uint32(elf.SHT_INIT_ARRAY)
1202 default:
1203 sh.Type = uint32(elf.SHT_PROGBITS)
1204 }
1205 } else {
1206 sh.Type = uint32(elf.SHT_NOBITS)
1207 }
1208 sh.Flags = uint64(elf.SHF_ALLOC)
1209 if sect.Rwx&1 != 0 {
1210 sh.Flags |= uint64(elf.SHF_EXECINSTR)
1211 }
1212 if sect.Rwx&2 != 0 {
1213 sh.Flags |= uint64(elf.SHF_WRITE)
1214 }
1215 if sect.Name == ".tbss" {
1216 sh.Flags |= uint64(elf.SHF_TLS)
1217 sh.Type = uint32(elf.SHT_NOBITS)
1218 }
1219 if linkmode != LinkExternal {
1220 sh.Addr = sect.Vaddr
1221 }
1222
1223 if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
1224 sh.Flags = 0
1225 sh.Addr = 0
1226 if sect.Compressed {
1227 sh.Flags |= uint64(elf.SHF_COMPRESSED)
1228 }
1229 }
1230
1231 sh.Addralign = uint64(sect.Align)
1232 sh.Size = sect.Length
1233 if sect.Name != ".tbss" {
1234 sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1235 }
1236
1237 return sh
1238 }
1239
1240 func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
1241
1242
1243 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1244 return nil
1245 }
1246 if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
1247 return nil
1248 }
1249 if sect.Elfsect.(*ElfShdr).Type == uint32(elf.SHT_NOTE) {
1250 return nil
1251 }
1252
1253 typ := elf.SHT_REL
1254 if elfRelType == ".rela" {
1255 typ = elf.SHT_RELA
1256 }
1257
1258 sh := elfshname(elfRelType + sect.Name)
1259
1260
1261
1262 if sect.Name == ".text" {
1263 if sh.Info != 0 && sh.Info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
1264 sh = elfshnamedup(elfRelType + sect.Name)
1265 }
1266 }
1267
1268 sh.Type = uint32(typ)
1269 sh.Entsize = uint64(arch.RegSize) * 2
1270 if typ == elf.SHT_RELA {
1271 sh.Entsize += uint64(arch.RegSize)
1272 }
1273 sh.Link = uint32(elfshname(".symtab").shnum)
1274 sh.Info = uint32(sect.Elfsect.(*ElfShdr).shnum)
1275 sh.Off = sect.Reloff
1276 sh.Size = sect.Rellen
1277 sh.Addralign = uint64(arch.RegSize)
1278 return sh
1279 }
1280
1281 func elfrelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) {
1282
1283
1284 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1285 return
1286 }
1287 if sect.Name == ".shstrtab" {
1288 return
1289 }
1290
1291 ldr := ctxt.loader
1292 for i, s := range syms {
1293 if !ldr.AttrReachable(s) {
1294 panic("should never happen")
1295 }
1296 if uint64(ldr.SymValue(s)) >= sect.Vaddr {
1297 syms = syms[i:]
1298 break
1299 }
1300 }
1301
1302 eaddr := sect.Vaddr + sect.Length
1303 for _, s := range syms {
1304 if !ldr.AttrReachable(s) {
1305 continue
1306 }
1307 if ldr.SymValue(s) >= int64(eaddr) {
1308 break
1309 }
1310
1311
1312
1313 relocs := ldr.Relocs(s)
1314 for ri := 0; ri < relocs.Count(); ri++ {
1315 r := relocs.At(ri)
1316 rr, ok := extreloc(ctxt, ldr, s, r)
1317 if !ok {
1318 continue
1319 }
1320 if rr.Xsym == 0 {
1321 ldr.Errorf(s, "missing xsym in relocation")
1322 continue
1323 }
1324 esr := ElfSymForReloc(ctxt, rr.Xsym)
1325 if esr == 0 {
1326 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())
1327 }
1328 if !ldr.AttrReachable(rr.Xsym) {
1329 ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(rr.Xsym))
1330 }
1331 if !thearch.ELF.Reloc1(ctxt, out, ldr, s, rr, ri, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) {
1332 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()))
1333 }
1334 }
1335 }
1336
1337
1338 if uint64(out.Offset()) != sect.Reloff+sect.Rellen {
1339 panic(fmt.Sprintf("elfrelocsect: size mismatch %d != %d + %d", out.Offset(), sect.Reloff, sect.Rellen))
1340 }
1341 }
1342
1343 func elfEmitReloc(ctxt *Link) {
1344 for ctxt.Out.Offset()&7 != 0 {
1345 ctxt.Out.Write8(0)
1346 }
1347
1348 sizeExtRelocs(ctxt, thearch.ELF.RelocSize)
1349 relocSect, wg := relocSectFn(ctxt, elfrelocsect)
1350
1351 for _, sect := range Segtext.Sections {
1352 if sect.Name == ".text" {
1353 relocSect(ctxt, sect, ctxt.Textp)
1354 } else {
1355 relocSect(ctxt, sect, ctxt.datap)
1356 }
1357 }
1358
1359 for _, sect := range Segrodata.Sections {
1360 relocSect(ctxt, sect, ctxt.datap)
1361 }
1362 for _, sect := range Segrelrodata.Sections {
1363 relocSect(ctxt, sect, ctxt.datap)
1364 }
1365 for _, sect := range Segdata.Sections {
1366 relocSect(ctxt, sect, ctxt.datap)
1367 }
1368 for i := 0; i < len(Segdwarf.Sections); i++ {
1369 sect := Segdwarf.Sections[i]
1370 si := dwarfp[i]
1371 if si.secSym() != loader.Sym(sect.Sym) ||
1372 ctxt.loader.SymSect(si.secSym()) != sect {
1373 panic("inconsistency between dwarfp and Segdwarf")
1374 }
1375 relocSect(ctxt, sect, si.syms)
1376 }
1377 wg.Wait()
1378 }
1379
1380 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
1381 ldr := ctxt.loader
1382 s := ldr.CreateSymForUpdate(sectionName, 0)
1383 s.SetType(sym.SELFROSECT)
1384
1385 s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
1386
1387 s.AddUint32(ctxt.Arch, uint32(len(desc)))
1388
1389 s.AddUint32(ctxt.Arch, tag)
1390
1391 s.AddBytes(ELF_NOTE_GO_NAME)
1392 for len(s.Data())%4 != 0 {
1393 s.AddUint8(0)
1394 }
1395
1396 s.AddBytes(desc)
1397 for len(s.Data())%4 != 0 {
1398 s.AddUint8(0)
1399 }
1400 s.SetSize(int64(len(s.Data())))
1401 s.SetAlign(4)
1402 }
1403
1404 func (ctxt *Link) doelf() {
1405 ldr := ctxt.loader
1406
1407
1408
1409 addshstr := func(s string) int {
1410 off := len(elfshstrdat)
1411 elfshstrdat = append(elfshstrdat, s...)
1412 elfshstrdat = append(elfshstrdat, 0)
1413 return off
1414 }
1415
1416 shstrtabAddstring := func(s string) {
1417 off := addshstr(s)
1418 elfsetstring(ctxt, 0, s, int(off))
1419 }
1420
1421 shstrtabAddstring("")
1422 shstrtabAddstring(".text")
1423 shstrtabAddstring(".noptrdata")
1424 shstrtabAddstring(".data")
1425 shstrtabAddstring(".bss")
1426 shstrtabAddstring(".noptrbss")
1427 shstrtabAddstring(".go.fuzzcntrs")
1428 shstrtabAddstring(".go.buildinfo")
1429 if ctxt.IsMIPS() {
1430 shstrtabAddstring(".MIPS.abiflags")
1431 shstrtabAddstring(".gnu.attributes")
1432 }
1433
1434
1435
1436
1437 if !*FlagD || ctxt.IsExternal() {
1438 shstrtabAddstring(".tbss")
1439 }
1440 if ctxt.IsNetbsd() {
1441 shstrtabAddstring(".note.netbsd.ident")
1442 if *flagRace {
1443 shstrtabAddstring(".note.netbsd.pax")
1444 }
1445 }
1446 if ctxt.IsOpenbsd() {
1447 shstrtabAddstring(".note.openbsd.ident")
1448 }
1449 if ctxt.IsFreebsd() {
1450 shstrtabAddstring(".note.tag")
1451 }
1452 if len(buildinfo) > 0 {
1453 shstrtabAddstring(".note.gnu.build-id")
1454 }
1455 if *flagBuildid != "" {
1456 shstrtabAddstring(".note.go.buildid")
1457 }
1458 shstrtabAddstring(".elfdata")
1459 shstrtabAddstring(".rodata")
1460
1461 relro_prefix := ""
1462 if ctxt.UseRelro() {
1463 shstrtabAddstring(".data.rel.ro")
1464 relro_prefix = ".data.rel.ro"
1465 }
1466 shstrtabAddstring(relro_prefix + ".typelink")
1467 shstrtabAddstring(relro_prefix + ".itablink")
1468 shstrtabAddstring(relro_prefix + ".gosymtab")
1469 shstrtabAddstring(relro_prefix + ".gopclntab")
1470
1471 if ctxt.IsExternal() {
1472 *FlagD = true
1473
1474 shstrtabAddstring(elfRelType + ".text")
1475 shstrtabAddstring(elfRelType + ".rodata")
1476 shstrtabAddstring(elfRelType + relro_prefix + ".typelink")
1477 shstrtabAddstring(elfRelType + relro_prefix + ".itablink")
1478 shstrtabAddstring(elfRelType + relro_prefix + ".gosymtab")
1479 shstrtabAddstring(elfRelType + relro_prefix + ".gopclntab")
1480 shstrtabAddstring(elfRelType + ".noptrdata")
1481 shstrtabAddstring(elfRelType + ".data")
1482 if ctxt.UseRelro() {
1483 shstrtabAddstring(elfRelType + ".data.rel.ro")
1484 }
1485 shstrtabAddstring(elfRelType + ".go.buildinfo")
1486 if ctxt.IsMIPS() {
1487 shstrtabAddstring(elfRelType + ".MIPS.abiflags")
1488 shstrtabAddstring(elfRelType + ".gnu.attributes")
1489 }
1490
1491
1492 shstrtabAddstring(".note.GNU-stack")
1493
1494 if ctxt.IsShared() {
1495 shstrtabAddstring(".note.go.abihash")
1496 shstrtabAddstring(".note.go.pkg-list")
1497 shstrtabAddstring(".note.go.deps")
1498 }
1499 }
1500
1501 hasinitarr := ctxt.linkShared
1502
1503
1504 switch ctxt.BuildMode {
1505 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
1506 hasinitarr = true
1507 }
1508
1509 if hasinitarr {
1510 shstrtabAddstring(".init_array")
1511 shstrtabAddstring(elfRelType + ".init_array")
1512 }
1513
1514 if !*FlagS {
1515 shstrtabAddstring(".symtab")
1516 shstrtabAddstring(".strtab")
1517 }
1518 if !*FlagW {
1519 dwarfaddshstrings(ctxt, shstrtabAddstring)
1520 }
1521
1522 shstrtabAddstring(".shstrtab")
1523
1524 if !*FlagD {
1525 shstrtabAddstring(".interp")
1526 shstrtabAddstring(".hash")
1527 shstrtabAddstring(".got")
1528 if ctxt.IsPPC64() {
1529 shstrtabAddstring(".glink")
1530 }
1531 shstrtabAddstring(".got.plt")
1532 shstrtabAddstring(".dynamic")
1533 shstrtabAddstring(".dynsym")
1534 shstrtabAddstring(".dynstr")
1535 shstrtabAddstring(elfRelType)
1536 shstrtabAddstring(elfRelType + ".plt")
1537
1538 shstrtabAddstring(".plt")
1539 shstrtabAddstring(".gnu.version")
1540 shstrtabAddstring(".gnu.version_r")
1541
1542
1543 dynsym := ldr.CreateSymForUpdate(".dynsym", 0)
1544
1545 dynsym.SetType(sym.SELFROSECT)
1546 if elf64 {
1547 dynsym.SetSize(dynsym.Size() + ELF64SYMSIZE)
1548 } else {
1549 dynsym.SetSize(dynsym.Size() + ELF32SYMSIZE)
1550 }
1551
1552
1553 dynstr := ldr.CreateSymForUpdate(".dynstr", 0)
1554
1555 dynstr.SetType(sym.SELFROSECT)
1556 if dynstr.Size() == 0 {
1557 dynstr.Addstring("")
1558 }
1559
1560
1561 s := ldr.CreateSymForUpdate(elfRelType, 0)
1562 s.SetType(sym.SELFROSECT)
1563
1564
1565 got := ldr.CreateSymForUpdate(".got", 0)
1566 if ctxt.UseRelro() {
1567 got.SetType(sym.SELFRELROSECT)
1568 } else {
1569 got.SetType(sym.SELFGOT)
1570 }
1571
1572
1573 if ctxt.IsPPC64() {
1574 s := ldr.CreateSymForUpdate(".glink", 0)
1575 s.SetType(sym.SELFRXSECT)
1576 }
1577
1578
1579 hash := ldr.CreateSymForUpdate(".hash", 0)
1580 hash.SetType(sym.SELFROSECT)
1581
1582 gotplt := ldr.CreateSymForUpdate(".got.plt", 0)
1583 if ctxt.UseRelro() && *flagBindNow {
1584 gotplt.SetType(sym.SELFRELROSECT)
1585 } else {
1586 gotplt.SetType(sym.SELFSECT)
1587 }
1588
1589 plt := ldr.CreateSymForUpdate(".plt", 0)
1590 if ctxt.IsPPC64() {
1591
1592
1593 plt.SetType(sym.SELFSECT)
1594 } else {
1595 plt.SetType(sym.SELFRXSECT)
1596 }
1597
1598 s = ldr.CreateSymForUpdate(elfRelType+".plt", 0)
1599 s.SetType(sym.SELFROSECT)
1600
1601 s = ldr.CreateSymForUpdate(".gnu.version", 0)
1602 s.SetType(sym.SELFROSECT)
1603
1604 s = ldr.CreateSymForUpdate(".gnu.version_r", 0)
1605 s.SetType(sym.SELFROSECT)
1606
1607
1608 dynamic := ldr.CreateSymForUpdate(".dynamic", 0)
1609 switch {
1610 case thearch.ELF.DynamicReadOnly:
1611 dynamic.SetType(sym.SELFROSECT)
1612 case ctxt.UseRelro():
1613 dynamic.SetType(sym.SELFRELROSECT)
1614 default:
1615 dynamic.SetType(sym.SELFSECT)
1616 }
1617
1618 if ctxt.IsS390X() {
1619
1620 gotplt = got
1621 }
1622 thearch.ELF.SetupPLT(ctxt, ctxt.loader, plt, gotplt, dynamic.Sym())
1623
1624
1627 elfWriteDynEntSym(ctxt, dynamic, elf.DT_HASH, hash.Sym())
1628
1629 elfWriteDynEntSym(ctxt, dynamic, elf.DT_SYMTAB, dynsym.Sym())
1630 if elf64 {
1631 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF64SYMSIZE)
1632 } else {
1633 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF32SYMSIZE)
1634 }
1635 elfWriteDynEntSym(ctxt, dynamic, elf.DT_STRTAB, dynstr.Sym())
1636 elfwritedynentsymsize(ctxt, dynamic, elf.DT_STRSZ, dynstr.Sym())
1637 if elfRelType == ".rela" {
1638 rela := ldr.LookupOrCreateSym(".rela", 0)
1639 elfWriteDynEntSym(ctxt, dynamic, elf.DT_RELA, rela)
1640 elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELASZ, rela)
1641 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELAENT, ELF64RELASIZE)
1642 } else {
1643 rel := ldr.LookupOrCreateSym(".rel", 0)
1644 elfWriteDynEntSym(ctxt, dynamic, elf.DT_REL, rel)
1645 elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELSZ, rel)
1646 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELENT, ELF32RELSIZE)
1647 }
1648
1649 if rpath.val != "" {
1650 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
1651 }
1652
1653 if ctxt.IsPPC64() {
1654 elfWriteDynEntSym(ctxt, dynamic, elf.DT_PLTGOT, plt.Sym())
1655 } else {
1656 elfWriteDynEntSym(ctxt, dynamic, elf.DT_PLTGOT, gotplt.Sym())
1657 }
1658
1659 if ctxt.IsPPC64() {
1660 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_PPC64_OPT, 0)
1661 }
1662
1663
1664
1665
1666
1667
1668 Elfwritedynent(ctxt.Arch, dynamic, elf.DT_DEBUG, 0)
1669 }
1670
1671 if ctxt.IsShared() {
1672
1673
1674 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
1675 sb := ldr.MakeSymbolUpdater(s)
1676 ldr.SetAttrLocal(s, true)
1677 sb.SetType(sym.SRODATA)
1678 ldr.SetAttrSpecial(s, true)
1679 sb.SetReachable(true)
1680 sb.SetSize(notsha256.Size)
1681
1682 sort.Sort(byPkg(ctxt.Library))
1683 h := notsha256.New()
1684 for _, l := range ctxt.Library {
1685 h.Write(l.Fingerprint[:])
1686 }
1687 addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
1688 addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
1689 var deplist []string
1690 for _, shlib := range ctxt.Shlibs {
1691 deplist = append(deplist, filepath.Base(shlib.Path))
1692 }
1693 addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
1694 }
1695
1696 if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
1697 addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
1698 }
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709 if ctxt.IsMIPS() {
1710 gnuattributes := ldr.CreateSymForUpdate(".gnu.attributes", 0)
1711 gnuattributes.SetType(sym.SELFROSECT)
1712 gnuattributes.SetReachable(true)
1713 gnuattributes.AddUint8('A')
1714 gnuattributes.AddUint32(ctxt.Arch, 15)
1715 gnuattributes.AddBytes([]byte("gnu\x00"))
1716 gnuattributes.AddUint8(1)
1717 gnuattributes.AddUint32(ctxt.Arch, 7)
1718 gnuattributes.AddUint8(4)
1719 if buildcfg.GOMIPS == "softfloat" {
1720 gnuattributes.AddUint8(MIPS_FPABI_SOFT)
1721 } else {
1722
1723
1724
1725 gnuattributes.AddUint8(MIPS_FPABI_ANY)
1726 }
1727 }
1728 }
1729
1730
1731 func shsym(sh *ElfShdr, ldr *loader.Loader, s loader.Sym) {
1732 if s == 0 {
1733 panic("bad symbol in shsym2")
1734 }
1735 addr := ldr.SymValue(s)
1736 if sh.Flags&uint64(elf.SHF_ALLOC) != 0 {
1737 sh.Addr = uint64(addr)
1738 }
1739 sh.Off = uint64(datoff(ldr, s, addr))
1740 sh.Size = uint64(ldr.SymSize(s))
1741 }
1742
1743 func phsh(ph *ElfPhdr, sh *ElfShdr) {
1744 ph.Vaddr = sh.Addr
1745 ph.Paddr = ph.Vaddr
1746 ph.Off = sh.Off
1747 ph.Filesz = sh.Size
1748 ph.Memsz = sh.Size
1749 ph.Align = sh.Addralign
1750 }
1751
1752 func Asmbelfsetup() {
1753
1754 elfshname("")
1755
1756 for _, sect := range Segtext.Sections {
1757
1758
1759 if sect.Name == ".text" {
1760 if sect.Elfsect == nil {
1761 sect.Elfsect = elfshnamedup(sect.Name)
1762 }
1763 } else {
1764 elfshalloc(sect)
1765 }
1766 }
1767 for _, sect := range Segrodata.Sections {
1768 elfshalloc(sect)
1769 }
1770 for _, sect := range Segrelrodata.Sections {
1771 elfshalloc(sect)
1772 }
1773 for _, sect := range Segdata.Sections {
1774 elfshalloc(sect)
1775 }
1776 for _, sect := range Segdwarf.Sections {
1777 elfshalloc(sect)
1778 }
1779 }
1780
1781 func asmbElf(ctxt *Link) {
1782 var symo int64
1783 symo = int64(Segdwarf.Fileoff + Segdwarf.Filelen)
1784 symo = Rnd(symo, int64(ctxt.Arch.PtrSize))
1785 ctxt.Out.SeekSet(symo)
1786 if *FlagS {
1787 ctxt.Out.Write(elfshstrdat)
1788 } else {
1789 ctxt.Out.SeekSet(symo)
1790 asmElfSym(ctxt)
1791 ctxt.Out.Write(elfstrdat)
1792 ctxt.Out.Write(elfshstrdat)
1793 if ctxt.IsExternal() {
1794 elfEmitReloc(ctxt)
1795 }
1796 }
1797 ctxt.Out.SeekSet(0)
1798
1799 ldr := ctxt.loader
1800 eh := getElfEhdr()
1801 switch ctxt.Arch.Family {
1802 default:
1803 Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
1804 case sys.MIPS, sys.MIPS64:
1805 eh.Machine = uint16(elf.EM_MIPS)
1806 case sys.Loong64:
1807 eh.Machine = uint16(elf.EM_LOONGARCH)
1808 case sys.ARM:
1809 eh.Machine = uint16(elf.EM_ARM)
1810 case sys.AMD64:
1811 eh.Machine = uint16(elf.EM_X86_64)
1812 case sys.ARM64:
1813 eh.Machine = uint16(elf.EM_AARCH64)
1814 case sys.I386:
1815 eh.Machine = uint16(elf.EM_386)
1816 case sys.PPC64:
1817 eh.Machine = uint16(elf.EM_PPC64)
1818 case sys.RISCV64:
1819 eh.Machine = uint16(elf.EM_RISCV)
1820 case sys.S390X:
1821 eh.Machine = uint16(elf.EM_S390)
1822 }
1823
1824 elfreserve := int64(ELFRESERVE)
1825
1826 numtext := int64(0)
1827 for _, sect := range Segtext.Sections {
1828 if sect.Name == ".text" {
1829 numtext++
1830 }
1831 }
1832
1833
1834
1835
1836
1837
1838 if numtext > 4 {
1839 elfreserve += elfreserve + numtext*64*2
1840 }
1841
1842 startva := *FlagTextAddr - int64(HEADR)
1843 resoff := elfreserve
1844
1845 var pph *ElfPhdr
1846 var pnote *ElfPhdr
1847 getpnote := func() *ElfPhdr {
1848 if pnote == nil {
1849 pnote = newElfPhdr()
1850 pnote.Type = elf.PT_NOTE
1851 pnote.Flags = elf.PF_R
1852 }
1853 return pnote
1854 }
1855 if *flagRace && ctxt.IsNetbsd() {
1856 sh := elfshname(".note.netbsd.pax")
1857 resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff)))
1858 phsh(getpnote(), sh)
1859 }
1860 if ctxt.LinkMode == LinkExternal {
1861
1862 eh.Phoff = 0
1863
1864 eh.Phentsize = 0
1865
1866 if ctxt.BuildMode == BuildModeShared {
1867 sh := elfshname(".note.go.pkg-list")
1868 sh.Type = uint32(elf.SHT_NOTE)
1869 sh = elfshname(".note.go.abihash")
1870 sh.Type = uint32(elf.SHT_NOTE)
1871 sh.Flags = uint64(elf.SHF_ALLOC)
1872 sh = elfshname(".note.go.deps")
1873 sh.Type = uint32(elf.SHT_NOTE)
1874 }
1875
1876 if *flagBuildid != "" {
1877 sh := elfshname(".note.go.buildid")
1878 sh.Type = uint32(elf.SHT_NOTE)
1879 sh.Flags = uint64(elf.SHF_ALLOC)
1880 }
1881
1882 goto elfobj
1883 }
1884
1885
1886 pph = newElfPhdr()
1887
1888 pph.Type = elf.PT_PHDR
1889 pph.Flags = elf.PF_R
1890 pph.Off = uint64(eh.Ehsize)
1891 pph.Vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off
1892 pph.Paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off
1893 pph.Align = uint64(*FlagRound)
1894
1895
1899 {
1900 o := int64(Segtext.Vaddr - pph.Vaddr)
1901 Segtext.Vaddr -= uint64(o)
1902 Segtext.Length += uint64(o)
1903 o = int64(Segtext.Fileoff - pph.Off)
1904 Segtext.Fileoff -= uint64(o)
1905 Segtext.Filelen += uint64(o)
1906 }
1907
1908 if !*FlagD {
1909
1910 sh := elfshname(".interp")
1911
1912 sh.Type = uint32(elf.SHT_PROGBITS)
1913 sh.Flags = uint64(elf.SHF_ALLOC)
1914 sh.Addralign = 1
1915
1916 if interpreter == "" && buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH && buildcfg.GO_LDSO != "" {
1917 interpreter = buildcfg.GO_LDSO
1918 }
1919
1920 if interpreter == "" {
1921 switch ctxt.HeadType {
1922 case objabi.Hlinux:
1923 if buildcfg.GOOS == "android" {
1924 interpreter = thearch.ELF.Androiddynld
1925 if interpreter == "" {
1926 Exitf("ELF interpreter not set")
1927 }
1928 } else {
1929 interpreter = thearch.ELF.Linuxdynld
1930
1931
1932
1933 if _, err := os.Stat(interpreter); err != nil {
1934 if musl := thearch.ELF.LinuxdynldMusl; musl != "" {
1935 if _, err := os.Stat(musl); err == nil {
1936 interpreter = musl
1937 }
1938 }
1939 }
1940 }
1941
1942 case objabi.Hfreebsd:
1943 interpreter = thearch.ELF.Freebsddynld
1944
1945 case objabi.Hnetbsd:
1946 interpreter = thearch.ELF.Netbsddynld
1947
1948 case objabi.Hopenbsd:
1949 interpreter = thearch.ELF.Openbsddynld
1950
1951 case objabi.Hdragonfly:
1952 interpreter = thearch.ELF.Dragonflydynld
1953
1954 case objabi.Hsolaris:
1955 interpreter = thearch.ELF.Solarisdynld
1956 }
1957 }
1958
1959 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
1960
1961 ph := newElfPhdr()
1962 ph.Type = elf.PT_INTERP
1963 ph.Flags = elf.PF_R
1964 phsh(ph, sh)
1965 }
1966
1967 if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd || ctxt.HeadType == objabi.Hfreebsd {
1968 var sh *ElfShdr
1969 switch ctxt.HeadType {
1970 case objabi.Hnetbsd:
1971 sh = elfshname(".note.netbsd.ident")
1972 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
1973
1974 case objabi.Hopenbsd:
1975 sh = elfshname(".note.openbsd.ident")
1976 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
1977
1978 case objabi.Hfreebsd:
1979 sh = elfshname(".note.tag")
1980 resoff -= int64(elffreebsdsig(sh, uint64(startva), uint64(resoff)))
1981 }
1982
1983 pnotei := newElfPhdr()
1984 pnotei.Type = elf.PT_NOTE
1985 pnotei.Flags = elf.PF_R
1986 phsh(pnotei, sh)
1987 }
1988
1989 if len(buildinfo) > 0 {
1990 sh := elfshname(".note.gnu.build-id")
1991 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
1992 phsh(getpnote(), sh)
1993 }
1994
1995 if *flagBuildid != "" {
1996 sh := elfshname(".note.go.buildid")
1997 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
1998 phsh(getpnote(), sh)
1999 }
2000
2001
2002
2003 elfphload(&Segtext)
2004 if len(Segrodata.Sections) > 0 {
2005 elfphload(&Segrodata)
2006 }
2007 if len(Segrelrodata.Sections) > 0 {
2008 elfphload(&Segrelrodata)
2009 elfphrelro(&Segrelrodata)
2010 }
2011 elfphload(&Segdata)
2012
2013
2014 if !*FlagD {
2015 sh := elfshname(".dynsym")
2016 sh.Type = uint32(elf.SHT_DYNSYM)
2017 sh.Flags = uint64(elf.SHF_ALLOC)
2018 if elf64 {
2019 sh.Entsize = ELF64SYMSIZE
2020 } else {
2021 sh.Entsize = ELF32SYMSIZE
2022 }
2023 sh.Addralign = uint64(ctxt.Arch.RegSize)
2024 sh.Link = uint32(elfshname(".dynstr").shnum)
2025
2026
2027 s := ldr.Lookup(".dynsym", 0)
2028 i := uint32(0)
2029 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2030 i++
2031 if !ldr.AttrLocal(sub) {
2032 break
2033 }
2034 }
2035 sh.Info = i
2036 shsym(sh, ldr, s)
2037
2038 sh = elfshname(".dynstr")
2039 sh.Type = uint32(elf.SHT_STRTAB)
2040 sh.Flags = uint64(elf.SHF_ALLOC)
2041 sh.Addralign = 1
2042 shsym(sh, ldr, ldr.Lookup(".dynstr", 0))
2043
2044 if elfverneed != 0 {
2045 sh := elfshname(".gnu.version")
2046 sh.Type = uint32(elf.SHT_GNU_VERSYM)
2047 sh.Flags = uint64(elf.SHF_ALLOC)
2048 sh.Addralign = 2
2049 sh.Link = uint32(elfshname(".dynsym").shnum)
2050 sh.Entsize = 2
2051 shsym(sh, ldr, ldr.Lookup(".gnu.version", 0))
2052
2053 sh = elfshname(".gnu.version_r")
2054 sh.Type = uint32(elf.SHT_GNU_VERNEED)
2055 sh.Flags = uint64(elf.SHF_ALLOC)
2056 sh.Addralign = uint64(ctxt.Arch.RegSize)
2057 sh.Info = uint32(elfverneed)
2058 sh.Link = uint32(elfshname(".dynstr").shnum)
2059 shsym(sh, ldr, ldr.Lookup(".gnu.version_r", 0))
2060 }
2061
2062 if elfRelType == ".rela" {
2063 sh := elfshname(".rela.plt")
2064 sh.Type = uint32(elf.SHT_RELA)
2065 sh.Flags = uint64(elf.SHF_ALLOC)
2066 sh.Entsize = ELF64RELASIZE
2067 sh.Addralign = uint64(ctxt.Arch.RegSize)
2068 sh.Link = uint32(elfshname(".dynsym").shnum)
2069 sh.Info = uint32(elfshname(".plt").shnum)
2070 shsym(sh, ldr, ldr.Lookup(".rela.plt", 0))
2071
2072 sh = elfshname(".rela")
2073 sh.Type = uint32(elf.SHT_RELA)
2074 sh.Flags = uint64(elf.SHF_ALLOC)
2075 sh.Entsize = ELF64RELASIZE
2076 sh.Addralign = 8
2077 sh.Link = uint32(elfshname(".dynsym").shnum)
2078 shsym(sh, ldr, ldr.Lookup(".rela", 0))
2079 } else {
2080 sh := elfshname(".rel.plt")
2081 sh.Type = uint32(elf.SHT_REL)
2082 sh.Flags = uint64(elf.SHF_ALLOC)
2083 sh.Entsize = ELF32RELSIZE
2084 sh.Addralign = 4
2085 sh.Link = uint32(elfshname(".dynsym").shnum)
2086 shsym(sh, ldr, ldr.Lookup(".rel.plt", 0))
2087
2088 sh = elfshname(".rel")
2089 sh.Type = uint32(elf.SHT_REL)
2090 sh.Flags = uint64(elf.SHF_ALLOC)
2091 sh.Entsize = ELF32RELSIZE
2092 sh.Addralign = 4
2093 sh.Link = uint32(elfshname(".dynsym").shnum)
2094 shsym(sh, ldr, ldr.Lookup(".rel", 0))
2095 }
2096
2097 if elf.Machine(eh.Machine) == elf.EM_PPC64 {
2098 sh := elfshname(".glink")
2099 sh.Type = uint32(elf.SHT_PROGBITS)
2100 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR)
2101 sh.Addralign = 4
2102 shsym(sh, ldr, ldr.Lookup(".glink", 0))
2103 }
2104
2105 sh = elfshname(".plt")
2106 sh.Type = uint32(elf.SHT_PROGBITS)
2107 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR)
2108 if elf.Machine(eh.Machine) == elf.EM_X86_64 {
2109 sh.Entsize = 16
2110 } else if elf.Machine(eh.Machine) == elf.EM_S390 {
2111 sh.Entsize = 32
2112 } else if elf.Machine(eh.Machine) == elf.EM_PPC64 {
2113
2114
2115 sh.Type = uint32(elf.SHT_NOBITS)
2116
2117 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2118 sh.Entsize = 8
2119 } else {
2120 sh.Entsize = 4
2121 }
2122 sh.Addralign = sh.Entsize
2123 shsym(sh, ldr, ldr.Lookup(".plt", 0))
2124
2125
2126
2127 if elf.Machine(eh.Machine) != elf.EM_PPC64 {
2128 sh := elfshname(".got")
2129 sh.Type = uint32(elf.SHT_PROGBITS)
2130 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2131 sh.Entsize = uint64(ctxt.Arch.RegSize)
2132 sh.Addralign = uint64(ctxt.Arch.RegSize)
2133 shsym(sh, ldr, ldr.Lookup(".got", 0))
2134
2135 sh = elfshname(".got.plt")
2136 sh.Type = uint32(elf.SHT_PROGBITS)
2137 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2138 sh.Entsize = uint64(ctxt.Arch.RegSize)
2139 sh.Addralign = uint64(ctxt.Arch.RegSize)
2140 shsym(sh, ldr, ldr.Lookup(".got.plt", 0))
2141 }
2142
2143 sh = elfshname(".hash")
2144 sh.Type = uint32(elf.SHT_HASH)
2145 sh.Flags = uint64(elf.SHF_ALLOC)
2146 sh.Entsize = 4
2147 sh.Addralign = uint64(ctxt.Arch.RegSize)
2148 sh.Link = uint32(elfshname(".dynsym").shnum)
2149 shsym(sh, ldr, ldr.Lookup(".hash", 0))
2150
2151
2152 sh = elfshname(".dynamic")
2153
2154 sh.Type = uint32(elf.SHT_DYNAMIC)
2155 sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE)
2156 sh.Entsize = 2 * uint64(ctxt.Arch.RegSize)
2157 sh.Addralign = uint64(ctxt.Arch.RegSize)
2158 sh.Link = uint32(elfshname(".dynstr").shnum)
2159 shsym(sh, ldr, ldr.Lookup(".dynamic", 0))
2160 ph := newElfPhdr()
2161 ph.Type = elf.PT_DYNAMIC
2162 ph.Flags = elf.PF_R + elf.PF_W
2163 phsh(ph, sh)
2164
2165
2168 tlssize := uint64(0)
2169 for _, sect := range Segdata.Sections {
2170 if sect.Name == ".tbss" {
2171 tlssize = sect.Length
2172 }
2173 }
2174 if tlssize != 0 {
2175 ph := newElfPhdr()
2176 ph.Type = elf.PT_TLS
2177 ph.Flags = elf.PF_R
2178 ph.Memsz = tlssize
2179 ph.Align = uint64(ctxt.Arch.RegSize)
2180 }
2181 }
2182
2183 if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd {
2184 ph := newElfPhdr()
2185 ph.Type = elf.PT_GNU_STACK
2186 ph.Flags = elf.PF_W + elf.PF_R
2187 ph.Align = uint64(ctxt.Arch.RegSize)
2188 } else if ctxt.HeadType == objabi.Hopenbsd {
2189 ph := newElfPhdr()
2190 ph.Type = elf.PT_OPENBSD_NOBTCFI
2191 ph.Flags = elf.PF_X
2192 } else if ctxt.HeadType == objabi.Hsolaris {
2193 ph := newElfPhdr()
2194 ph.Type = elf.PT_SUNWSTACK
2195 ph.Flags = elf.PF_W + elf.PF_R
2196 }
2197
2198 elfobj:
2199 sh := elfshname(".shstrtab")
2200 eh.Shstrndx = uint16(sh.shnum)
2201
2202 if ctxt.IsMIPS() {
2203 sh = elfshname(".MIPS.abiflags")
2204 sh.Type = uint32(elf.SHT_MIPS_ABIFLAGS)
2205 sh.Flags = uint64(elf.SHF_ALLOC)
2206 sh.Addralign = 8
2207 resoff -= int64(elfMipsAbiFlags(sh, uint64(startva), uint64(resoff)))
2208
2209 ph := newElfPhdr()
2210 ph.Type = elf.PT_MIPS_ABIFLAGS
2211 ph.Flags = elf.PF_R
2212 phsh(ph, sh)
2213
2214 sh = elfshname(".gnu.attributes")
2215 sh.Type = uint32(elf.SHT_GNU_ATTRIBUTES)
2216 sh.Addralign = 1
2217 ldr := ctxt.loader
2218 shsym(sh, ldr, ldr.Lookup(".gnu.attributes", 0))
2219 }
2220
2221
2222 if !*FlagS {
2223 elfshname(".symtab")
2224 elfshname(".strtab")
2225 }
2226 elfshname(".shstrtab")
2227
2228 for _, sect := range Segtext.Sections {
2229 elfshbits(ctxt.LinkMode, sect)
2230 }
2231 for _, sect := range Segrodata.Sections {
2232 elfshbits(ctxt.LinkMode, sect)
2233 }
2234 for _, sect := range Segrelrodata.Sections {
2235 elfshbits(ctxt.LinkMode, sect)
2236 }
2237 for _, sect := range Segdata.Sections {
2238 elfshbits(ctxt.LinkMode, sect)
2239 }
2240 for _, sect := range Segdwarf.Sections {
2241 elfshbits(ctxt.LinkMode, sect)
2242 }
2243
2244 if ctxt.LinkMode == LinkExternal {
2245 for _, sect := range Segtext.Sections {
2246 elfshreloc(ctxt.Arch, sect)
2247 }
2248 for _, sect := range Segrodata.Sections {
2249 elfshreloc(ctxt.Arch, sect)
2250 }
2251 for _, sect := range Segrelrodata.Sections {
2252 elfshreloc(ctxt.Arch, sect)
2253 }
2254 for _, sect := range Segdata.Sections {
2255 elfshreloc(ctxt.Arch, sect)
2256 }
2257 for _, si := range dwarfp {
2258 sect := ldr.SymSect(si.secSym())
2259 elfshreloc(ctxt.Arch, sect)
2260 }
2261
2262 sh := elfshname(".note.GNU-stack")
2263
2264 sh.Type = uint32(elf.SHT_PROGBITS)
2265 sh.Addralign = 1
2266 sh.Flags = 0
2267 }
2268
2269 var shstroff uint64
2270 if !*FlagS {
2271 sh := elfshname(".symtab")
2272 sh.Type = uint32(elf.SHT_SYMTAB)
2273 sh.Off = uint64(symo)
2274 sh.Size = uint64(symSize)
2275 sh.Addralign = uint64(ctxt.Arch.RegSize)
2276 sh.Entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
2277 sh.Link = uint32(elfshname(".strtab").shnum)
2278 sh.Info = uint32(elfglobalsymndx)
2279
2280 sh = elfshname(".strtab")
2281 sh.Type = uint32(elf.SHT_STRTAB)
2282 sh.Off = uint64(symo) + uint64(symSize)
2283 sh.Size = uint64(len(elfstrdat))
2284 sh.Addralign = 1
2285 shstroff = sh.Off + sh.Size
2286 } else {
2287 shstroff = uint64(symo)
2288 }
2289
2290 sh = elfshname(".shstrtab")
2291 sh.Type = uint32(elf.SHT_STRTAB)
2292 sh.Off = shstroff
2293 sh.Size = uint64(len(elfshstrdat))
2294 sh.Addralign = 1
2295
2296
2297 copy(eh.Ident[:], elf.ELFMAG)
2298
2299 var osabi elf.OSABI
2300 switch ctxt.HeadType {
2301 case objabi.Hfreebsd:
2302 osabi = elf.ELFOSABI_FREEBSD
2303 case objabi.Hnetbsd:
2304 osabi = elf.ELFOSABI_NETBSD
2305 case objabi.Hopenbsd:
2306 osabi = elf.ELFOSABI_OPENBSD
2307 case objabi.Hdragonfly:
2308 osabi = elf.ELFOSABI_NONE
2309 }
2310 eh.Ident[elf.EI_OSABI] = byte(osabi)
2311
2312 if elf64 {
2313 eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS64)
2314 } else {
2315 eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS32)
2316 }
2317 if ctxt.Arch.ByteOrder == binary.BigEndian {
2318 eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2MSB)
2319 } else {
2320 eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2LSB)
2321 }
2322 eh.Ident[elf.EI_VERSION] = byte(elf.EV_CURRENT)
2323
2324 if ctxt.LinkMode == LinkExternal {
2325 eh.Type = uint16(elf.ET_REL)
2326 } else if ctxt.BuildMode == BuildModePIE {
2327 eh.Type = uint16(elf.ET_DYN)
2328 } else {
2329 eh.Type = uint16(elf.ET_EXEC)
2330 }
2331
2332 if ctxt.LinkMode != LinkExternal {
2333 eh.Entry = uint64(Entryvalue(ctxt))
2334 }
2335
2336 eh.Version = uint32(elf.EV_CURRENT)
2337
2338 if pph != nil {
2339 pph.Filesz = uint64(eh.Phnum) * uint64(eh.Phentsize)
2340 pph.Memsz = pph.Filesz
2341 }
2342
2343 ctxt.Out.SeekSet(0)
2344 a := int64(0)
2345 a += int64(elfwritehdr(ctxt.Out))
2346 a += int64(elfwritephdrs(ctxt.Out))
2347 a += int64(elfwriteshdrs(ctxt.Out))
2348 if !*FlagD {
2349 a += int64(elfwriteinterp(ctxt.Out))
2350 }
2351 if ctxt.IsMIPS() {
2352 a += int64(elfWriteMipsAbiFlags(ctxt))
2353 }
2354
2355 if ctxt.LinkMode != LinkExternal {
2356 if ctxt.HeadType == objabi.Hnetbsd {
2357 a += int64(elfwritenetbsdsig(ctxt.Out))
2358 }
2359 if ctxt.HeadType == objabi.Hopenbsd {
2360 a += int64(elfwriteopenbsdsig(ctxt.Out))
2361 }
2362 if ctxt.HeadType == objabi.Hfreebsd {
2363 a += int64(elfwritefreebsdsig(ctxt.Out))
2364 }
2365 if len(buildinfo) > 0 {
2366 a += int64(elfwritebuildinfo(ctxt.Out))
2367 }
2368 if *flagBuildid != "" {
2369 a += int64(elfwritegobuildid(ctxt.Out))
2370 }
2371 }
2372 if *flagRace && ctxt.IsNetbsd() {
2373 a += int64(elfwritenetbsdpax(ctxt.Out))
2374 }
2375
2376 if a > elfreserve {
2377 Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
2378 }
2379
2380
2381
2382 if a > int64(HEADR) {
2383 Errorf(nil, "HEADR too small: %d > %d with %d text sections", a, HEADR, numtext)
2384 }
2385 }
2386
2387 func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
2388 ldr.SetSymDynid(s, int32(Nelfsym))
2389 Nelfsym++
2390 d := ldr.MakeSymbolUpdater(syms.DynSym)
2391 name := ldr.SymExtname(s)
2392 dstru := ldr.MakeSymbolUpdater(syms.DynStr)
2393 st := ldr.SymType(s)
2394 cgoeStatic := ldr.AttrCgoExportStatic(s)
2395 cgoeDynamic := ldr.AttrCgoExportDynamic(s)
2396 cgoexp := (cgoeStatic || cgoeDynamic)
2397
2398 d.AddUint32(target.Arch, uint32(dstru.Addstring(name)))
2399
2400 if elf64 {
2401
2402
2403 var t uint8
2404
2405 if cgoexp && st == sym.STEXT {
2406 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2407 } else {
2408 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT)
2409 }
2410 d.AddUint8(t)
2411
2412
2413 d.AddUint8(0)
2414
2415
2416 if st == sym.SDYNIMPORT {
2417 d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF))
2418 } else {
2419 d.AddUint16(target.Arch, 1)
2420 }
2421
2422
2423 if st == sym.SDYNIMPORT {
2424 d.AddUint64(target.Arch, 0)
2425 } else {
2426 d.AddAddrPlus(target.Arch, s, 0)
2427 }
2428
2429
2430 d.AddUint64(target.Arch, uint64(len(ldr.Data(s))))
2431
2432 dil := ldr.SymDynimplib(s)
2433
2434 if !cgoeDynamic && dil != "" && !seenlib[dil] {
2435 du := ldr.MakeSymbolUpdater(syms.Dynamic)
2436 Elfwritedynent(target.Arch, du, elf.DT_NEEDED, uint64(dstru.Addstring(dil)))
2437 seenlib[dil] = true
2438 }
2439 } else {
2440
2441
2442 if st == sym.SDYNIMPORT {
2443 d.AddUint32(target.Arch, 0)
2444 } else {
2445 d.AddAddrPlus(target.Arch, s, 0)
2446 }
2447
2448
2449 d.AddUint32(target.Arch, uint32(len(ldr.Data(s))))
2450
2451
2452 var t uint8
2453
2454
2455 if target.Arch.Family == sys.I386 && cgoexp && st == sym.STEXT {
2456 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2457 } else if target.Arch.Family == sys.ARM && cgoeDynamic && st == sym.STEXT {
2458 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC)
2459 } else {
2460 t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT)
2461 }
2462 d.AddUint8(t)
2463 d.AddUint8(0)
2464
2465
2466 if st == sym.SDYNIMPORT {
2467 d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF))
2468 } else {
2469 d.AddUint16(target.Arch, 1)
2470 }
2471 }
2472 }
2473
View as plain text