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