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