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