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