1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package ld
33
34 import (
35 "bytes"
36 "cmd/internal/gcprog"
37 "cmd/internal/objabi"
38 "cmd/internal/sys"
39 "cmd/link/internal/loader"
40 "cmd/link/internal/loadpe"
41 "cmd/link/internal/sym"
42 "compress/zlib"
43 "debug/elf"
44 "encoding/binary"
45 "fmt"
46 "internal/abi"
47 "log"
48 "math/rand"
49 "os"
50 "sort"
51 "strconv"
52 "strings"
53 "sync"
54 "sync/atomic"
55 )
56
57
58 func isRuntimeDepPkg(pkg string) bool {
59 switch pkg {
60 case "runtime",
61 "sync/atomic",
62 "internal/abi",
63 "internal/bytealg",
64 "internal/chacha8rand",
65 "internal/cpu":
66 return true
67 }
68 return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test")
69 }
70
71
72
73
74 func maxSizeTrampolines(ctxt *Link, ldr *loader.Loader, s loader.Sym, isTramp bool) uint64 {
75
76
77 if thearch.Trampoline == nil || isTramp {
78 return 0
79 }
80
81 n := uint64(0)
82 relocs := ldr.Relocs(s)
83 for ri := 0; ri < relocs.Count(); ri++ {
84 r := relocs.At(ri)
85 if r.Type().IsDirectCallOrJump() {
86 n++
87 }
88 }
89
90 switch {
91 case ctxt.IsARM():
92 return n * 20
93 case ctxt.IsARM64():
94 return n * 12
95 case ctxt.IsPPC64():
96 return n * 16
97 case ctxt.IsRISCV64():
98 return n * 8
99 }
100 panic("unreachable")
101 }
102
103
104
105
106
107 func trampoline(ctxt *Link, s loader.Sym) {
108 if thearch.Trampoline == nil {
109 return
110 }
111
112 ldr := ctxt.loader
113 relocs := ldr.Relocs(s)
114 for ri := 0; ri < relocs.Count(); ri++ {
115 r := relocs.At(ri)
116 rt := r.Type()
117 if !rt.IsDirectCallOrJump() && !isPLTCall(rt) {
118 continue
119 }
120 rs := r.Sym()
121 if !ldr.AttrReachable(rs) || ldr.SymType(rs) == sym.Sxxx {
122 continue
123 }
124
125 if ldr.SymValue(rs) == 0 && ldr.SymType(rs) != sym.SDYNIMPORT && ldr.SymType(rs) != sym.SUNDEFEXT {
126
127
128
129
130 if ldr.SymPkg(s) != "" && ldr.SymPkg(rs) == ldr.SymPkg(s) && *flagRandLayout == 0 {
131
132
133
134 if !ctxt.Target.IsRISCV64() {
135 continue
136 }
137 }
138
139 if isRuntimeDepPkg(ldr.SymPkg(s)) && isRuntimeDepPkg(ldr.SymPkg(rs)) && *flagRandLayout == 0 {
140 continue
141 }
142 }
143 thearch.Trampoline(ctxt, ldr, ri, rs, s)
144 }
145 }
146
147
148
149 func isPLTCall(rt objabi.RelocType) bool {
150 const pcrel = 1
151 switch rt {
152
153 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
154 objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26),
155 objabi.MachoRelocOffset + MACHO_ARM64_RELOC_BRANCH26*2 + pcrel:
156 return true
157
158
159 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
160 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
161 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
162 return true
163 }
164
165 return false
166 }
167
168
169
170
171 func FoldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) {
172 outer := ldr.OuterSym(s)
173 off := int64(0)
174 if outer != 0 {
175 off += ldr.SymValue(s) - ldr.SymValue(outer)
176 s = outer
177 }
178 return s, off
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
198 ldr := st.ldr
199 relocs := ldr.Relocs(s)
200 if relocs.Count() == 0 {
201 return
202 }
203 target := st.target
204 syms := st.syms
205 nExtReloc := 0
206 for ri := 0; ri < relocs.Count(); ri++ {
207 r := relocs.At(ri)
208 off := r.Off()
209 siz := int32(r.Siz())
210 rs := r.Sym()
211 rt := r.Type()
212 weak := r.Weak()
213 if off < 0 || off+siz > int32(len(P)) {
214 rname := ""
215 if rs != 0 {
216 rname = ldr.SymName(rs)
217 }
218 st.err.Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(P))
219 continue
220 }
221 if siz == 0 {
222 continue
223 }
224
225 var rst sym.SymKind
226 if rs != 0 {
227 rst = ldr.SymType(rs)
228 }
229
230 if rs != 0 && (rst == sym.Sxxx || rst == sym.SXREF) {
231
232
233 if target.IsShared() || target.IsPlugin() {
234 if ldr.SymName(rs) == "main.main" || (!target.IsPlugin() && ldr.SymName(rs) == "main..inittask") {
235 sb := ldr.MakeSymbolUpdater(rs)
236 sb.SetType(sym.SDYNIMPORT)
237 } else if strings.HasPrefix(ldr.SymName(rs), "go:info.") {
238
239
240 continue
241 }
242 } else if target.IsPPC64() && ldr.SymName(rs) == ".TOC." {
243
244
245
246 } else {
247 st.err.errorUnresolved(ldr, s, rs)
248 continue
249 }
250 }
251
252 if rt >= objabi.ElfRelocOffset {
253 continue
254 }
255
256
257
258 if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
259 if !(target.IsPPC64() && target.IsExternal() && ldr.SymName(rs) == ".TOC.") {
260 st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
261 }
262 }
263 if rs != 0 && rst != sym.STLSBSS && !weak && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
264 st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
265 }
266
267 var rv sym.RelocVariant
268 if target.IsPPC64() || target.IsS390X() {
269 rv = ldr.RelocVariant(s, ri)
270 }
271
272
273 if target.IsS390X() {
274 switch rt {
275 case objabi.R_PCRELDBL:
276 rt = objabi.R_PCREL
277 rv = sym.RV_390_DBL
278 case objabi.R_CALL:
279 rv = sym.RV_390_DBL
280 }
281 }
282
283 var o int64
284 switch rt {
285 default:
286 switch siz {
287 default:
288 st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs))
289 case 1:
290 o = int64(P[off])
291 case 2:
292 o = int64(target.Arch.ByteOrder.Uint16(P[off:]))
293 case 4:
294 o = int64(target.Arch.ByteOrder.Uint32(P[off:]))
295 case 8:
296 o = int64(target.Arch.ByteOrder.Uint64(P[off:]))
297 }
298 out, n, ok := thearch.Archreloc(target, ldr, syms, r, s, o)
299 if target.IsExternal() {
300 nExtReloc += n
301 }
302 if ok {
303 o = out
304 } else {
305 st.err.Errorf(s, "unknown reloc to %v: %d (%s)", ldr.SymName(rs), rt, sym.RelocName(target.Arch, rt))
306 }
307 case objabi.R_TLS_LE:
308 if target.IsExternal() && target.IsElf() {
309 nExtReloc++
310 o = 0
311 if !target.IsAMD64() {
312 o = r.Add()
313 }
314 break
315 }
316
317 if target.IsElf() && target.IsARM() {
318
319
320
321
322
323
324
325 o = 8 + ldr.SymValue(rs)
326 } else if target.IsElf() || target.IsPlan9() || target.IsDarwin() {
327 o = int64(syms.Tlsoffset) + r.Add()
328 } else if target.IsWindows() {
329 o = r.Add()
330 } else {
331 log.Fatalf("unexpected R_TLS_LE relocation for %v", target.HeadType)
332 }
333 case objabi.R_TLS_IE:
334 if target.IsExternal() && target.IsElf() {
335 nExtReloc++
336 o = 0
337 if !target.IsAMD64() {
338 o = r.Add()
339 }
340 if target.Is386() {
341 nExtReloc++
342 }
343 break
344 }
345 if target.IsPIE() && target.IsElf() {
346
347
348 if thearch.TLSIEtoLE == nil {
349 log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family)
350 }
351 thearch.TLSIEtoLE(P, int(off), int(siz))
352 o = int64(syms.Tlsoffset)
353 } else {
354 log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
355 }
356 case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
357 if weak && !ldr.AttrReachable(rs) {
358
359 rs = syms.unreachableMethod
360 }
361 if target.IsExternal() {
362 nExtReloc++
363
364
365 rs := rs
366 rs, off := FoldSubSymbolOffset(ldr, rs)
367 xadd := r.Add() + off
368 rst := ldr.SymType(rs)
369 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
370 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
371 }
372
373 o = xadd
374 if target.IsElf() {
375 if target.IsAMD64() {
376 o = 0
377 }
378 } else if target.IsDarwin() {
379 if ldr.SymType(s).IsDWARF() {
380
381
382
383
384 o += ldr.SymValue(rs)
385 }
386 } else if target.IsWindows() {
387
388 } else if target.IsAIX() {
389 o = ldr.SymValue(rs) + xadd
390 } else {
391 st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
392 }
393
394 break
395 }
396
397
398
399
400
401 if target.IsAIX() && rst != sym.SDYNIMPORT {
402
403
404
405
406
407 if ldr.SymSect(s).Seg == &Segdata {
408 Xcoffadddynrel(target, ldr, syms, s, r, ri)
409 }
410 }
411
412 o = ldr.SymValue(rs) + r.Add()
413 if rt == objabi.R_PEIMAGEOFF {
414
415
416 o -= PEBASE
417 }
418
419
420
421
422
423
424 if int32(o) < 0 && target.Arch.PtrSize > 4 && siz == 4 {
425 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", ldr.SymName(rs), uint64(o), ldr.SymValue(rs), r.Add())
426 errorexit()
427 }
428 case objabi.R_DWARFSECREF:
429 if ldr.SymSect(rs) == nil {
430 st.err.Errorf(s, "missing DWARF section for relocation target %s", ldr.SymName(rs))
431 }
432
433 if target.IsExternal() {
434
435
436
437
438
439 if !target.IsDarwin() {
440 nExtReloc++
441 }
442
443 xadd := r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
444
445 o = xadd
446 if target.IsElf() && target.IsAMD64() {
447 o = 0
448 }
449 break
450 }
451 o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
452 case objabi.R_METHODOFF:
453 if !ldr.AttrReachable(rs) {
454
455
456 o = -1
457 break
458 }
459 fallthrough
460 case objabi.R_ADDROFF:
461 if weak && !ldr.AttrReachable(rs) {
462 continue
463 }
464 sect := ldr.SymSect(rs)
465 if sect == nil {
466 if rst == sym.SDYNIMPORT {
467 st.err.Errorf(s, "cannot target DYNIMPORT sym in section-relative reloc: %s", ldr.SymName(rs))
468 } else if rst == sym.SUNDEFEXT {
469 st.err.Errorf(s, "undefined symbol in relocation: %s", ldr.SymName(rs))
470 } else {
471 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
472 }
473 continue
474 }
475
476
477
478 if sect.Name == ".text" {
479 o = ldr.SymValue(rs) - int64(Segtext.Sections[0].Vaddr) + r.Add()
480 } else {
481 o = ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) + r.Add()
482 }
483
484 case objabi.R_ADDRCUOFF:
485
486
487 o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(loader.Sym(ldr.SymUnit(rs).Textp[0]))
488
489
490 case objabi.R_GOTPCREL:
491 if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 {
492 nExtReloc++
493 o = r.Add()
494 break
495 }
496 if target.Is386() && target.IsExternal() && target.IsELF {
497 nExtReloc++
498 }
499 fallthrough
500 case objabi.R_CALL, objabi.R_PCREL:
501 if target.IsExternal() && rs != 0 && rst == sym.SUNDEFEXT {
502
503 nExtReloc++
504 o = 0
505 break
506 }
507 if target.IsExternal() && rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
508 nExtReloc++
509
510
511 rs := rs
512 rs, off := FoldSubSymbolOffset(ldr, rs)
513 xadd := r.Add() + off - int64(siz)
514 rst := ldr.SymType(rs)
515 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
516 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
517 }
518
519 o = xadd
520 if target.IsElf() {
521 if target.IsAMD64() {
522 o = 0
523 }
524 } else if target.IsDarwin() {
525 if rt == objabi.R_CALL {
526 if target.IsExternal() && rst == sym.SDYNIMPORT {
527 if target.IsAMD64() {
528
529 o += int64(siz)
530 }
531 } else {
532 if rst != sym.SHOSTOBJ {
533 o += int64(uint64(ldr.SymValue(rs)) - ldr.SymSect(rs).Vaddr)
534 }
535 o -= int64(off)
536 }
537 } else {
538 o += int64(siz)
539 }
540 } else if target.IsWindows() && target.IsAMD64() {
541
542
543 o += int64(siz)
544 } else {
545 st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
546 }
547
548 break
549 }
550
551 o = 0
552 if rs != 0 {
553 o = ldr.SymValue(rs)
554 }
555
556 o += r.Add() - (ldr.SymValue(s) + int64(off) + int64(siz))
557 case objabi.R_SIZE:
558 o = ldr.SymSize(rs) + r.Add()
559
560 case objabi.R_XCOFFREF:
561 if !target.IsAIX() {
562 st.err.Errorf(s, "find XCOFF R_REF on non-XCOFF files")
563 }
564 if !target.IsExternal() {
565 st.err.Errorf(s, "find XCOFF R_REF with internal linking")
566 }
567 nExtReloc++
568 continue
569
570 case objabi.R_DWARFFILEREF:
571
572 continue
573
574 case objabi.R_CONST:
575 o = r.Add()
576
577 case objabi.R_GOTOFF:
578 o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.GOT)
579 }
580
581 if target.IsPPC64() || target.IsS390X() {
582 if rv != sym.RV_NONE {
583 o = thearch.Archrelocvariant(target, ldr, r, rv, s, o, P)
584 }
585 }
586
587 switch siz {
588 default:
589 st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs))
590 case 1:
591 P[off] = byte(int8(o))
592 case 2:
593 if (rt == objabi.R_PCREL || rt == objabi.R_CALL) && o != int64(int16(o)) {
594 st.err.Errorf(s, "pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), o)
595 } else if o != int64(int16(o)) && o != int64(uint16(o)) {
596 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o))
597 }
598 target.Arch.ByteOrder.PutUint16(P[off:], uint16(o))
599 case 4:
600 if (rt == objabi.R_PCREL || rt == objabi.R_CALL) && o != int64(int32(o)) {
601 st.err.Errorf(s, "pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), o)
602 } else if o != int64(int32(o)) && o != int64(uint32(o)) {
603 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o))
604 }
605 target.Arch.ByteOrder.PutUint32(P[off:], uint32(o))
606 case 8:
607 target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
608 }
609 }
610 if target.IsExternal() {
611
612
613 atomic.AddUint32(&ldr.SymSect(s).Relcount, uint32(nExtReloc))
614 }
615 }
616
617
618 func extreloc(ctxt *Link, ldr *loader.Loader, s loader.Sym, r loader.Reloc) (loader.ExtReloc, bool) {
619 var rr loader.ExtReloc
620 target := &ctxt.Target
621 siz := int32(r.Siz())
622 if siz == 0 {
623 return rr, false
624 }
625
626 rt := r.Type()
627 if rt >= objabi.ElfRelocOffset {
628 return rr, false
629 }
630 rr.Type = rt
631 rr.Size = uint8(siz)
632
633
634 if target.IsS390X() {
635 switch rt {
636 case objabi.R_PCRELDBL:
637 rt = objabi.R_PCREL
638 }
639 }
640
641 switch rt {
642 default:
643 return thearch.Extreloc(target, ldr, r, s)
644
645 case objabi.R_TLS_LE, objabi.R_TLS_IE:
646 if target.IsElf() {
647 rs := r.Sym()
648 rr.Xsym = rs
649 if rr.Xsym == 0 {
650 rr.Xsym = ctxt.Tlsg
651 }
652 rr.Xadd = r.Add()
653 break
654 }
655 return rr, false
656
657 case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
658
659 rs := r.Sym()
660 if r.Weak() && !ldr.AttrReachable(rs) {
661 rs = ctxt.ArchSyms.unreachableMethod
662 }
663 rs, off := FoldSubSymbolOffset(ldr, rs)
664 rr.Xadd = r.Add() + off
665 rr.Xsym = rs
666
667 case objabi.R_DWARFSECREF:
668
669
670
671
672
673 if target.IsDarwin() {
674 return rr, false
675 }
676 rs := r.Sym()
677 rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym)
678 rr.Xadd = r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
679
680
681 case objabi.R_GOTPCREL, objabi.R_CALL, objabi.R_PCREL:
682 rs := r.Sym()
683 if rt == objabi.R_GOTPCREL && target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 {
684 rr.Xadd = r.Add()
685 rr.Xadd -= int64(siz)
686 rr.Xsym = rs
687 break
688 }
689 if rs != 0 && ldr.SymType(rs) == sym.SUNDEFEXT {
690
691 rr.Xadd = 0
692 if target.IsElf() {
693 rr.Xadd -= int64(siz)
694 }
695 rr.Xsym = rs
696 break
697 }
698 if rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
699
700 rs := rs
701 rs, off := FoldSubSymbolOffset(ldr, rs)
702 rr.Xadd = r.Add() + off
703 rr.Xadd -= int64(siz)
704 rr.Xsym = rs
705 break
706 }
707 return rr, false
708
709 case objabi.R_XCOFFREF:
710 return ExtrelocSimple(ldr, r), true
711
712
713 case objabi.R_ADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
714 objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF:
715 return rr, false
716 }
717 return rr, true
718 }
719
720
721
722 func ExtrelocSimple(ldr *loader.Loader, r loader.Reloc) loader.ExtReloc {
723 var rr loader.ExtReloc
724 rs := r.Sym()
725 rr.Xsym = rs
726 rr.Xadd = r.Add()
727 rr.Type = r.Type()
728 rr.Size = r.Siz()
729 return rr
730 }
731
732
733
734 func ExtrelocViaOuterSym(ldr *loader.Loader, r loader.Reloc, s loader.Sym) loader.ExtReloc {
735
736 var rr loader.ExtReloc
737 rs := r.Sym()
738 rs, off := FoldSubSymbolOffset(ldr, rs)
739 rr.Xadd = r.Add() + off
740 rst := ldr.SymType(rs)
741 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
742 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
743 }
744 rr.Xsym = rs
745 rr.Type = r.Type()
746 rr.Size = r.Siz()
747 return rr
748 }
749
750
751
752
753
754
755
756
757 type relocSymState struct {
758 target *Target
759 ldr *loader.Loader
760 err *ErrorReporter
761 syms *ArchSyms
762 }
763
764
765
766
767 func (ctxt *Link) makeRelocSymState() *relocSymState {
768 return &relocSymState{
769 target: &ctxt.Target,
770 ldr: ctxt.loader,
771 err: &ctxt.ErrorReporter,
772 syms: &ctxt.ArchSyms,
773 }
774 }
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807 func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error {
808 var su *loader.SymbolBuilder
809 relocs := ctxt.loader.Relocs(s)
810 for ri := 0; ri < relocs.Count(); ri++ {
811 r := relocs.At(ri)
812 if r.IsMarker() {
813 continue
814 }
815 targ := r.Sym()
816 if targ == 0 {
817 continue
818 }
819 if !ctxt.loader.AttrReachable(targ) {
820 if r.Weak() {
821 continue
822 }
823 return fmt.Errorf("dynamic relocation to unreachable symbol %s",
824 ctxt.loader.SymName(targ))
825 }
826 tgot := ctxt.loader.SymGot(targ)
827 if tgot == loadpe.RedirectToDynImportGotToken {
828
829
830 sname := ctxt.loader.SymName(targ)
831 if !strings.HasPrefix(sname, "__imp_") {
832 return fmt.Errorf("internal error in windynrelocsym: redirect GOT token applied to non-import symbol %s", sname)
833 }
834
835
836
837 ds, err := loadpe.LookupBaseFromImport(targ, ctxt.loader, ctxt.Arch)
838 if err != nil {
839 return err
840 }
841 dstyp := ctxt.loader.SymType(ds)
842 if dstyp != sym.SWINDOWS {
843 return fmt.Errorf("internal error in windynrelocsym: underlying sym for %q has wrong type %s", sname, dstyp.String())
844 }
845
846
847 r.SetSym(ds)
848 continue
849 }
850
851 tplt := ctxt.loader.SymPlt(targ)
852 if tplt == loadpe.CreateImportStubPltToken {
853
854
855 if tgot != -1 {
856 return fmt.Errorf("internal error in windynrelocsym: invalid GOT setting %d for reloc to %s", tgot, ctxt.loader.SymName(targ))
857 }
858
859
860 tplt := int32(rel.Size())
861 ctxt.loader.SetPlt(targ, tplt)
862
863 if su == nil {
864 su = ctxt.loader.MakeSymbolUpdater(s)
865 }
866 r.SetSym(rel.Sym())
867 r.SetAdd(int64(tplt))
868
869
870 switch ctxt.Arch.Family {
871 default:
872 return fmt.Errorf("internal error in windynrelocsym: unsupported arch %v", ctxt.Arch.Family)
873 case sys.I386:
874 rel.AddUint8(0xff)
875 rel.AddUint8(0x25)
876 rel.AddAddrPlus(ctxt.Arch, targ, 0)
877 rel.AddUint8(0x90)
878 rel.AddUint8(0x90)
879 case sys.AMD64:
880 rel.AddUint8(0xff)
881 rel.AddUint8(0x24)
882 rel.AddUint8(0x25)
883 rel.AddAddrPlus4(ctxt.Arch, targ, 0)
884 rel.AddUint8(0x90)
885 }
886 } else if tplt >= 0 {
887 if su == nil {
888 su = ctxt.loader.MakeSymbolUpdater(s)
889 }
890 r.SetSym(rel.Sym())
891 r.SetAdd(int64(tplt))
892 }
893 }
894 return nil
895 }
896
897
898
899 func (ctxt *Link) windynrelocsyms() {
900 if !(ctxt.IsWindows() && iscgo && ctxt.IsInternal()) {
901 return
902 }
903
904 rel := ctxt.loader.CreateSymForUpdate(".rel", 0)
905 rel.SetType(sym.STEXT)
906
907 for _, s := range ctxt.Textp {
908 if err := windynrelocsym(ctxt, rel, s); err != nil {
909 ctxt.Errorf(s, "%v", err)
910 }
911 }
912
913 ctxt.Textp = append(ctxt.Textp, rel.Sym())
914 }
915
916 func dynrelocsym(ctxt *Link, s loader.Sym) {
917 target := &ctxt.Target
918 ldr := ctxt.loader
919 syms := &ctxt.ArchSyms
920 relocs := ldr.Relocs(s)
921 for ri := 0; ri < relocs.Count(); ri++ {
922 r := relocs.At(ri)
923 if r.IsMarker() {
924 continue
925 }
926 rSym := r.Sym()
927 if r.Weak() && !ldr.AttrReachable(rSym) {
928 continue
929 }
930 if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
931
932
933
934 thearch.Adddynrel(target, ldr, syms, s, r, ri)
935 continue
936 }
937
938 if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
939 if rSym != 0 && !ldr.AttrReachable(rSym) {
940 ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
941 }
942 if !thearch.Adddynrel(target, ldr, syms, s, r, ri) {
943 ctxt.Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", ldr.SymName(rSym), r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymType(rSym), ldr.SymType(rSym))
944 }
945 }
946 }
947 }
948
949 func (state *dodataState) dynreloc(ctxt *Link) {
950 if ctxt.HeadType == objabi.Hwindows {
951 return
952 }
953
954
955 if *FlagD {
956 return
957 }
958
959 for _, s := range ctxt.Textp {
960 dynrelocsym(ctxt, s)
961 }
962 for _, syms := range state.data {
963 for _, s := range syms {
964 dynrelocsym(ctxt, s)
965 }
966 }
967 if ctxt.IsELF {
968 elfdynhash(ctxt)
969 }
970 }
971
972 func CodeblkPad(ctxt *Link, out *OutBuf, addr int64, size int64, pad []byte) {
973 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.Textp, addr, size, pad)
974 }
975
976 const blockSize = 1 << 20
977
978
979
980
981
982
983 func writeBlocks(ctxt *Link, out *OutBuf, sem chan int, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
984 for i, s := range syms {
985 if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
986 syms = syms[i:]
987 break
988 }
989 }
990
991 var wg sync.WaitGroup
992 max, lastAddr, written := int64(blockSize), addr+size, int64(0)
993 for addr < lastAddr {
994
995 idx := -1
996 for i, s := range syms {
997 if ldr.AttrSubSymbol(s) {
998 continue
999 }
1000
1001
1002
1003 end := ldr.SymValue(s) + ldr.SymSize(s)
1004 if end > lastAddr {
1005 break
1006 }
1007
1008
1009 idx = i
1010
1011
1012 if end > addr+max {
1013 break
1014 }
1015 }
1016
1017
1018 if idx < 0 {
1019 break
1020 }
1021
1022
1023
1024
1025
1026
1027 length := int64(0)
1028 if idx+1 < len(syms) {
1029
1030
1031
1032 next := syms[idx+1]
1033 for ldr.AttrSubSymbol(next) {
1034 idx++
1035 next = syms[idx+1]
1036 }
1037 length = ldr.SymValue(next) - addr
1038 }
1039 if length == 0 || length > lastAddr-addr {
1040 length = lastAddr - addr
1041 }
1042
1043
1044 if o, err := out.View(uint64(out.Offset() + written)); err == nil {
1045 sem <- 1
1046 wg.Add(1)
1047 go func(o *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
1048 writeBlock(ctxt, o, ldr, syms, addr, size, pad)
1049 wg.Done()
1050 <-sem
1051 }(o, ldr, syms, addr, length, pad)
1052 } else {
1053 writeBlock(ctxt, out, ldr, syms, addr, length, pad)
1054 }
1055
1056
1057 if idx != -1 {
1058 syms = syms[idx+1:]
1059 }
1060 written += length
1061 addr += length
1062 }
1063 wg.Wait()
1064 }
1065
1066 func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
1067
1068 st := ctxt.makeRelocSymState()
1069
1070
1071
1072
1073
1074 eaddr := addr + size
1075 for _, s := range syms {
1076 if ldr.AttrSubSymbol(s) {
1077 continue
1078 }
1079 val := ldr.SymValue(s)
1080 if val >= eaddr {
1081 break
1082 }
1083 if val < addr {
1084 ldr.Errorf(s, "phase error: addr=%#x but val=%#x sym=%s type=%v sect=%v sect.addr=%#x", addr, val, ldr.SymName(s), ldr.SymType(s), ldr.SymSect(s).Name, ldr.SymSect(s).Vaddr)
1085 errorexit()
1086 }
1087 if addr < val {
1088 out.WriteStringPad("", int(val-addr), pad)
1089 addr = val
1090 }
1091 P := out.WriteSym(ldr, s)
1092 st.relocsym(s, P)
1093 if ldr.IsGeneratedSym(s) {
1094 f := ctxt.generatorSyms[s]
1095 f(ctxt, s)
1096 }
1097 addr += int64(len(P))
1098 siz := ldr.SymSize(s)
1099 if addr < val+siz {
1100 out.WriteStringPad("", int(val+siz-addr), pad)
1101 addr = val + siz
1102 }
1103 if addr != val+siz {
1104 ldr.Errorf(s, "phase error: addr=%#x value+size=%#x", addr, val+siz)
1105 errorexit()
1106 }
1107 if val+siz >= eaddr {
1108 break
1109 }
1110 }
1111
1112 if addr < eaddr {
1113 out.WriteStringPad("", int(eaddr-addr), pad)
1114 }
1115 }
1116
1117 type writeFn func(*Link, *OutBuf, int64, int64)
1118
1119
1120 func writeParallel(wg *sync.WaitGroup, fn writeFn, ctxt *Link, seek, vaddr, length uint64) {
1121 if out, err := ctxt.Out.View(seek); err != nil {
1122 ctxt.Out.SeekSet(int64(seek))
1123 fn(ctxt, ctxt.Out, int64(vaddr), int64(length))
1124 } else {
1125 wg.Add(1)
1126 go func() {
1127 defer wg.Done()
1128 fn(ctxt, out, int64(vaddr), int64(length))
1129 }()
1130 }
1131 }
1132
1133 func datblk(ctxt *Link, out *OutBuf, addr, size int64) {
1134 writeDatblkToOutBuf(ctxt, out, addr, size)
1135 }
1136
1137
1138 func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
1139 buf := make([]byte, size)
1140 out := &OutBuf{heap: buf}
1141 writeDatblkToOutBuf(ctxt, out, addr, size)
1142 return buf
1143 }
1144
1145 func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
1146 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.datap, addr, size, zeros[:])
1147 }
1148
1149 func dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
1150
1151
1152
1153
1154
1155
1156 n := 0
1157 for i := range dwarfp {
1158 n += len(dwarfp[i].syms)
1159 }
1160 syms := make([]loader.Sym, 0, n)
1161 for i := range dwarfp {
1162 syms = append(syms, dwarfp[i].syms...)
1163 }
1164 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:])
1165 }
1166
1167 func pdatablk(ctxt *Link, out *OutBuf, addr int64, size int64) {
1168 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, sehp.pdata, addr, size, zeros[:])
1169 }
1170
1171 func xdatablk(ctxt *Link, out *OutBuf, addr int64, size int64) {
1172 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, sehp.xdata, addr, size, zeros[:])
1173 }
1174
1175 var covCounterDataStartOff, covCounterDataLen uint64
1176
1177 var zeros [512]byte
1178
1179 var (
1180 strdata = make(map[string]string)
1181 strnames []string
1182 )
1183
1184 func addstrdata1(ctxt *Link, arg string) {
1185 eq := strings.Index(arg, "=")
1186 dot := strings.LastIndex(arg[:eq+1], ".")
1187 if eq < 0 || dot < 0 {
1188 Exitf("-X flag requires argument of the form importpath.name=value")
1189 }
1190 pkg := arg[:dot]
1191 if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
1192 pkg = *flagPluginPath
1193 }
1194 pkg = objabi.PathToPrefix(pkg)
1195 name := pkg + arg[dot:eq]
1196 value := arg[eq+1:]
1197 if _, ok := strdata[name]; !ok {
1198 strnames = append(strnames, name)
1199 }
1200 strdata[name] = value
1201 }
1202
1203
1204 func addstrdata(arch *sys.Arch, l *loader.Loader, name, value string) {
1205 s := l.Lookup(name, 0)
1206 if s == 0 {
1207 return
1208 }
1209 if goType := l.SymGoType(s); goType == 0 {
1210 return
1211 } else if typeName := l.SymName(goType); typeName != "type:string" {
1212 Errorf(nil, "%s: cannot set with -X: not a var of type string (%s)", name, typeName)
1213 return
1214 }
1215 if !l.AttrReachable(s) {
1216 return
1217 }
1218 bld := l.MakeSymbolUpdater(s)
1219 if bld.Type() == sym.SBSS {
1220 bld.SetType(sym.SDATA)
1221 }
1222
1223 p := fmt.Sprintf("%s.str", name)
1224 sbld := l.CreateSymForUpdate(p, 0)
1225 sbld.Addstring(value)
1226 sbld.SetType(sym.SRODATA)
1227
1228
1229
1230
1231 bld.SetData(make([]byte, arch.PtrSize*2))
1232 bld.SetReadOnly(false)
1233 bld.ResetRelocs()
1234 bld.SetAddrPlus(arch, 0, sbld.Sym(), 0)
1235 bld.SetUint(arch, int64(arch.PtrSize), uint64(len(value)))
1236 }
1237
1238 func (ctxt *Link) dostrdata() {
1239 for _, name := range strnames {
1240 addstrdata(ctxt.Arch, ctxt.loader, name, strdata[name])
1241 }
1242 }
1243
1244
1245
1246 func addgostring(ctxt *Link, ldr *loader.Loader, s *loader.SymbolBuilder, symname, str string) {
1247 sdata := ldr.CreateSymForUpdate(symname, 0)
1248 if sdata.Type() != sym.Sxxx {
1249 ctxt.Errorf(s.Sym(), "duplicate symname in addgostring: %s", symname)
1250 }
1251 sdata.SetLocal(true)
1252 sdata.SetType(sym.SRODATA)
1253 sdata.SetSize(int64(len(str)))
1254 sdata.SetData([]byte(str))
1255 s.AddAddr(ctxt.Arch, sdata.Sym())
1256 s.AddUint(ctxt.Arch, uint64(len(str)))
1257 }
1258
1259 func addinitarrdata(ctxt *Link, ldr *loader.Loader, s loader.Sym) {
1260 p := ldr.SymName(s) + ".ptr"
1261 sp := ldr.CreateSymForUpdate(p, 0)
1262 sp.SetType(sym.SINITARR)
1263 sp.SetSize(0)
1264 sp.SetDuplicateOK(true)
1265 sp.AddAddr(ctxt.Arch, s)
1266 }
1267
1268
1269 func symalign(ldr *loader.Loader, s loader.Sym) int32 {
1270 min := int32(thearch.Minalign)
1271 align := ldr.SymAlign(s)
1272 if align >= min {
1273 return align
1274 } else if align != 0 {
1275 return min
1276 }
1277 align = int32(thearch.Maxalign)
1278 ssz := ldr.SymSize(s)
1279 for int64(align) > ssz && align > min {
1280 align >>= 1
1281 }
1282 ldr.SetSymAlign(s, align)
1283 return align
1284 }
1285
1286 func aligndatsize(state *dodataState, datsize int64, s loader.Sym) int64 {
1287 return Rnd(datsize, int64(symalign(state.ctxt.loader, s)))
1288 }
1289
1290 const debugGCProg = false
1291
1292 type GCProg struct {
1293 ctxt *Link
1294 sym *loader.SymbolBuilder
1295 w gcprog.Writer
1296 }
1297
1298 func (p *GCProg) Init(ctxt *Link, name string) {
1299 p.ctxt = ctxt
1300 p.sym = ctxt.loader.CreateSymForUpdate(name, 0)
1301 p.w.Init(p.writeByte())
1302 if debugGCProg {
1303 fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name)
1304 p.w.Debug(os.Stderr)
1305 }
1306 }
1307
1308 func (p *GCProg) writeByte() func(x byte) {
1309 return func(x byte) {
1310 p.sym.AddUint8(x)
1311 }
1312 }
1313
1314 func (p *GCProg) End(size int64) {
1315 p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
1316 p.w.End()
1317 if debugGCProg {
1318 fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
1319 }
1320 }
1321
1322 func (p *GCProg) AddSym(s loader.Sym) {
1323 ldr := p.ctxt.loader
1324 typ := ldr.SymGoType(s)
1325
1326
1327
1328 if typ == 0 {
1329 switch ldr.SymName(s) {
1330 case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss":
1331
1332
1333
1334 return
1335 }
1336 p.ctxt.Errorf(p.sym.Sym(), "missing Go type information for global symbol %s: size %d", ldr.SymName(s), ldr.SymSize(s))
1337 return
1338 }
1339
1340 ptrsize := int64(p.ctxt.Arch.PtrSize)
1341 typData := ldr.Data(typ)
1342 nptr := decodetypePtrdata(p.ctxt.Arch, typData) / ptrsize
1343
1344 if debugGCProg {
1345 fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", ldr.SymName(s), ldr.SymValue(s), ldr.SymValue(s)/ptrsize, nptr)
1346 }
1347
1348 sval := ldr.SymValue(s)
1349 if !decodetypeUsegcprog(p.ctxt.Arch, typData) {
1350
1351 mask := decodetypeGcmask(p.ctxt, typ)
1352 for i := int64(0); i < nptr; i++ {
1353 if (mask[i/8]>>uint(i%8))&1 != 0 {
1354 p.w.Ptr(sval/ptrsize + i)
1355 }
1356 }
1357 return
1358 }
1359
1360
1361 prog := decodetypeGcprog(p.ctxt, typ)
1362 p.w.ZeroUntil(sval / ptrsize)
1363 p.w.Append(prog[4:], nptr)
1364 }
1365
1366
1367
1368 const cutoff = 2e9
1369
1370
1371 func (state *dodataState) checkdatsize(symn sym.SymKind) {
1372 if state.datsize > cutoff {
1373 Errorf(nil, "too much data, last section %v (%d, over %v bytes)", symn, state.datsize, cutoff)
1374 }
1375 }
1376
1377 func checkSectSize(sect *sym.Section) {
1378
1379
1380
1381 if sect.Length > cutoff {
1382 Errorf(nil, "too much data in section %s (%d, over %v bytes)", sect.Name, sect.Length, cutoff)
1383 }
1384 }
1385
1386
1387 func fixZeroSizedSymbols(ctxt *Link) {
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
1412 return
1413 }
1414
1415 ldr := ctxt.loader
1416 bss := ldr.CreateSymForUpdate("runtime.bss", 0)
1417 bss.SetSize(8)
1418 ldr.SetAttrSpecial(bss.Sym(), false)
1419
1420 ebss := ldr.CreateSymForUpdate("runtime.ebss", 0)
1421 ldr.SetAttrSpecial(ebss.Sym(), false)
1422
1423 data := ldr.CreateSymForUpdate("runtime.data", 0)
1424 data.SetSize(8)
1425 ldr.SetAttrSpecial(data.Sym(), false)
1426
1427 edata := ldr.CreateSymForUpdate("runtime.edata", 0)
1428 ldr.SetAttrSpecial(edata.Sym(), false)
1429
1430 if ctxt.HeadType == objabi.Haix {
1431
1432 edata.SetType(sym.SXCOFFTOC)
1433 }
1434
1435 noptrbss := ldr.CreateSymForUpdate("runtime.noptrbss", 0)
1436 noptrbss.SetSize(8)
1437 ldr.SetAttrSpecial(noptrbss.Sym(), false)
1438
1439 enoptrbss := ldr.CreateSymForUpdate("runtime.enoptrbss", 0)
1440 ldr.SetAttrSpecial(enoptrbss.Sym(), false)
1441
1442 noptrdata := ldr.CreateSymForUpdate("runtime.noptrdata", 0)
1443 noptrdata.SetSize(8)
1444 ldr.SetAttrSpecial(noptrdata.Sym(), false)
1445
1446 enoptrdata := ldr.CreateSymForUpdate("runtime.enoptrdata", 0)
1447 ldr.SetAttrSpecial(enoptrdata.Sym(), false)
1448
1449 types := ldr.CreateSymForUpdate("runtime.types", 0)
1450 types.SetType(sym.STYPE)
1451 types.SetSize(8)
1452 ldr.SetAttrSpecial(types.Sym(), false)
1453
1454 etypes := ldr.CreateSymForUpdate("runtime.etypes", 0)
1455 etypes.SetType(sym.SFUNCTAB)
1456 ldr.SetAttrSpecial(etypes.Sym(), false)
1457
1458 if ctxt.HeadType == objabi.Haix {
1459 rodata := ldr.CreateSymForUpdate("runtime.rodata", 0)
1460 rodata.SetType(sym.SSTRING)
1461 rodata.SetSize(8)
1462 ldr.SetAttrSpecial(rodata.Sym(), false)
1463
1464 erodata := ldr.CreateSymForUpdate("runtime.erodata", 0)
1465 ldr.SetAttrSpecial(erodata.Sym(), false)
1466 }
1467 }
1468
1469
1470 func (state *dodataState) makeRelroForSharedLib(target *Link) {
1471 if !target.UseRelro() {
1472 return
1473 }
1474
1475
1476
1477
1478 ldr := target.loader
1479 for _, symnro := range sym.ReadOnly {
1480 symnrelro := sym.RelROMap[symnro]
1481
1482 ro := []loader.Sym{}
1483 relro := state.data[symnrelro]
1484
1485 for _, s := range state.data[symnro] {
1486 relocs := ldr.Relocs(s)
1487 isRelro := relocs.Count() > 0
1488 switch state.symType(s) {
1489 case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
1490
1491
1492
1493 isRelro = true
1494 case sym.SFUNCTAB:
1495 if ldr.SymName(s) == "runtime.etypes" {
1496
1497
1498 isRelro = true
1499 }
1500 case sym.SGOFUNC:
1501
1502
1503
1504 isRelro = false
1505 }
1506 if isRelro {
1507 state.setSymType(s, symnrelro)
1508 if outer := ldr.OuterSym(s); outer != 0 {
1509 state.setSymType(outer, symnrelro)
1510 }
1511 relro = append(relro, s)
1512 } else {
1513 ro = append(ro, s)
1514 }
1515 }
1516
1517
1518
1519
1520
1521 for _, s := range relro {
1522 if outer := ldr.OuterSym(s); outer != 0 {
1523 st := state.symType(s)
1524 ost := state.symType(outer)
1525 if st != ost {
1526 state.ctxt.Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
1527 ldr.SymName(outer), st, ost)
1528 }
1529 }
1530 }
1531
1532 state.data[symnro] = ro
1533 state.data[symnrelro] = relro
1534 }
1535 }
1536
1537
1538
1539
1540 type dodataState struct {
1541
1542 ctxt *Link
1543
1544 data [sym.SXREF][]loader.Sym
1545
1546 dataMaxAlign [sym.SXREF]int32
1547
1548 symGroupType []sym.SymKind
1549
1550 datsize int64
1551 }
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565 func (state *dodataState) symType(s loader.Sym) sym.SymKind {
1566 if int(s) < len(state.symGroupType) {
1567 if override := state.symGroupType[s]; override != 0 {
1568 return override
1569 }
1570 }
1571 return state.ctxt.loader.SymType(s)
1572 }
1573
1574
1575 func (state *dodataState) setSymType(s loader.Sym, kind sym.SymKind) {
1576 if s == 0 {
1577 panic("bad")
1578 }
1579 if int(s) < len(state.symGroupType) {
1580 state.symGroupType[s] = kind
1581 } else {
1582 su := state.ctxt.loader.MakeSymbolUpdater(s)
1583 su.SetType(kind)
1584 }
1585 }
1586
1587 func (ctxt *Link) dodata(symGroupType []sym.SymKind) {
1588
1589
1590 fixZeroSizedSymbols(ctxt)
1591
1592
1593 state := dodataState{ctxt: ctxt, symGroupType: symGroupType}
1594 ldr := ctxt.loader
1595 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
1596 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || ldr.AttrSubSymbol(s) ||
1597 !ldr.TopLevelSym(s) {
1598 continue
1599 }
1600
1601 st := state.symType(s)
1602
1603 if st <= sym.STEXT || st >= sym.SXREF {
1604 continue
1605 }
1606 state.data[st] = append(state.data[st], s)
1607
1608
1609 if ldr.AttrOnList(s) {
1610 log.Fatalf("symbol %s listed multiple times", ldr.SymName(s))
1611 }
1612 ldr.SetAttrOnList(s, true)
1613 }
1614
1615
1616
1617
1618
1619
1620
1621 if ctxt.HeadType == objabi.Hdarwin {
1622 machosymorder(ctxt)
1623 }
1624 state.dynreloc(ctxt)
1625
1626
1627 state.makeRelroForSharedLib(ctxt)
1628
1629
1630
1631
1632
1633 lastSym := loader.Sym(ldr.NSym() - 1)
1634 ldr.SetSymAlign(lastSym, ldr.SymAlign(lastSym))
1635
1636
1637 var wg sync.WaitGroup
1638 for symn := range state.data {
1639 symn := sym.SymKind(symn)
1640 wg.Add(1)
1641 go func() {
1642 state.data[symn], state.dataMaxAlign[symn] = state.dodataSect(ctxt, symn, state.data[symn])
1643 wg.Done()
1644 }()
1645 }
1646 wg.Wait()
1647
1648 if ctxt.IsELF {
1649
1650
1651 syms := state.data[sym.SELFROSECT]
1652 reli, plti := -1, -1
1653 for i, s := range syms {
1654 switch ldr.SymName(s) {
1655 case ".rel.plt", ".rela.plt":
1656 plti = i
1657 case ".rel", ".rela":
1658 reli = i
1659 }
1660 }
1661 if reli >= 0 && plti >= 0 && plti != reli+1 {
1662 var first, second int
1663 if plti > reli {
1664 first, second = reli, plti
1665 } else {
1666 first, second = plti, reli
1667 }
1668 rel, plt := syms[reli], syms[plti]
1669 copy(syms[first+2:], syms[first+1:second])
1670 syms[first+0] = rel
1671 syms[first+1] = plt
1672
1673
1674
1675
1676
1677 ldr.SetSymAlign(rel, int32(ctxt.Arch.RegSize))
1678 ldr.SetSymAlign(plt, int32(ctxt.Arch.RegSize))
1679 }
1680 state.data[sym.SELFROSECT] = syms
1681 }
1682
1683 if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
1684
1685
1686 ldr.SetSymAlign(ldr.Lookup("runtime.data", 0), state.dataMaxAlign[sym.SDATA])
1687 ldr.SetSymAlign(ldr.Lookup("runtime.bss", 0), state.dataMaxAlign[sym.SBSS])
1688 }
1689
1690
1691
1692 state.allocateDataSections(ctxt)
1693
1694 state.allocateSEHSections(ctxt)
1695
1696
1697
1698 state.allocateDwarfSections(ctxt)
1699
1700
1701 n := int16(1)
1702
1703 for _, sect := range Segtext.Sections {
1704 sect.Extnum = n
1705 n++
1706 }
1707 for _, sect := range Segrodata.Sections {
1708 sect.Extnum = n
1709 n++
1710 }
1711 for _, sect := range Segrelrodata.Sections {
1712 sect.Extnum = n
1713 n++
1714 }
1715 for _, sect := range Segdata.Sections {
1716 sect.Extnum = n
1717 n++
1718 }
1719 for _, sect := range Segdwarf.Sections {
1720 sect.Extnum = n
1721 n++
1722 }
1723 for _, sect := range Segpdata.Sections {
1724 sect.Extnum = n
1725 n++
1726 }
1727 for _, sect := range Segxdata.Sections {
1728 sect.Extnum = n
1729 n++
1730 }
1731 }
1732
1733
1734
1735
1736
1737 func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section {
1738 ldr := state.ctxt.loader
1739 sname := ldr.SymName(s)
1740 if strings.HasPrefix(sname, "go:") {
1741 sname = ".go." + sname[len("go:"):]
1742 }
1743 sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx)
1744 sect.Align = symalign(ldr, s)
1745 state.datsize = Rnd(state.datsize, int64(sect.Align))
1746 sect.Vaddr = uint64(state.datsize)
1747 return sect
1748 }
1749
1750
1751
1752
1753
1754
1755 func (state *dodataState) allocateNamedDataSection(seg *sym.Segment, sName string, types []sym.SymKind, rwx int) *sym.Section {
1756 sect := addsection(state.ctxt.loader, state.ctxt.Arch, seg, sName, rwx)
1757 if len(types) == 0 {
1758 sect.Align = 1
1759 } else if len(types) == 1 {
1760 sect.Align = state.dataMaxAlign[types[0]]
1761 } else {
1762 for _, symn := range types {
1763 align := state.dataMaxAlign[symn]
1764 if sect.Align < align {
1765 sect.Align = align
1766 }
1767 }
1768 }
1769 state.datsize = Rnd(state.datsize, int64(sect.Align))
1770 sect.Vaddr = uint64(state.datsize)
1771 return sect
1772 }
1773
1774
1775
1776
1777
1778
1779
1780 func (state *dodataState) assignDsymsToSection(sect *sym.Section, syms []loader.Sym, forceType sym.SymKind, aligner func(state *dodataState, datsize int64, s loader.Sym) int64) {
1781 ldr := state.ctxt.loader
1782 for _, s := range syms {
1783 state.datsize = aligner(state, state.datsize, s)
1784 ldr.SetSymSect(s, sect)
1785 if forceType != sym.Sxxx {
1786 state.setSymType(s, forceType)
1787 }
1788 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
1789 state.datsize += ldr.SymSize(s)
1790 }
1791 sect.Length = uint64(state.datsize) - sect.Vaddr
1792 }
1793
1794 func (state *dodataState) assignToSection(sect *sym.Section, symn sym.SymKind, forceType sym.SymKind) {
1795 state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
1796 state.checkdatsize(symn)
1797 }
1798
1799
1800
1801
1802
1803
1804
1805 func (state *dodataState) allocateSingleSymSections(seg *sym.Segment, symn sym.SymKind, forceType sym.SymKind, rwx int) {
1806 ldr := state.ctxt.loader
1807 for _, s := range state.data[symn] {
1808 sect := state.allocateDataSectionForSym(seg, s, rwx)
1809 ldr.SetSymSect(s, sect)
1810 state.setSymType(s, forceType)
1811 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
1812 state.datsize += ldr.SymSize(s)
1813 sect.Length = uint64(state.datsize) - sect.Vaddr
1814 }
1815 state.checkdatsize(symn)
1816 }
1817
1818
1819
1820
1821
1822
1823
1824
1825 func (state *dodataState) allocateNamedSectionAndAssignSyms(seg *sym.Segment, secName string, symn sym.SymKind, forceType sym.SymKind, rwx int) *sym.Section {
1826
1827 sect := state.allocateNamedDataSection(seg, secName, []sym.SymKind{symn}, rwx)
1828 state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
1829 return sect
1830 }
1831
1832
1833
1834 func (state *dodataState) allocateDataSections(ctxt *Link) {
1835
1836
1837
1838
1839
1840
1841 writable := []sym.SymKind{
1842 sym.SBUILDINFO,
1843 sym.SELFSECT,
1844 sym.SMACHO,
1845 sym.SMACHOGOT,
1846 sym.SWINDOWS,
1847 }
1848 for _, symn := range writable {
1849 state.allocateSingleSymSections(&Segdata, symn, sym.SDATA, 06)
1850 }
1851 ldr := ctxt.loader
1852
1853
1854 if len(state.data[sym.SELFGOT]) > 0 {
1855 state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
1856 }
1857
1858
1859 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06)
1860 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrdata", 0), sect)
1861 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrdata", 0), sect)
1862
1863 hasinitarr := ctxt.linkShared
1864
1865
1866 switch ctxt.BuildMode {
1867 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
1868 hasinitarr = true
1869 }
1870
1871 if ctxt.HeadType == objabi.Haix {
1872 if len(state.data[sym.SINITARR]) > 0 {
1873 Errorf(nil, "XCOFF format doesn't allow .init_array section")
1874 }
1875 }
1876
1877 if hasinitarr && len(state.data[sym.SINITARR]) > 0 {
1878 state.allocateNamedSectionAndAssignSyms(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06)
1879 }
1880
1881
1882 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".data", sym.SDATA, sym.SDATA, 06)
1883 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.data", 0), sect)
1884 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.edata", 0), sect)
1885 dataGcEnd := state.datsize - int64(sect.Vaddr)
1886
1887
1888
1889 state.assignToSection(sect, sym.SXCOFFTOC, sym.SDATA)
1890 state.checkdatsize(sym.SDATA)
1891 sect.Length = uint64(state.datsize) - sect.Vaddr
1892
1893
1894 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06)
1895 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.bss", 0), sect)
1896 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect)
1897 bssGcEnd := state.datsize - int64(sect.Vaddr)
1898
1899
1900 gcsToEmit := []struct {
1901 symName string
1902 symKind sym.SymKind
1903 gcEnd int64
1904 }{
1905 {"runtime.gcdata", sym.SDATA, dataGcEnd},
1906 {"runtime.gcbss", sym.SBSS, bssGcEnd},
1907 }
1908 for _, g := range gcsToEmit {
1909 var gc GCProg
1910 gc.Init(ctxt, g.symName)
1911 for _, s := range state.data[g.symKind] {
1912 gc.AddSym(s)
1913 }
1914 gc.End(g.gcEnd)
1915 }
1916
1917
1918 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06)
1919 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrbss", 0), sect)
1920 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect)
1921
1922
1923
1924
1925 covCounterDataStartOff = sect.Length
1926 state.assignToSection(sect, sym.SCOVERAGE_COUNTER, sym.SNOPTRBSS)
1927 covCounterDataLen = sect.Length - covCounterDataStartOff
1928 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.covctrs", 0), sect)
1929 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ecovctrs", 0), sect)
1930
1931
1932 if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
1933 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
1934 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect)
1935 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect)
1936 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
1937 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
1938 }
1939
1940
1941 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), Segdata.Sections[len(Segdata.Sections)-1])
1942
1943 if len(state.data[sym.STLSBSS]) > 0 {
1944 var sect *sym.Section
1945
1946 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
1947 sect = addsection(ldr, ctxt.Arch, &Segdata, ".tbss", 06)
1948 sect.Align = int32(ctxt.Arch.PtrSize)
1949
1950 sect.Vaddr = 0
1951 }
1952 state.datsize = 0
1953
1954 for _, s := range state.data[sym.STLSBSS] {
1955 state.datsize = aligndatsize(state, state.datsize, s)
1956 if sect != nil {
1957 ldr.SetSymSect(s, sect)
1958 }
1959 ldr.SetSymValue(s, state.datsize)
1960 state.datsize += ldr.SymSize(s)
1961 }
1962 state.checkdatsize(sym.STLSBSS)
1963
1964 if sect != nil {
1965 sect.Length = uint64(state.datsize)
1966 }
1967 }
1968
1969
1978 var segro *sym.Segment
1979 if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
1980 segro = &Segrodata
1981 } else if ctxt.HeadType == objabi.Hwindows {
1982 segro = &Segrodata
1983 } else {
1984 segro = &Segtext
1985 }
1986
1987 state.datsize = 0
1988
1989
1990 if len(state.data[sym.STEXT]) != 0 {
1991 culprit := ldr.SymName(state.data[sym.STEXT][0])
1992 Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit)
1993 }
1994 state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05)
1995 state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05)
1996
1997
1998 sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
1999 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.rodata", 0), sect)
2000 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.erodata", 0), sect)
2001 if !ctxt.UseRelro() {
2002 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
2003 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
2004 }
2005 for _, symn := range sym.ReadOnly {
2006 symnStartValue := state.datsize
2007 if len(state.data[symn]) != 0 {
2008 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
2009 }
2010 state.assignToSection(sect, symn, sym.SRODATA)
2011 setCarrierSize(symn, state.datsize-symnStartValue)
2012 if ctxt.HeadType == objabi.Haix {
2013
2014
2015
2016
2017 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
2018 }
2019 }
2020
2021
2022 state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034 const relroPerm = 06
2035 const fallbackPerm = 04
2036 relroSecPerm := fallbackPerm
2037 genrelrosecname := func(suffix string) string {
2038 if suffix == "" {
2039 return ".rodata"
2040 }
2041 return suffix
2042 }
2043 seg := segro
2044
2045 if ctxt.UseRelro() {
2046 segrelro := &Segrelrodata
2047 if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() {
2048
2049
2050
2051
2052
2053
2054 segrelro = segro
2055 } else {
2056
2057 state.datsize = 0
2058 }
2059
2060 if !ctxt.IsDarwin() {
2061 genrelrosecname = func(suffix string) string {
2062 return ".data.rel.ro" + suffix
2063 }
2064 }
2065
2066 relroReadOnly := []sym.SymKind{}
2067 for _, symnro := range sym.ReadOnly {
2068 symn := sym.RelROMap[symnro]
2069 relroReadOnly = append(relroReadOnly, symn)
2070 }
2071 seg = segrelro
2072 relroSecPerm = relroPerm
2073
2074
2075 sect = state.allocateNamedDataSection(segrelro, genrelrosecname(""), relroReadOnly, relroSecPerm)
2076
2077 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
2078 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
2079
2080 for i, symnro := range sym.ReadOnly {
2081 if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix {
2082
2083
2084
2085
2086 state.datsize++
2087 }
2088
2089 symn := sym.RelROMap[symnro]
2090 symnStartValue := state.datsize
2091 if len(state.data[symn]) != 0 {
2092 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
2093 }
2094
2095 for _, s := range state.data[symn] {
2096 outer := ldr.OuterSym(s)
2097 if s != 0 && ldr.SymSect(outer) != nil && ldr.SymSect(outer) != sect {
2098 ctxt.Errorf(s, "s.Outer (%s) in different section from s, %s != %s", ldr.SymName(outer), ldr.SymSect(outer).Name, sect.Name)
2099 }
2100 }
2101 state.assignToSection(sect, symn, sym.SRODATA)
2102 setCarrierSize(symn, state.datsize-symnStartValue)
2103 if ctxt.HeadType == objabi.Haix {
2104
2105
2106
2107
2108 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
2109 }
2110 }
2111 sect.Length = uint64(state.datsize) - sect.Vaddr
2112
2113 state.allocateSingleSymSections(segrelro, sym.SELFRELROSECT, sym.SRODATA, relroSecPerm)
2114 }
2115
2116
2117 sect = state.allocateNamedDataSection(seg, genrelrosecname(".typelink"), []sym.SymKind{sym.STYPELINK}, relroSecPerm)
2118
2119 typelink := ldr.CreateSymForUpdate("runtime.typelink", 0)
2120 ldr.SetSymSect(typelink.Sym(), sect)
2121 typelink.SetType(sym.SRODATA)
2122 state.datsize += typelink.Size()
2123 state.checkdatsize(sym.STYPELINK)
2124 sect.Length = uint64(state.datsize) - sect.Vaddr
2125
2126
2127 sect = state.allocateNamedDataSection(seg, genrelrosecname(".itablink"), []sym.SymKind{sym.SITABLINK}, relroSecPerm)
2128
2129 itablink := ldr.CreateSymForUpdate("runtime.itablink", 0)
2130 ldr.SetSymSect(itablink.Sym(), sect)
2131 itablink.SetType(sym.SRODATA)
2132 state.datsize += itablink.Size()
2133 state.checkdatsize(sym.SITABLINK)
2134 sect.Length = uint64(state.datsize) - sect.Vaddr
2135
2136
2137 sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm)
2138 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.symtab", 0), sect)
2139 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.esymtab", 0), sect)
2140
2141
2142 sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm)
2143 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
2144 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect)
2145 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
2146 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
2147 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
2148 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
2149 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
2150 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
2151 setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
2152 if ctxt.HeadType == objabi.Haix {
2153 xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
2154 }
2155
2156
2157 if state.datsize != int64(uint32(state.datsize)) {
2158 Errorf(nil, "read-only data segment too large: %d", state.datsize)
2159 }
2160
2161 siz := 0
2162 for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
2163 siz += len(state.data[symn])
2164 }
2165 ctxt.datap = make([]loader.Sym, 0, siz)
2166 for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
2167 ctxt.datap = append(ctxt.datap, state.data[symn]...)
2168 }
2169 }
2170
2171
2172
2173 func (state *dodataState) allocateDwarfSections(ctxt *Link) {
2174
2175 alignOne := func(state *dodataState, datsize int64, s loader.Sym) int64 { return datsize }
2176
2177 ldr := ctxt.loader
2178 for i := 0; i < len(dwarfp); i++ {
2179
2180 s := dwarfp[i].secSym()
2181 sect := state.allocateNamedDataSection(&Segdwarf, ldr.SymName(s), []sym.SymKind{}, 04)
2182 ldr.SetSymSect(s, sect)
2183 sect.Sym = sym.LoaderSym(s)
2184 curType := ldr.SymType(s)
2185 state.setSymType(s, sym.SRODATA)
2186 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
2187 state.datsize += ldr.SymSize(s)
2188
2189
2190 subSyms := dwarfp[i].subSyms()
2191 state.assignDsymsToSection(sect, subSyms, sym.SRODATA, alignOne)
2192
2193 for j := 0; j < len(subSyms); j++ {
2194 s := subSyms[j]
2195 if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
2196
2197
2198 addDwsectCUSize(".debug_loc", ldr.SymPkg(s), uint64(ldr.SymSize(s)))
2199 }
2200 }
2201 sect.Length = uint64(state.datsize) - sect.Vaddr
2202 checkSectSize(sect)
2203 }
2204 }
2205
2206
2207
2208 func (state *dodataState) allocateSEHSections(ctxt *Link) {
2209 if len(sehp.pdata) > 0 {
2210 sect := state.allocateNamedDataSection(&Segpdata, ".pdata", []sym.SymKind{}, 04)
2211 state.assignDsymsToSection(sect, sehp.pdata, sym.SRODATA, aligndatsize)
2212 state.checkdatsize(sym.SSEHSECT)
2213 }
2214 if len(sehp.xdata) > 0 {
2215 sect := state.allocateNamedDataSection(&Segxdata, ".xdata", []sym.SymKind{}, 04)
2216 state.assignDsymsToSection(sect, sehp.xdata, sym.SRODATA, aligndatsize)
2217 state.checkdatsize(sym.SSEHSECT)
2218 }
2219 }
2220
2221 type symNameSize struct {
2222 name string
2223 sz int64
2224 val int64
2225 sym loader.Sym
2226 }
2227
2228 func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
2229 var head, tail, zerobase loader.Sym
2230 ldr := ctxt.loader
2231 sl := make([]symNameSize, len(syms))
2232
2233
2234
2235
2236
2237 checkSize := symn != sym.SELFGOT
2238
2239 for k, s := range syms {
2240 ss := ldr.SymSize(s)
2241 sl[k] = symNameSize{sz: ss, sym: s}
2242 if !checkSize {
2243 sl[k].name = ldr.SymName(s)
2244 }
2245 ds := int64(len(ldr.Data(s)))
2246 switch {
2247 case ss < ds:
2248 ctxt.Errorf(s, "initialize bounds (%d < %d)", ss, ds)
2249 case ss < 0:
2250 ctxt.Errorf(s, "negative size (%d bytes)", ss)
2251 case ss > cutoff:
2252 ctxt.Errorf(s, "symbol too large (%d bytes)", ss)
2253 }
2254
2255
2256
2257
2258 if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
2259 switch ldr.SymName(s) {
2260 case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata",
2261 "runtime.noptrdata", "runtime.noptrbss":
2262 head = s
2263 continue
2264 case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata",
2265 "runtime.enoptrdata", "runtime.enoptrbss":
2266 tail = s
2267 continue
2268 }
2269 }
2270 }
2271 zerobase = ldr.Lookup("runtime.zerobase", 0)
2272
2273
2274 if symn != sym.SPCLNTAB {
2275 sort.Slice(sl, func(i, j int) bool {
2276 si, sj := sl[i].sym, sl[j].sym
2277 isz, jsz := sl[i].sz, sl[j].sz
2278 switch {
2279 case si == head, sj == tail:
2280 return true
2281 case sj == head, si == tail:
2282 return false
2283
2284
2285 case si == zerobase:
2286 return jsz != 0
2287 case sj == zerobase:
2288 return isz == 0
2289 }
2290 if checkSize {
2291 if isz != jsz {
2292 return isz < jsz
2293 }
2294 } else {
2295 iname := sl[i].name
2296 jname := sl[j].name
2297 if iname != jname {
2298 return iname < jname
2299 }
2300 }
2301 return si < sj
2302 })
2303 } else {
2304
2305 }
2306
2307
2308 syms = syms[:0]
2309 for k := range sl {
2310 s := sl[k].sym
2311 if s != head && s != tail {
2312 align := symalign(ldr, s)
2313 if maxAlign < align {
2314 maxAlign = align
2315 }
2316 }
2317 syms = append(syms, s)
2318 }
2319
2320 return syms, maxAlign
2321 }
2322
2323
2324
2325
2326
2327
2328 func (ctxt *Link) textbuildid() {
2329 if ctxt.IsELF || *flagBuildid == "" {
2330 return
2331 }
2332
2333 ldr := ctxt.loader
2334 s := ldr.CreateSymForUpdate("go:buildid", 0)
2335
2336
2337 data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
2338 s.SetType(sym.STEXT)
2339 s.SetData([]byte(data))
2340 s.SetSize(int64(len(data)))
2341
2342 ctxt.Textp = append(ctxt.Textp, 0)
2343 copy(ctxt.Textp[1:], ctxt.Textp)
2344 ctxt.Textp[0] = s.Sym()
2345 }
2346
2347 func (ctxt *Link) buildinfo() {
2348
2349
2350 ldr := ctxt.loader
2351 s := ldr.CreateSymForUpdate("go:buildinfo", 0)
2352 s.SetType(sym.SBUILDINFO)
2353 s.SetAlign(16)
2354
2355
2356 const prefix = "\xff Go buildinf:"
2357 data := make([]byte, 32)
2358 copy(data, prefix)
2359 data[len(prefix)] = byte(ctxt.Arch.PtrSize)
2360 data[len(prefix)+1] = 0
2361 if ctxt.Arch.ByteOrder == binary.BigEndian {
2362 data[len(prefix)+1] = 1
2363 }
2364 data[len(prefix)+1] |= 2
2365 data = appendString(data, strdata["runtime.buildVersion"])
2366 data = appendString(data, strdata["runtime.modinfo"])
2367
2368 for len(data)%16 != 0 {
2369 data = append(data, 0)
2370 }
2371 s.SetData(data)
2372 s.SetSize(int64(len(data)))
2373
2374
2375
2376
2377 sr := ldr.CreateSymForUpdate("go:buildinfo.ref", 0)
2378 sr.SetType(sym.SRODATA)
2379 sr.SetAlign(int32(ctxt.Arch.PtrSize))
2380 sr.AddAddr(ctxt.Arch, s.Sym())
2381 }
2382
2383
2384 func appendString(data []byte, s string) []byte {
2385 var v [binary.MaxVarintLen64]byte
2386 n := binary.PutUvarint(v[:], uint64(len(s)))
2387 data = append(data, v[:n]...)
2388 data = append(data, s...)
2389 return data
2390 }
2391
2392
2393 func (ctxt *Link) textaddress() {
2394 addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2395
2396
2397
2398
2399 sect := Segtext.Sections[0]
2400
2401 sect.Align = int32(Funcalign)
2402
2403 ldr := ctxt.loader
2404
2405 if *flagRandLayout != 0 {
2406 r := rand.New(rand.NewSource(*flagRandLayout))
2407 textp := ctxt.Textp
2408 i := 0
2409
2410 if len(textp) > 0 && ldr.SymName(textp[0]) == "go:buildid" {
2411 i++
2412 }
2413
2414
2415
2416 for i < len(textp) && (ldr.SubSym(textp[i]) != 0 || ldr.AttrSubSymbol(textp[i])) {
2417 i++
2418 }
2419 textp = textp[i:]
2420 r.Shuffle(len(textp), func(i, j int) {
2421 textp[i], textp[j] = textp[j], textp[i]
2422 })
2423 }
2424
2425 text := ctxt.xdefine("runtime.text", sym.STEXT, 0)
2426 etext := ctxt.xdefine("runtime.etext", sym.STEXT, 0)
2427 ldr.SetSymSect(text, sect)
2428 if ctxt.IsAIX() && ctxt.IsExternal() {
2429
2430
2431
2432 u := ldr.MakeSymbolUpdater(text)
2433 u.SetAlign(sect.Align)
2434 u.SetSize(8)
2435 }
2436
2437 if (ctxt.DynlinkingGo() && ctxt.IsDarwin()) || (ctxt.IsAIX() && ctxt.IsExternal()) {
2438 ldr.SetSymSect(etext, sect)
2439 ctxt.Textp = append(ctxt.Textp, etext, 0)
2440 copy(ctxt.Textp[1:], ctxt.Textp)
2441 ctxt.Textp[0] = text
2442 }
2443
2444 start := uint64(Rnd(*FlagTextAddr, int64(Funcalign)))
2445 va := start
2446 n := 1
2447 sect.Vaddr = va
2448
2449 limit := thearch.TrampLimit
2450 if limit == 0 {
2451 limit = 1 << 63
2452 }
2453 if *FlagDebugTextSize != 0 {
2454 limit = uint64(*FlagDebugTextSize)
2455 }
2456 if *FlagDebugTramp > 1 {
2457 limit = 1
2458 }
2459
2460 if ctxt.IsAIX() && ctxt.IsExternal() {
2461
2462
2463
2464
2465
2466 limit = 1
2467 }
2468
2469
2470
2471 big := false
2472 for _, s := range ctxt.Textp {
2473 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2474 if va-start >= limit {
2475 big = true
2476 break
2477 }
2478 }
2479
2480
2481
2482 if big {
2483
2484 for _, s := range ctxt.Textp {
2485 if s != text {
2486 resetAddress(ctxt, s)
2487 }
2488 }
2489 va = start
2490
2491 ntramps := 0
2492 var curPkg string
2493 for i, s := range ctxt.Textp {
2494
2495
2496
2497
2498
2499 if symPkg := ldr.SymPkg(s); symPkg != "" && curPkg != symPkg {
2500 curPkg = symPkg
2501 vaTmp := va
2502 for j := i; j < len(ctxt.Textp); j++ {
2503 curSym := ctxt.Textp[j]
2504 if symPkg := ldr.SymPkg(curSym); symPkg == "" || curPkg != symPkg {
2505 break
2506 }
2507
2508
2509 sect, n, vaTmp = assignAddress(ctxt, sect, n, curSym, vaTmp, false, false)
2510 vaTmp += maxSizeTrampolines(ctxt, ldr, curSym, false)
2511 }
2512 }
2513
2514
2515 if s != text {
2516 resetAddress(ctxt, s)
2517 }
2518
2519
2520 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2521
2522
2523 trampoline(ctxt, s)
2524
2525
2526 for ; ntramps < len(ctxt.tramps); ntramps++ {
2527 tramp := ctxt.tramps[ntramps]
2528 if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") {
2529
2530 continue
2531 }
2532 sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true, big)
2533 }
2534 }
2535
2536
2537 if ntramps != 0 {
2538 newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
2539 i := 0
2540 for _, s := range ctxt.Textp {
2541 for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
2542 newtextp = append(newtextp, ctxt.tramps[i])
2543 }
2544 newtextp = append(newtextp, s)
2545 }
2546 newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
2547
2548 ctxt.Textp = newtextp
2549 }
2550 }
2551
2552
2553
2554 sect.Length = va - sect.Vaddr + uint64(ctxt.Arch.MinLC)
2555 ldr.SetSymSect(etext, sect)
2556 if ldr.SymValue(etext) == 0 {
2557
2558
2559 ldr.SetSymValue(etext, int64(va))
2560 ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr))
2561 }
2562 }
2563
2564
2565 func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) {
2566 ldr := ctxt.loader
2567 if thearch.AssignAddress != nil {
2568 return thearch.AssignAddress(ldr, sect, n, s, va, isTramp)
2569 }
2570
2571 ldr.SetSymSect(s, sect)
2572 if ldr.AttrSubSymbol(s) {
2573 return sect, n, va
2574 }
2575
2576 align := ldr.SymAlign(s)
2577 if align == 0 {
2578 align = int32(Funcalign)
2579 }
2580 va = uint64(Rnd(int64(va), int64(align)))
2581 if sect.Align < align {
2582 sect.Align = align
2583 }
2584
2585 funcsize := uint64(abi.MINFUNC)
2586 if ldr.SymSize(s) > abi.MINFUNC {
2587 funcsize = uint64(ldr.SymSize(s))
2588 }
2589
2590
2591
2592
2593
2594 if big && splitTextSections(ctxt) && ldr.OuterSym(s) == 0 {
2595
2596
2597 var textSizelimit uint64 = thearch.TrampLimit
2598 if *FlagDebugTextSize != 0 {
2599 textSizelimit = uint64(*FlagDebugTextSize)
2600 }
2601
2602
2603
2604 if funcsize > textSizelimit {
2605 panic(fmt.Sprintf("error: text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
2606 }
2607
2608 if va-sect.Vaddr+funcsize+maxSizeTrampolines(ctxt, ldr, s, isTramp) > textSizelimit {
2609 sectAlign := int32(thearch.Funcalign)
2610 if ctxt.IsPPC64() {
2611
2612
2613
2614
2615
2616
2617 const ppc64maxFuncalign = 64
2618 sectAlign = ppc64maxFuncalign
2619 va = uint64(Rnd(int64(va), ppc64maxFuncalign))
2620 }
2621
2622
2623 sect.Length = va - sect.Vaddr
2624
2625
2626 sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2627
2628 sect.Vaddr = va
2629 sect.Align = sectAlign
2630 ldr.SetSymSect(s, sect)
2631
2632
2633 ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
2634 ntext.SetSect(sect)
2635 if ctxt.IsAIX() {
2636
2637
2638
2639 ntext.SetType(sym.STEXT)
2640 ntext.SetSize(int64(abi.MINFUNC))
2641 ntext.SetOnList(true)
2642 ntext.SetAlign(sectAlign)
2643 ctxt.tramps = append(ctxt.tramps, ntext.Sym())
2644
2645 ntext.SetValue(int64(va))
2646 va += uint64(ntext.Size())
2647
2648 if align := ldr.SymAlign(s); align != 0 {
2649 va = uint64(Rnd(int64(va), int64(align)))
2650 } else {
2651 va = uint64(Rnd(int64(va), int64(Funcalign)))
2652 }
2653 }
2654 n++
2655 }
2656 }
2657
2658 ldr.SetSymValue(s, 0)
2659 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2660 ldr.SetSymValue(sub, ldr.SymValue(sub)+int64(va))
2661 if ctxt.Debugvlog > 2 {
2662 fmt.Println("assign text address:", ldr.SymName(sub), ldr.SymValue(sub))
2663 }
2664 }
2665
2666 va += funcsize
2667
2668 return sect, n, va
2669 }
2670
2671 func resetAddress(ctxt *Link, s loader.Sym) {
2672 ldr := ctxt.loader
2673 if ldr.OuterSym(s) != 0 {
2674 return
2675 }
2676 oldv := ldr.SymValue(s)
2677 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2678 ldr.SetSymValue(sub, ldr.SymValue(sub)-oldv)
2679 }
2680 }
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698 func splitTextSections(ctxt *Link) bool {
2699 return (ctxt.IsARM() || ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
2700 }
2701
2702
2703
2704
2705
2706 const wasmMinDataAddr = 4096 + 8192
2707
2708
2709
2710 func (ctxt *Link) address() []*sym.Segment {
2711 var order []*sym.Segment
2712
2713 va := uint64(*FlagTextAddr)
2714 order = append(order, &Segtext)
2715 Segtext.Rwx = 05
2716 Segtext.Vaddr = va
2717 for i, s := range Segtext.Sections {
2718 va = uint64(Rnd(int64(va), int64(s.Align)))
2719 s.Vaddr = va
2720 va += s.Length
2721
2722 if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr {
2723 va = wasmMinDataAddr
2724 }
2725 }
2726
2727 Segtext.Length = va - uint64(*FlagTextAddr)
2728
2729 if len(Segrodata.Sections) > 0 {
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743 va = uint64(Rnd(int64(va), *FlagRound))
2744
2745 order = append(order, &Segrodata)
2746 Segrodata.Rwx = 04
2747 Segrodata.Vaddr = va
2748 for _, s := range Segrodata.Sections {
2749 va = uint64(Rnd(int64(va), int64(s.Align)))
2750 s.Vaddr = va
2751 va += s.Length
2752 }
2753
2754 Segrodata.Length = va - Segrodata.Vaddr
2755 }
2756 if len(Segrelrodata.Sections) > 0 {
2757
2758
2759 va = uint64(Rnd(int64(va), *FlagRound))
2760 if ctxt.HeadType == objabi.Haix {
2761
2762 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2763 }
2764
2765 order = append(order, &Segrelrodata)
2766 Segrelrodata.Rwx = 06
2767 Segrelrodata.Vaddr = va
2768 for _, s := range Segrelrodata.Sections {
2769 va = uint64(Rnd(int64(va), int64(s.Align)))
2770 s.Vaddr = va
2771 va += s.Length
2772 }
2773
2774 Segrelrodata.Length = va - Segrelrodata.Vaddr
2775 }
2776
2777 va = uint64(Rnd(int64(va), *FlagRound))
2778 if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 {
2779
2780
2781
2782 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2783 }
2784 order = append(order, &Segdata)
2785 Segdata.Rwx = 06
2786 Segdata.Vaddr = va
2787 var data *sym.Section
2788 var noptr *sym.Section
2789 var bss *sym.Section
2790 var noptrbss *sym.Section
2791 var fuzzCounters *sym.Section
2792 for i, s := range Segdata.Sections {
2793 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" {
2794 continue
2795 }
2796 vlen := int64(s.Length)
2797 if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") {
2798 vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
2799 }
2800 s.Vaddr = va
2801 va += uint64(vlen)
2802 Segdata.Length = va - Segdata.Vaddr
2803 switch s.Name {
2804 case ".data":
2805 data = s
2806 case ".noptrdata":
2807 noptr = s
2808 case ".bss":
2809 bss = s
2810 case ".noptrbss":
2811 noptrbss = s
2812 case ".go.fuzzcntrs":
2813 fuzzCounters = s
2814 }
2815 }
2816
2817
2818
2819 Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
2820
2821 if len(Segpdata.Sections) > 0 {
2822 va = uint64(Rnd(int64(va), *FlagRound))
2823 order = append(order, &Segpdata)
2824 Segpdata.Rwx = 04
2825 Segpdata.Vaddr = va
2826
2827
2828 for _, s := range Segpdata.Sections {
2829 va = uint64(Rnd(int64(va), int64(s.Align)))
2830 s.Vaddr = va
2831 va += s.Length
2832 }
2833 Segpdata.Length = va - Segpdata.Vaddr
2834 }
2835
2836 if len(Segxdata.Sections) > 0 {
2837 va = uint64(Rnd(int64(va), *FlagRound))
2838 order = append(order, &Segxdata)
2839 Segxdata.Rwx = 04
2840 Segxdata.Vaddr = va
2841
2842
2843 for _, s := range Segxdata.Sections {
2844 va = uint64(Rnd(int64(va), int64(s.Align)))
2845 s.Vaddr = va
2846 va += s.Length
2847 }
2848 Segxdata.Length = va - Segxdata.Vaddr
2849 }
2850
2851 va = uint64(Rnd(int64(va), *FlagRound))
2852 order = append(order, &Segdwarf)
2853 Segdwarf.Rwx = 06
2854 Segdwarf.Vaddr = va
2855 for i, s := range Segdwarf.Sections {
2856 vlen := int64(s.Length)
2857 if i+1 < len(Segdwarf.Sections) {
2858 vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
2859 }
2860 s.Vaddr = va
2861 va += uint64(vlen)
2862 if ctxt.HeadType == objabi.Hwindows {
2863 va = uint64(Rnd(int64(va), PEFILEALIGN))
2864 }
2865 Segdwarf.Length = va - Segdwarf.Vaddr
2866 }
2867
2868 ldr := ctxt.loader
2869 var (
2870 rodata = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0))
2871 symtab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0))
2872 pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0))
2873 types = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0))
2874 )
2875
2876 for _, s := range ctxt.datap {
2877 if sect := ldr.SymSect(s); sect != nil {
2878 ldr.AddToSymValue(s, int64(sect.Vaddr))
2879 }
2880 v := ldr.SymValue(s)
2881 for sub := ldr.SubSym(s); sub != 0; sub = ldr.SubSym(sub) {
2882 ldr.AddToSymValue(sub, v)
2883 }
2884 }
2885
2886 for _, si := range dwarfp {
2887 for _, s := range si.syms {
2888 if sect := ldr.SymSect(s); sect != nil {
2889 ldr.AddToSymValue(s, int64(sect.Vaddr))
2890 }
2891 sub := ldr.SubSym(s)
2892 if sub != 0 {
2893 panic(fmt.Sprintf("unexpected sub-sym for %s %s", ldr.SymName(s), ldr.SymType(s).String()))
2894 }
2895 v := ldr.SymValue(s)
2896 for ; sub != 0; sub = ldr.SubSym(sub) {
2897 ldr.AddToSymValue(s, v)
2898 }
2899 }
2900 }
2901
2902 for _, s := range sehp.pdata {
2903 if sect := ldr.SymSect(s); sect != nil {
2904 ldr.AddToSymValue(s, int64(sect.Vaddr))
2905 }
2906 }
2907 for _, s := range sehp.xdata {
2908 if sect := ldr.SymSect(s); sect != nil {
2909 ldr.AddToSymValue(s, int64(sect.Vaddr))
2910 }
2911 }
2912
2913 if ctxt.BuildMode == BuildModeShared {
2914 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
2915 sect := ldr.SymSect(ldr.LookupOrCreateSym(".note.go.abihash", 0))
2916 ldr.SetSymSect(s, sect)
2917 ldr.SetSymValue(s, int64(sect.Vaddr+16))
2918 }
2919
2920
2921
2922 n := 1
2923 for _, sect := range Segtext.Sections[1:] {
2924 if sect.Name != ".text" {
2925 break
2926 }
2927 symname := fmt.Sprintf("runtime.text.%d", n)
2928 if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal {
2929
2930
2931 ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
2932 }
2933 n++
2934 }
2935
2936 ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
2937 ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
2938 ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
2939 ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
2940
2941 s := ldr.Lookup("runtime.gcdata", 0)
2942 ldr.SetAttrLocal(s, true)
2943 ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
2944 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s))
2945
2946 s = ldr.LookupOrCreateSym("runtime.gcbss", 0)
2947 ldr.SetAttrLocal(s, true)
2948 ctxt.xdefine("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
2949 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcbss", 0), ldr.SymSect(s))
2950
2951 ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
2952 ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
2953 ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
2954 ctxt.defineInternal("runtime.pcheader", sym.SRODATA)
2955 ctxt.defineInternal("runtime.funcnametab", sym.SRODATA)
2956 ctxt.defineInternal("runtime.cutab", sym.SRODATA)
2957 ctxt.defineInternal("runtime.filetab", sym.SRODATA)
2958 ctxt.defineInternal("runtime.pctab", sym.SRODATA)
2959 ctxt.defineInternal("runtime.functab", sym.SRODATA)
2960 ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
2961 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
2962 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
2963 ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
2964 ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
2965 ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
2966 ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
2967 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
2968 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
2969 ctxt.xdefine("runtime.covctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff))
2970 ctxt.xdefine("runtime.ecovctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff+covCounterDataLen))
2971 ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
2972
2973 if fuzzCounters != nil {
2974 ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
2975 ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
2976 ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
2977 ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
2978 }
2979
2980 if ctxt.IsSolaris() {
2981
2982
2983
2984 etext := ldr.Lookup("runtime.etext", 0)
2985 edata := ldr.Lookup("runtime.edata", 0)
2986 end := ldr.Lookup("runtime.end", 0)
2987 ldr.SetSymExtname(etext, "runtime.etext")
2988 ldr.SetSymExtname(edata, "runtime.edata")
2989 ldr.SetSymExtname(end, "runtime.end")
2990 ctxt.xdefine("_etext", ldr.SymType(etext), ldr.SymValue(etext))
2991 ctxt.xdefine("_edata", ldr.SymType(edata), ldr.SymValue(edata))
2992 ctxt.xdefine("_end", ldr.SymType(end), ldr.SymValue(end))
2993 ldr.SetSymSect(ldr.Lookup("_etext", 0), ldr.SymSect(etext))
2994 ldr.SetSymSect(ldr.Lookup("_edata", 0), ldr.SymSect(edata))
2995 ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
2996 }
2997
2998 if ctxt.IsPPC64() && ctxt.IsElf() {
2999
3000
3001
3002 tocAddr := int64(Segdata.Vaddr) + 0x8000
3003 if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
3004 tocAddr = gotAddr + 0x8000
3005 }
3006 for i := range ctxt.DotTOC {
3007 if i >= sym.SymVerABICount && i < sym.SymVerStatic {
3008 continue
3009 }
3010 if toc := ldr.Lookup(".TOC.", i); toc != 0 {
3011 ldr.SetSymValue(toc, tocAddr)
3012 }
3013 }
3014 }
3015
3016 return order
3017 }
3018
3019
3020
3021 func (ctxt *Link) layout(order []*sym.Segment) uint64 {
3022 var prev *sym.Segment
3023 for _, seg := range order {
3024 if prev == nil {
3025 seg.Fileoff = uint64(HEADR)
3026 } else {
3027 switch ctxt.HeadType {
3028 default:
3029
3030
3031
3032
3033 seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), *FlagRound))
3034 if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) {
3035 Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound)
3036 }
3037 case objabi.Hwindows:
3038 seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN))
3039 case objabi.Hplan9:
3040 seg.Fileoff = prev.Fileoff + prev.Filelen
3041 }
3042 }
3043 if seg != &Segdata {
3044
3045
3046 seg.Filelen = seg.Length
3047 }
3048 prev = seg
3049 }
3050 return prev.Fileoff + prev.Filelen
3051 }
3052
3053
3054 func (ctxt *Link) AddTramp(s *loader.SymbolBuilder) {
3055 s.SetType(sym.STEXT)
3056 s.SetReachable(true)
3057 s.SetOnList(true)
3058 ctxt.tramps = append(ctxt.tramps, s.Sym())
3059 if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
3060 ctxt.Logf("trampoline %s inserted\n", s.Name())
3061 }
3062 }
3063
3064
3065
3066 func compressSyms(ctxt *Link, syms []loader.Sym) []byte {
3067 ldr := ctxt.loader
3068 var total int64
3069 for _, sym := range syms {
3070 total += ldr.SymSize(sym)
3071 }
3072
3073 var buf bytes.Buffer
3074 if ctxt.IsELF {
3075 switch ctxt.Arch.PtrSize {
3076 case 8:
3077 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{
3078 Type: uint32(elf.COMPRESS_ZLIB),
3079 Size: uint64(total),
3080 Addralign: uint64(ctxt.Arch.Alignment),
3081 })
3082 case 4:
3083 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{
3084 Type: uint32(elf.COMPRESS_ZLIB),
3085 Size: uint32(total),
3086 Addralign: uint32(ctxt.Arch.Alignment),
3087 })
3088 default:
3089 log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize)
3090 }
3091 } else {
3092 buf.Write([]byte("ZLIB"))
3093 var sizeBytes [8]byte
3094 binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
3095 buf.Write(sizeBytes[:])
3096 }
3097
3098 var relocbuf []byte
3099
3100
3101
3102
3103
3104 z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
3105 if err != nil {
3106 log.Fatalf("NewWriterLevel failed: %s", err)
3107 }
3108 st := ctxt.makeRelocSymState()
3109 for _, s := range syms {
3110
3111
3112 P := ldr.Data(s)
3113 relocs := ldr.Relocs(s)
3114 if relocs.Count() != 0 {
3115 relocbuf = append(relocbuf[:0], P...)
3116 P = relocbuf
3117 st.relocsym(s, P)
3118 }
3119 if _, err := z.Write(P); err != nil {
3120 log.Fatalf("compression failed: %s", err)
3121 }
3122 for i := ldr.SymSize(s) - int64(len(P)); i > 0; {
3123 b := zeros[:]
3124 if i < int64(len(b)) {
3125 b = b[:i]
3126 }
3127 n, err := z.Write(b)
3128 if err != nil {
3129 log.Fatalf("compression failed: %s", err)
3130 }
3131 i -= int64(n)
3132 }
3133 }
3134 if err := z.Close(); err != nil {
3135 log.Fatalf("compression failed: %s", err)
3136 }
3137 if int64(buf.Len()) >= total {
3138
3139 return nil
3140 }
3141 return buf.Bytes()
3142 }
3143
View as plain text