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