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 if len(state.data[sym.SELFGOT]) > 0 {
1942 state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
1943 }
1944 if len(state.data[sym.SMACHOGOT]) > 0 {
1945 state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SMACHOGOT, sym.SDATA, 06)
1946 }
1947
1948
1949 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06)
1950 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrdata", 0), sect)
1951 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrdata", 0), sect)
1952
1953 state.assignToSection(sect, sym.SNOPTRDATAFIPSSTART, sym.SDATA)
1954 state.assignToSection(sect, sym.SNOPTRDATAFIPS, sym.SDATA)
1955 state.assignToSection(sect, sym.SNOPTRDATAFIPSEND, sym.SDATA)
1956 state.assignToSection(sect, sym.SNOPTRDATAEND, sym.SDATA)
1957
1958 hasinitarr := ctxt.linkShared
1959
1960
1961 switch ctxt.BuildMode {
1962 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
1963 hasinitarr = true
1964 }
1965
1966 if ctxt.HeadType == objabi.Haix {
1967 if len(state.data[sym.SINITARR]) > 0 {
1968 Errorf("XCOFF format doesn't allow .init_array section")
1969 }
1970 }
1971
1972 if hasinitarr && len(state.data[sym.SINITARR]) > 0 {
1973 state.allocateNamedSectionAndAssignSyms(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06)
1974 }
1975
1976
1977 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".data", sym.SDATA, sym.SDATA, 06)
1978 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.data", 0), sect)
1979 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.edata", 0), sect)
1980
1981 state.assignToSection(sect, sym.SDATAFIPSSTART, sym.SDATA)
1982 state.assignToSection(sect, sym.SDATAFIPS, sym.SDATA)
1983 state.assignToSection(sect, sym.SDATAFIPSEND, sym.SDATA)
1984 state.assignToSection(sect, sym.SDATAEND, sym.SDATA)
1985
1986 dataGcEnd := state.datsize - int64(sect.Vaddr)
1987
1988
1989
1990 state.assignToSection(sect, sym.SXCOFFTOC, sym.SDATA)
1991 state.checkdatsize(sym.SDATA)
1992 sect.Length = uint64(state.datsize) - sect.Vaddr
1993
1994
1995 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06)
1996 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.bss", 0), sect)
1997 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect)
1998 bssGcEnd := state.datsize - int64(sect.Vaddr)
1999
2000
2001 gcsToEmit := []struct {
2002 symName string
2003 symKind sym.SymKind
2004 gcEnd int64
2005 }{
2006 {"runtime.gcdata", sym.SDATA, dataGcEnd},
2007 {"runtime.gcbss", sym.SBSS, bssGcEnd},
2008 }
2009 for _, g := range gcsToEmit {
2010 var gc GCProg
2011 gc.Init(ctxt, g.symName)
2012 for _, s := range state.data[g.symKind] {
2013 gc.AddSym(s)
2014 }
2015 gc.End(g.gcEnd)
2016 }
2017
2018
2019 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06)
2020 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrbss", 0), sect)
2021 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect)
2022
2023
2024
2025
2026 covCounterDataStartOff = sect.Length
2027 state.assignToSection(sect, sym.SCOVERAGE_COUNTER, sym.SNOPTRBSS)
2028 covCounterDataLen = sect.Length - covCounterDataStartOff
2029 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.covctrs", 0), sect)
2030 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ecovctrs", 0), sect)
2031
2032
2033 if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
2034 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
2035 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect)
2036 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect)
2037 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
2038 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
2039 }
2040
2041
2042 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), Segdata.Sections[len(Segdata.Sections)-1])
2043
2044 if len(state.data[sym.STLSBSS]) > 0 {
2045 var sect *sym.Section
2046
2047 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
2048 sect = addsection(ldr, ctxt.Arch, &Segdata, ".tbss", 06)
2049 sect.Align = int32(ctxt.Arch.PtrSize)
2050
2051 sect.Vaddr = 0
2052 }
2053 state.datsize = 0
2054
2055 for _, s := range state.data[sym.STLSBSS] {
2056 state.datsize = aligndatsize(state, state.datsize, s)
2057 if sect != nil {
2058 ldr.SetSymSect(s, sect)
2059 }
2060 ldr.SetSymValue(s, state.datsize)
2061 state.datsize += ldr.SymSize(s)
2062 }
2063 state.checkdatsize(sym.STLSBSS)
2064
2065 if sect != nil {
2066 sect.Length = uint64(state.datsize)
2067 }
2068 }
2069
2070
2079 var segro *sym.Segment
2080 if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
2081 segro = &Segrodata
2082 } else if ctxt.HeadType == objabi.Hwindows {
2083 segro = &Segrodata
2084 } else {
2085 segro = &Segtext
2086 }
2087
2088 state.datsize = 0
2089
2090
2091 if len(state.data[sym.STEXT]) != 0 {
2092 culprit := ldr.SymName(state.data[sym.STEXT][0])
2093 Errorf("dodata found an sym.STEXT symbol: %s", culprit)
2094 }
2095 state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05)
2096 state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05)
2097
2098
2099 sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
2100 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.rodata", 0), sect)
2101 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.erodata", 0), sect)
2102 if !ctxt.UseRelro() {
2103 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
2104 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
2105 }
2106 for _, symn := range sym.ReadOnly {
2107 symnStartValue := state.datsize
2108 if len(state.data[symn]) != 0 {
2109 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
2110 }
2111 state.assignToSection(sect, symn, sym.SRODATA)
2112 setCarrierSize(symn, state.datsize-symnStartValue)
2113 if ctxt.HeadType == objabi.Haix {
2114
2115
2116
2117
2118 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
2119 }
2120 }
2121
2122
2123 sect = state.allocateNamedSectionAndAssignSyms(segro, ".gopclntab", sym.SPCLNTAB, sym.SRODATA, 04)
2124 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
2125 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect)
2126 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
2127 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
2128 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
2129 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
2130 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
2131 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
2132 setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
2133 if ctxt.HeadType == objabi.Haix {
2134 xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
2135 }
2136
2137
2138 state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150 const relroPerm = 06
2151 const fallbackPerm = 04
2152 relroSecPerm := fallbackPerm
2153 genrelrosecname := func(suffix string) string {
2154 if suffix == "" {
2155 return ".rodata"
2156 }
2157 return suffix
2158 }
2159 seg := segro
2160
2161 if ctxt.UseRelro() {
2162 segrelro := &Segrelrodata
2163 if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() {
2164
2165
2166
2167
2168
2169
2170 segrelro = segro
2171 } else {
2172
2173 state.datsize = 0
2174 }
2175
2176 if !ctxt.IsDarwin() {
2177 genrelrosecname = func(suffix string) string {
2178 return ".data.rel.ro" + suffix
2179 }
2180 }
2181
2182 relroReadOnly := []sym.SymKind{}
2183 for _, symnro := range sym.ReadOnly {
2184 symn := sym.RelROMap[symnro]
2185 relroReadOnly = append(relroReadOnly, symn)
2186 }
2187 seg = segrelro
2188 relroSecPerm = relroPerm
2189
2190
2191 sect = state.allocateNamedDataSection(segrelro, genrelrosecname(""), relroReadOnly, relroSecPerm)
2192
2193 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
2194 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
2195
2196 for i, symnro := range sym.ReadOnly {
2197 if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix {
2198
2199
2200
2201
2202 state.datsize++
2203 }
2204
2205 symn := sym.RelROMap[symnro]
2206 if symn == sym.Sxxx {
2207 continue
2208 }
2209 symnStartValue := state.datsize
2210 if len(state.data[symn]) != 0 {
2211 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
2212 }
2213
2214 for _, s := range state.data[symn] {
2215 outer := ldr.OuterSym(s)
2216 if s != 0 && ldr.SymSect(outer) != nil && ldr.SymSect(outer) != sect {
2217 ctxt.Errorf(s, "s.Outer (%s) in different section from s, %s != %s", ldr.SymName(outer), ldr.SymSect(outer).Name, sect.Name)
2218 }
2219 }
2220 state.assignToSection(sect, symn, sym.SRODATA)
2221 setCarrierSize(symn, state.datsize-symnStartValue)
2222 if ctxt.HeadType == objabi.Haix {
2223
2224
2225
2226
2227 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
2228 }
2229 }
2230 sect.Length = uint64(state.datsize) - sect.Vaddr
2231
2232 state.allocateSingleSymSections(segrelro, sym.SELFRELROSECT, sym.SRODATA, relroSecPerm)
2233 state.allocateSingleSymSections(segrelro, sym.SMACHORELROSECT, sym.SRODATA, relroSecPerm)
2234 }
2235
2236
2237 sect = state.allocateNamedDataSection(seg, genrelrosecname(".typelink"), []sym.SymKind{sym.STYPELINK}, relroSecPerm)
2238
2239 typelink := ldr.CreateSymForUpdate("runtime.typelink", 0)
2240 ldr.SetSymSect(typelink.Sym(), sect)
2241 typelink.SetType(sym.SRODATA)
2242 state.datsize += typelink.Size()
2243 state.checkdatsize(sym.STYPELINK)
2244 sect.Length = uint64(state.datsize) - sect.Vaddr
2245
2246
2247 sect = state.allocateNamedDataSection(seg, genrelrosecname(".itablink"), []sym.SymKind{sym.SITABLINK}, relroSecPerm)
2248
2249 itablink := ldr.CreateSymForUpdate("runtime.itablink", 0)
2250 ldr.SetSymSect(itablink.Sym(), sect)
2251 itablink.SetType(sym.SRODATA)
2252 state.datsize += itablink.Size()
2253 state.checkdatsize(sym.SITABLINK)
2254 sect.Length = uint64(state.datsize) - sect.Vaddr
2255
2256
2257 if state.datsize != int64(uint32(state.datsize)) {
2258 Errorf("read-only data segment too large: %d", state.datsize)
2259 }
2260
2261 siz := 0
2262 for symn := sym.SELFRXSECT; symn < sym.SFirstUnallocated; symn++ {
2263 siz += len(state.data[symn])
2264 }
2265 ctxt.datap = make([]loader.Sym, 0, siz)
2266 for symn := sym.SELFRXSECT; symn < sym.SFirstUnallocated; symn++ {
2267 ctxt.datap = append(ctxt.datap, state.data[symn]...)
2268 }
2269 }
2270
2271
2272
2273 func (state *dodataState) allocateDwarfSections(ctxt *Link) {
2274
2275 alignOne := func(state *dodataState, datsize int64, s loader.Sym) int64 { return datsize }
2276
2277 ldr := ctxt.loader
2278 for i := 0; i < len(dwarfp); i++ {
2279
2280 s := dwarfp[i].secSym()
2281 sect := state.allocateNamedDataSection(&Segdwarf, ldr.SymName(s), []sym.SymKind{}, 04)
2282 ldr.SetSymSect(s, sect)
2283 sect.Sym = s
2284 curType := ldr.SymType(s)
2285 state.setSymType(s, sym.SRODATA)
2286 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
2287 state.datsize += ldr.SymSize(s)
2288
2289
2290 subSyms := dwarfp[i].subSyms()
2291 state.assignDsymsToSection(sect, subSyms, sym.SRODATA, alignOne)
2292
2293 for j := 0; j < len(subSyms); j++ {
2294 s := subSyms[j]
2295 if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
2296
2297
2298 addDwsectCUSize(".debug_loc", ldr.SymPkg(s), uint64(ldr.SymSize(s)))
2299 }
2300 }
2301 sect.Length = uint64(state.datsize) - sect.Vaddr
2302 checkSectSize(sect)
2303 }
2304 }
2305
2306
2307
2308 func (state *dodataState) allocateSEHSections(ctxt *Link) {
2309 if len(sehp.pdata) > 0 {
2310 sect := state.allocateNamedDataSection(&Segpdata, ".pdata", []sym.SymKind{}, 04)
2311 state.assignDsymsToSection(sect, sehp.pdata, sym.SRODATA, aligndatsize)
2312 state.checkdatsize(sym.SSEHSECT)
2313 }
2314 if len(sehp.xdata) > 0 {
2315 sect := state.allocateNamedDataSection(&Segxdata, ".xdata", []sym.SymKind{}, 04)
2316 state.assignDsymsToSection(sect, sehp.xdata, sym.SRODATA, aligndatsize)
2317 state.checkdatsize(sym.SSEHSECT)
2318 }
2319 }
2320
2321 type symNameSize struct {
2322 name string
2323 sz int64
2324 val int64
2325 sym loader.Sym
2326 }
2327
2328 func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
2329 var head, tail, zerobase loader.Sym
2330 ldr := ctxt.loader
2331 sl := make([]symNameSize, len(syms))
2332
2333
2334
2335
2336
2337 sortBySize := symn != sym.SELFGOT
2338
2339 for k, s := range syms {
2340 ss := ldr.SymSize(s)
2341 sl[k] = symNameSize{sz: ss, sym: s}
2342 if !sortBySize {
2343 sl[k].name = ldr.SymName(s)
2344 }
2345 ds := int64(len(ldr.Data(s)))
2346 switch {
2347 case ss < ds:
2348 ctxt.Errorf(s, "initialize bounds (%d < %d)", ss, ds)
2349 case ss < 0:
2350 ctxt.Errorf(s, "negative size (%d bytes)", ss)
2351 case ss > cutoff:
2352 ctxt.Errorf(s, "symbol too large (%d bytes)", ss)
2353 }
2354
2355
2356
2357
2358 if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
2359 switch ldr.SymName(s) {
2360 case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata",
2361 "runtime.noptrdata", "runtime.noptrbss":
2362 head = s
2363 continue
2364 case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata",
2365 "runtime.enoptrdata", "runtime.enoptrbss":
2366 tail = s
2367 continue
2368 }
2369 }
2370 }
2371 zerobase = ldr.Lookup("runtime.zerobase", 0)
2372
2373
2374 if symn != sym.SPCLNTAB {
2375 sort.Slice(sl, func(i, j int) bool {
2376 si, sj := sl[i].sym, sl[j].sym
2377 isz, jsz := sl[i].sz, sl[j].sz
2378 switch {
2379 case si == head, sj == tail:
2380 return true
2381 case sj == head, si == tail:
2382 return false
2383 }
2384 if sortBySize {
2385 switch {
2386
2387
2388 case si == zerobase:
2389 return jsz != 0
2390 case sj == zerobase:
2391 return isz == 0
2392 case isz != jsz:
2393 return isz < jsz
2394 }
2395 } else {
2396 iname := sl[i].name
2397 jname := sl[j].name
2398 if iname != jname {
2399 return iname < jname
2400 }
2401 }
2402 return si < sj
2403 })
2404 } else {
2405
2406 }
2407
2408
2409 syms = syms[:0]
2410 for k := range sl {
2411 s := sl[k].sym
2412 if s != head && s != tail {
2413 align := symalign(ldr, s)
2414 if maxAlign < align {
2415 maxAlign = align
2416 }
2417 }
2418 syms = append(syms, s)
2419 }
2420
2421 return syms, maxAlign
2422 }
2423
2424
2425
2426
2427
2428
2429 func (ctxt *Link) textbuildid() {
2430 if ctxt.IsELF || *flagBuildid == "" {
2431 return
2432 }
2433
2434 ldr := ctxt.loader
2435 s := ldr.CreateSymForUpdate("go:buildid", 0)
2436
2437
2438 data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
2439 s.SetType(sym.STEXT)
2440 s.SetData([]byte(data))
2441 s.SetSize(int64(len(data)))
2442
2443 ctxt.Textp = append(ctxt.Textp, 0)
2444 copy(ctxt.Textp[1:], ctxt.Textp)
2445 ctxt.Textp[0] = s.Sym()
2446 }
2447
2448 func (ctxt *Link) buildinfo() {
2449
2450
2451 ldr := ctxt.loader
2452 s := ldr.CreateSymForUpdate("go:buildinfo", 0)
2453 s.SetType(sym.SBUILDINFO)
2454 s.SetAlign(16)
2455
2456
2457
2458 const prefix = "\xff Go buildinf:"
2459
2460
2461
2462 data := make([]byte, 32)
2463 copy(data, prefix)
2464 data[len(prefix)] = byte(ctxt.Arch.PtrSize)
2465 data[len(prefix)+1] = 0
2466 if ctxt.Arch.ByteOrder == binary.BigEndian {
2467 data[len(prefix)+1] = 1
2468 }
2469 data[len(prefix)+1] |= 2
2470 data = appendString(data, strdata["runtime.buildVersion"])
2471 data = appendString(data, strdata["runtime.modinfo"])
2472
2473 for len(data)%16 != 0 {
2474 data = append(data, 0)
2475 }
2476 s.SetData(data)
2477 s.SetSize(int64(len(data)))
2478
2479
2480
2481
2482 sr := ldr.CreateSymForUpdate("go:buildinfo.ref", 0)
2483 sr.SetType(sym.SRODATA)
2484 sr.SetAlign(int32(ctxt.Arch.PtrSize))
2485 sr.AddAddr(ctxt.Arch, s.Sym())
2486 }
2487
2488
2489 func appendString(data []byte, s string) []byte {
2490 var v [binary.MaxVarintLen64]byte
2491 n := binary.PutUvarint(v[:], uint64(len(s)))
2492 data = append(data, v[:n]...)
2493 data = append(data, s...)
2494 return data
2495 }
2496
2497
2498 func (ctxt *Link) textaddress() {
2499 addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2500
2501
2502
2503
2504 sect := Segtext.Sections[0]
2505
2506 sect.Align = int32(Funcalign)
2507
2508 ldr := ctxt.loader
2509
2510 if *flagRandLayout != 0 {
2511 r := rand.New(rand.NewSource(*flagRandLayout))
2512 textp := ctxt.Textp
2513 i := 0
2514
2515 if len(textp) > 0 && ldr.SymName(textp[0]) == "go:buildid" {
2516 i++
2517 }
2518
2519
2520
2521 for i < len(textp) && (ldr.SubSym(textp[i]) != 0 || ldr.AttrSubSymbol(textp[i])) {
2522 i++
2523 }
2524 textp = textp[i:]
2525 r.Shuffle(len(textp), func(i, j int) {
2526 textp[i], textp[j] = textp[j], textp[i]
2527 })
2528 }
2529
2530
2531
2532
2533 sort.SliceStable(ctxt.Textp, func(i, j int) bool {
2534 return ldr.SymType(ctxt.Textp[i]) < ldr.SymType(ctxt.Textp[j])
2535 })
2536
2537 text := ctxt.xdefine("runtime.text", sym.STEXT, 0)
2538 etext := ctxt.xdefine("runtime.etext", sym.STEXTEND, 0)
2539 ldr.SetSymSect(text, sect)
2540 if ctxt.IsAIX() && ctxt.IsExternal() {
2541
2542
2543
2544 u := ldr.MakeSymbolUpdater(text)
2545 u.SetAlign(sect.Align)
2546 u.SetSize(8)
2547 }
2548
2549 if (ctxt.DynlinkingGo() && ctxt.IsDarwin()) || (ctxt.IsAIX() && ctxt.IsExternal()) {
2550 ldr.SetSymSect(etext, sect)
2551 ctxt.Textp = append(ctxt.Textp, etext, 0)
2552 copy(ctxt.Textp[1:], ctxt.Textp)
2553 ctxt.Textp[0] = text
2554 }
2555
2556 start := uint64(Rnd(*FlagTextAddr, int64(Funcalign)))
2557 va := start
2558 n := 1
2559 sect.Vaddr = va
2560
2561 limit := thearch.TrampLimit
2562 if limit == 0 {
2563 limit = 1 << 63
2564 }
2565 if *FlagDebugTextSize != 0 {
2566 limit = uint64(*FlagDebugTextSize)
2567 }
2568 if *FlagDebugTramp > 1 {
2569 limit = 1
2570 }
2571
2572 if ctxt.IsAIX() && ctxt.IsExternal() {
2573
2574
2575
2576
2577
2578 limit = 1
2579 }
2580
2581
2582
2583 big := false
2584 for _, s := range ctxt.Textp {
2585 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2586 if va-start >= limit {
2587 big = true
2588 break
2589 }
2590 }
2591
2592
2593
2594 if big {
2595
2596 for _, s := range ctxt.Textp {
2597 if s != text {
2598 resetAddress(ctxt, s)
2599 }
2600 }
2601 va = start
2602
2603 ntramps := 0
2604 var curPkg string
2605 for i, s := range ctxt.Textp {
2606
2607
2608
2609
2610
2611 if symPkg := ldr.SymPkg(s); symPkg != "" && curPkg != symPkg {
2612 curPkg = symPkg
2613 vaTmp := va
2614 for j := i; j < len(ctxt.Textp); j++ {
2615 curSym := ctxt.Textp[j]
2616 if symPkg := ldr.SymPkg(curSym); symPkg == "" || curPkg != symPkg {
2617 break
2618 }
2619
2620
2621 sect, n, vaTmp = assignAddress(ctxt, sect, n, curSym, vaTmp, false, false)
2622 vaTmp += maxSizeTrampolines(ctxt, ldr, curSym, false)
2623 }
2624 }
2625
2626
2627 if s != text {
2628 resetAddress(ctxt, s)
2629 }
2630
2631
2632 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2633
2634
2635 trampoline(ctxt, s)
2636
2637
2638 for ; ntramps < len(ctxt.tramps); ntramps++ {
2639 tramp := ctxt.tramps[ntramps]
2640 if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") {
2641
2642 continue
2643 }
2644 sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true, big)
2645 }
2646 }
2647
2648
2649 if ntramps != 0 {
2650 newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
2651 i := 0
2652 for _, s := range ctxt.Textp {
2653 for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
2654 newtextp = append(newtextp, ctxt.tramps[i])
2655 }
2656 newtextp = append(newtextp, s)
2657 }
2658 newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
2659
2660 ctxt.Textp = newtextp
2661 }
2662 }
2663
2664
2665
2666 sect.Length = va - sect.Vaddr + uint64(ctxt.Arch.MinLC)
2667 ldr.SetSymSect(etext, sect)
2668 if ldr.SymValue(etext) == 0 {
2669
2670
2671 ldr.SetSymValue(etext, int64(va))
2672 ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr))
2673 }
2674 }
2675
2676
2677 func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) {
2678 ldr := ctxt.loader
2679 if thearch.AssignAddress != nil {
2680 return thearch.AssignAddress(ldr, sect, n, s, va, isTramp)
2681 }
2682
2683 ldr.SetSymSect(s, sect)
2684 if ldr.AttrSubSymbol(s) {
2685 return sect, n, va
2686 }
2687
2688 align := ldr.SymAlign(s)
2689 align = max(align, int32(Funcalign))
2690 va = uint64(Rnd(int64(va), int64(align)))
2691 if sect.Align < align {
2692 sect.Align = align
2693 }
2694
2695 funcsize := uint64(abi.MINFUNC)
2696 if ldr.SymSize(s) > abi.MINFUNC {
2697 funcsize = uint64(ldr.SymSize(s))
2698 }
2699
2700
2701
2702
2703
2704 if big && splitTextSections(ctxt) && ldr.OuterSym(s) == 0 {
2705
2706
2707 var textSizelimit uint64 = thearch.TrampLimit
2708 if *FlagDebugTextSize != 0 {
2709 textSizelimit = uint64(*FlagDebugTextSize)
2710 }
2711
2712
2713
2714 if funcsize > textSizelimit {
2715 panic(fmt.Sprintf("error: text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
2716 }
2717
2718 if va-sect.Vaddr+funcsize+maxSizeTrampolines(ctxt, ldr, s, isTramp) > textSizelimit {
2719 sectAlign := int32(thearch.Funcalign)
2720 if ctxt.IsPPC64() {
2721
2722
2723
2724
2725
2726
2727 const ppc64maxFuncalign = 64
2728 sectAlign = ppc64maxFuncalign
2729 va = uint64(Rnd(int64(va), ppc64maxFuncalign))
2730 }
2731
2732
2733 sect.Length = va - sect.Vaddr
2734
2735
2736 sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2737
2738 sect.Vaddr = va
2739 sect.Align = sectAlign
2740 ldr.SetSymSect(s, sect)
2741
2742
2743 ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
2744 ntext.SetSect(sect)
2745 if ctxt.IsAIX() {
2746
2747
2748
2749 ntext.SetType(sym.STEXT)
2750 ntext.SetSize(int64(abi.MINFUNC))
2751 ntext.SetOnList(true)
2752 ntext.SetAlign(sectAlign)
2753 ctxt.tramps = append(ctxt.tramps, ntext.Sym())
2754
2755 ntext.SetValue(int64(va))
2756 va += uint64(ntext.Size())
2757
2758 if align := ldr.SymAlign(s); align != 0 {
2759 va = uint64(Rnd(int64(va), int64(align)))
2760 } else {
2761 va = uint64(Rnd(int64(va), int64(Funcalign)))
2762 }
2763 }
2764 n++
2765 }
2766 }
2767
2768 ldr.SetSymValue(s, 0)
2769 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2770 ldr.SetSymValue(sub, ldr.SymValue(sub)+int64(va))
2771 if ctxt.Debugvlog > 2 {
2772 fmt.Println("assign text address:", ldr.SymName(sub), ldr.SymValue(sub))
2773 }
2774 }
2775
2776 va += funcsize
2777
2778 return sect, n, va
2779 }
2780
2781 func resetAddress(ctxt *Link, s loader.Sym) {
2782 ldr := ctxt.loader
2783 if ldr.OuterSym(s) != 0 {
2784 return
2785 }
2786 oldv := ldr.SymValue(s)
2787 for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2788 ldr.SetSymValue(sub, ldr.SymValue(sub)-oldv)
2789 }
2790 }
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808 func splitTextSections(ctxt *Link) bool {
2809 return (ctxt.IsARM() || ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
2810 }
2811
2812
2813
2814
2815
2816 const wasmMinDataAddr = 4096 + 8192
2817
2818
2819
2820 func (ctxt *Link) address() []*sym.Segment {
2821 var order []*sym.Segment
2822
2823 va := uint64(*FlagTextAddr)
2824 order = append(order, &Segtext)
2825 Segtext.Rwx = 05
2826 Segtext.Vaddr = va
2827 for i, s := range Segtext.Sections {
2828 va = uint64(Rnd(int64(va), int64(s.Align)))
2829 s.Vaddr = va
2830 va += s.Length
2831
2832 if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr {
2833 va = wasmMinDataAddr
2834 }
2835 }
2836
2837 Segtext.Length = va - uint64(*FlagTextAddr)
2838
2839 if len(Segrodata.Sections) > 0 {
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850 va = uint64(Rnd(int64(va), *FlagRound))
2851
2852 order = append(order, &Segrodata)
2853 Segrodata.Rwx = 04
2854 Segrodata.Vaddr = va
2855 for _, s := range Segrodata.Sections {
2856 va = uint64(Rnd(int64(va), int64(s.Align)))
2857 s.Vaddr = va
2858 va += s.Length
2859 }
2860
2861 Segrodata.Length = va - Segrodata.Vaddr
2862 }
2863 if len(Segrelrodata.Sections) > 0 {
2864
2865
2866 va = uint64(Rnd(int64(va), *FlagRound))
2867 if ctxt.HeadType == objabi.Haix {
2868
2869 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2870 }
2871
2872 order = append(order, &Segrelrodata)
2873 Segrelrodata.Rwx = 06
2874 Segrelrodata.Vaddr = va
2875 for _, s := range Segrelrodata.Sections {
2876 va = uint64(Rnd(int64(va), int64(s.Align)))
2877 s.Vaddr = va
2878 va += s.Length
2879 }
2880
2881 Segrelrodata.Length = va - Segrelrodata.Vaddr
2882 }
2883
2884 va = uint64(Rnd(int64(va), *FlagRound))
2885 if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 {
2886
2887
2888
2889 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2890 }
2891 order = append(order, &Segdata)
2892 Segdata.Rwx = 06
2893 if *FlagDataAddr != -1 {
2894 Segdata.Vaddr = uint64(*FlagDataAddr)
2895 va = Segdata.Vaddr
2896 } else {
2897 Segdata.Vaddr = va
2898 }
2899 var data *sym.Section
2900 var noptr *sym.Section
2901 var bss *sym.Section
2902 var noptrbss *sym.Section
2903 var fuzzCounters *sym.Section
2904 for i, s := range Segdata.Sections {
2905 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" {
2906 continue
2907 }
2908 vlen := int64(s.Length)
2909 if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") {
2910 vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
2911 }
2912 s.Vaddr = va
2913 va += uint64(vlen)
2914 Segdata.Length = va - Segdata.Vaddr
2915 switch s.Name {
2916 case ".data":
2917 data = s
2918 case ".noptrdata":
2919 noptr = s
2920 case ".bss":
2921 bss = s
2922 case ".noptrbss":
2923 noptrbss = s
2924 case ".go.fuzzcntrs":
2925 fuzzCounters = s
2926 }
2927 }
2928
2929
2930
2931 Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
2932
2933 if len(Segpdata.Sections) > 0 {
2934 va = uint64(Rnd(int64(va), *FlagRound))
2935 order = append(order, &Segpdata)
2936 Segpdata.Rwx = 04
2937 Segpdata.Vaddr = va
2938
2939
2940 for _, s := range Segpdata.Sections {
2941 va = uint64(Rnd(int64(va), int64(s.Align)))
2942 s.Vaddr = va
2943 va += s.Length
2944 }
2945 Segpdata.Length = va - Segpdata.Vaddr
2946 }
2947
2948 if len(Segxdata.Sections) > 0 {
2949 va = uint64(Rnd(int64(va), *FlagRound))
2950 order = append(order, &Segxdata)
2951 Segxdata.Rwx = 04
2952 Segxdata.Vaddr = va
2953
2954
2955 for _, s := range Segxdata.Sections {
2956 va = uint64(Rnd(int64(va), int64(s.Align)))
2957 s.Vaddr = va
2958 va += s.Length
2959 }
2960 Segxdata.Length = va - Segxdata.Vaddr
2961 }
2962
2963 va = uint64(Rnd(int64(va), *FlagRound))
2964 order = append(order, &Segdwarf)
2965 Segdwarf.Rwx = 06
2966 Segdwarf.Vaddr = va
2967 for i, s := range Segdwarf.Sections {
2968 vlen := int64(s.Length)
2969 if i+1 < len(Segdwarf.Sections) {
2970 vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
2971 }
2972 s.Vaddr = va
2973 va += uint64(vlen)
2974 if ctxt.HeadType == objabi.Hwindows {
2975 va = uint64(Rnd(int64(va), PEFILEALIGN))
2976 }
2977 Segdwarf.Length = va - Segdwarf.Vaddr
2978 }
2979
2980 ldr := ctxt.loader
2981 var (
2982 rodata = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0))
2983 pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0))
2984 types = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0))
2985 )
2986
2987 for _, s := range ctxt.datap {
2988 if sect := ldr.SymSect(s); sect != nil {
2989 ldr.AddToSymValue(s, int64(sect.Vaddr))
2990 }
2991 v := ldr.SymValue(s)
2992 for sub := ldr.SubSym(s); sub != 0; sub = ldr.SubSym(sub) {
2993 ldr.AddToSymValue(sub, v)
2994 }
2995 }
2996
2997 for _, si := range dwarfp {
2998 for _, s := range si.syms {
2999 if sect := ldr.SymSect(s); sect != nil {
3000 ldr.AddToSymValue(s, int64(sect.Vaddr))
3001 }
3002 sub := ldr.SubSym(s)
3003 if sub != 0 {
3004 panic(fmt.Sprintf("unexpected sub-sym for %s %s", ldr.SymName(s), ldr.SymType(s).String()))
3005 }
3006 v := ldr.SymValue(s)
3007 for ; sub != 0; sub = ldr.SubSym(sub) {
3008 ldr.AddToSymValue(s, v)
3009 }
3010 }
3011 }
3012
3013 for _, s := range sehp.pdata {
3014 if sect := ldr.SymSect(s); sect != nil {
3015 ldr.AddToSymValue(s, int64(sect.Vaddr))
3016 }
3017 }
3018 for _, s := range sehp.xdata {
3019 if sect := ldr.SymSect(s); sect != nil {
3020 ldr.AddToSymValue(s, int64(sect.Vaddr))
3021 }
3022 }
3023
3024 if ctxt.BuildMode == BuildModeShared {
3025 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
3026 sect := ldr.SymSect(ldr.LookupOrCreateSym(".note.go.abihash", 0))
3027 ldr.SetSymSect(s, sect)
3028 ldr.SetSymValue(s, int64(sect.Vaddr+16))
3029 }
3030
3031
3032
3033 n := 1
3034 for _, sect := range Segtext.Sections[1:] {
3035 if sect.Name != ".text" {
3036 break
3037 }
3038 symname := fmt.Sprintf("runtime.text.%d", n)
3039 if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal {
3040
3041
3042 ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
3043 }
3044 n++
3045 }
3046
3047 ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
3048 ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
3049 ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
3050 ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
3051
3052 s := ldr.Lookup("runtime.gcdata", 0)
3053 ldr.SetAttrLocal(s, true)
3054 ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
3055 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s))
3056
3057 s = ldr.LookupOrCreateSym("runtime.gcbss", 0)
3058 ldr.SetAttrLocal(s, true)
3059 ctxt.xdefine("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
3060 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcbss", 0), ldr.SymSect(s))
3061
3062 ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
3063 ctxt.defineInternal("runtime.pcheader", sym.SRODATA)
3064 ctxt.defineInternal("runtime.funcnametab", sym.SRODATA)
3065 ctxt.defineInternal("runtime.cutab", sym.SRODATA)
3066 ctxt.defineInternal("runtime.filetab", sym.SRODATA)
3067 ctxt.defineInternal("runtime.pctab", sym.SRODATA)
3068 ctxt.defineInternal("runtime.functab", sym.SRODATA)
3069 ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
3070 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
3071 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATAEND, int64(noptr.Vaddr+noptr.Length))
3072 ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
3073 ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
3074 ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
3075 ctxt.xdefine("runtime.edata", sym.SDATAEND, int64(data.Vaddr+data.Length))
3076 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
3077 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
3078 ctxt.xdefine("runtime.covctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff))
3079 ctxt.xdefine("runtime.ecovctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff+covCounterDataLen))
3080 ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
3081
3082 if fuzzCounters != nil {
3083 if *flagAsan {
3084
3085
3086
3087 fuzzCounters.Length = uint64(Rnd(int64(fuzzCounters.Length), 8))
3088 }
3089 ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
3090 ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
3091 ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
3092 ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
3093 }
3094
3095 if ctxt.IsSolaris() {
3096
3097
3098
3099 etext := ldr.Lookup("runtime.etext", 0)
3100 edata := ldr.Lookup("runtime.edata", 0)
3101 end := ldr.Lookup("runtime.end", 0)
3102 ldr.SetSymExtname(etext, "runtime.etext")
3103 ldr.SetSymExtname(edata, "runtime.edata")
3104 ldr.SetSymExtname(end, "runtime.end")
3105 ctxt.xdefine("_etext", ldr.SymType(etext), ldr.SymValue(etext))
3106 ctxt.xdefine("_edata", ldr.SymType(edata), ldr.SymValue(edata))
3107 ctxt.xdefine("_end", ldr.SymType(end), ldr.SymValue(end))
3108 ldr.SetSymSect(ldr.Lookup("_etext", 0), ldr.SymSect(etext))
3109 ldr.SetSymSect(ldr.Lookup("_edata", 0), ldr.SymSect(edata))
3110 ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
3111 }
3112
3113 if ctxt.IsPPC64() && ctxt.IsElf() {
3114
3115
3116
3117 tocAddr := int64(Segdata.Vaddr) + 0x8000
3118 if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
3119 tocAddr = gotAddr + 0x8000
3120 }
3121 for i := range ctxt.DotTOC {
3122 if i >= sym.SymVerABICount && i < sym.SymVerStatic {
3123 continue
3124 }
3125 if toc := ldr.Lookup(".TOC.", i); toc != 0 {
3126 ldr.SetSymValue(toc, tocAddr)
3127 }
3128 }
3129 }
3130
3131 return order
3132 }
3133
3134
3135
3136 func (ctxt *Link) layout(order []*sym.Segment) uint64 {
3137 var prev *sym.Segment
3138 for _, seg := range order {
3139 if prev == nil {
3140 seg.Fileoff = uint64(HEADR)
3141 } else {
3142 switch ctxt.HeadType {
3143 default:
3144
3145
3146
3147
3148 seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), *FlagRound))
3149 if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) {
3150 Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound)
3151 }
3152 case objabi.Hwindows:
3153 seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN))
3154 case objabi.Hplan9:
3155 seg.Fileoff = prev.Fileoff + prev.Filelen
3156 }
3157 }
3158 if seg != &Segdata {
3159
3160
3161 seg.Filelen = seg.Length
3162 }
3163 prev = seg
3164 }
3165 return prev.Fileoff + prev.Filelen
3166 }
3167
3168
3169 func (ctxt *Link) AddTramp(s *loader.SymbolBuilder, typ sym.SymKind) {
3170 s.SetType(typ)
3171 s.SetReachable(true)
3172 s.SetOnList(true)
3173 ctxt.tramps = append(ctxt.tramps, s.Sym())
3174 if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
3175 ctxt.Logf("trampoline %s inserted\n", s.Name())
3176 }
3177 }
3178
3179
3180
3181 func compressSyms(ctxt *Link, syms []loader.Sym) []byte {
3182 ldr := ctxt.loader
3183 var total int64
3184 for _, sym := range syms {
3185 total += ldr.SymSize(sym)
3186 }
3187
3188 var buf bytes.Buffer
3189 if ctxt.IsELF {
3190 switch ctxt.Arch.PtrSize {
3191 case 8:
3192 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{
3193 Type: uint32(elf.COMPRESS_ZLIB),
3194 Size: uint64(total),
3195 Addralign: uint64(ctxt.Arch.Alignment),
3196 })
3197 case 4:
3198 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{
3199 Type: uint32(elf.COMPRESS_ZLIB),
3200 Size: uint32(total),
3201 Addralign: uint32(ctxt.Arch.Alignment),
3202 })
3203 default:
3204 log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize)
3205 }
3206 } else {
3207 buf.Write([]byte("ZLIB"))
3208 var sizeBytes [8]byte
3209 binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
3210 buf.Write(sizeBytes[:])
3211 }
3212
3213 var relocbuf []byte
3214
3215
3216
3217
3218
3219 z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
3220 if err != nil {
3221 log.Fatalf("NewWriterLevel failed: %s", err)
3222 }
3223 st := ctxt.makeRelocSymState()
3224 for _, s := range syms {
3225
3226
3227 P := ldr.Data(s)
3228 relocs := ldr.Relocs(s)
3229 if relocs.Count() != 0 {
3230 relocbuf = append(relocbuf[:0], P...)
3231 P = relocbuf
3232 st.relocsym(s, P)
3233 }
3234 if _, err := z.Write(P); err != nil {
3235 log.Fatalf("compression failed: %s", err)
3236 }
3237 for i := ldr.SymSize(s) - int64(len(P)); i > 0; {
3238 b := zeros[:]
3239 if i < int64(len(b)) {
3240 b = b[:i]
3241 }
3242 n, err := z.Write(b)
3243 if err != nil {
3244 log.Fatalf("compression failed: %s", err)
3245 }
3246 i -= int64(n)
3247 }
3248 }
3249 if err := z.Close(); err != nil {
3250 log.Fatalf("compression failed: %s", err)
3251 }
3252 if int64(buf.Len()) >= total {
3253
3254 return nil
3255 }
3256 return buf.Bytes()
3257 }
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267 func writeUleb128FixedLength(b []byte, v uint64, length int) error {
3268 for i := 0; i < length; i++ {
3269 c := uint8(v & 0x7f)
3270 v >>= 7
3271 if i < length-1 {
3272 c |= 0x80
3273 }
3274 b[i] = c
3275 }
3276 if v != 0 {
3277 return fmt.Errorf("writeUleb128FixedLength: length too small")
3278 }
3279 return nil
3280 }
3281
View as plain text