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