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