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