Source file src/pkg/cmd/link/internal/x86/asm.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 package x86
32
33 import (
34 "cmd/internal/objabi"
35 "cmd/internal/sys"
36 "cmd/link/internal/ld"
37 "cmd/link/internal/sym"
38 "debug/elf"
39 "log"
40 )
41
42
43 func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
44 s.Attr |= sym.AttrReachable
45 i := s.Size
46 s.Size += 4
47 s.Grow(s.Size)
48 r := s.AddRel()
49 r.Sym = t
50 r.Off = int32(i)
51 r.Type = objabi.R_CALL
52 r.Siz = 4
53 }
54
55 func gentext(ctxt *ld.Link) {
56 if ctxt.DynlinkingGo() {
57
58 } else {
59 switch ctxt.BuildMode {
60 case ld.BuildModeCArchive:
61 if !ctxt.IsELF {
62 return
63 }
64 case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
65
66 default:
67 return
68 }
69 }
70
71
72 thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
73 for _, r := range [...]struct {
74 name string
75 num uint8
76 }{
77 {"ax", 0},
78 {"cx", 1},
79 {"dx", 2},
80 {"bx", 3},
81
82 {"bp", 5},
83 {"si", 6},
84 {"di", 7},
85 } {
86 thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
87 thunkfunc.Type = sym.STEXT
88 thunkfunc.Attr |= sym.AttrLocal
89 thunkfunc.Attr |= sym.AttrReachable
90 o := func(op ...uint8) {
91 for _, op1 := range op {
92 thunkfunc.AddUint8(op1)
93 }
94 }
95
96
97 o(0x8b, 0x04+r.num<<3, 0x24)
98
99 o(0xc3)
100
101 thunks = append(thunks, thunkfunc)
102 }
103 ctxt.Textp = append(thunks, ctxt.Textp...)
104
105 addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
106 if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
107
108
109 return
110 }
111
112 addmoduledata.Attr |= sym.AttrReachable
113
114 initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
115 initfunc.Type = sym.STEXT
116 initfunc.Attr |= sym.AttrLocal
117 initfunc.Attr |= sym.AttrReachable
118 o := func(op ...uint8) {
119 for _, op1 := range op {
120 initfunc.AddUint8(op1)
121 }
122 }
123
124
125
126
127
128
129
130
131
132
133 o(0x53)
134
135 o(0xe8)
136 addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
137
138 o(0x8d, 0x81)
139 initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
140
141 o(0x8d, 0x99)
142 i := initfunc.Size
143 initfunc.Size += 4
144 initfunc.Grow(initfunc.Size)
145 r := initfunc.AddRel()
146 r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
147 r.Off = int32(i)
148 r.Type = objabi.R_PCREL
149 r.Add = 12
150 r.Siz = 4
151
152 o(0xe8)
153 addcall(ctxt, initfunc, addmoduledata)
154
155 o(0x5b)
156
157 o(0xc3)
158
159 if ctxt.BuildMode == ld.BuildModePlugin {
160 ctxt.Textp = append(ctxt.Textp, addmoduledata)
161 }
162 ctxt.Textp = append(ctxt.Textp, initfunc)
163 initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
164 initarray_entry.Attr |= sym.AttrReachable
165 initarray_entry.Attr |= sym.AttrLocal
166 initarray_entry.Type = sym.SINITARR
167 initarray_entry.AddAddr(ctxt.Arch, initfunc)
168 }
169
170 func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
171 targ := r.Sym
172
173 switch r.Type {
174 default:
175 if r.Type >= objabi.ElfRelocOffset {
176 ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
177 return false
178 }
179
180
181 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PC32):
182 if targ.Type == sym.SDYNIMPORT {
183 ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
184 }
185
186
187 if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
188 ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
189 }
190 r.Type = objabi.R_PCREL
191 r.Add += 4
192 return true
193
194 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PLT32):
195 r.Type = objabi.R_PCREL
196 r.Add += 4
197 if targ.Type == sym.SDYNIMPORT {
198 addpltsym(ctxt, targ)
199 r.Sym = ctxt.Syms.Lookup(".plt", 0)
200 r.Add += int64(targ.Plt())
201 }
202
203 return true
204
205 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32),
206 objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32X):
207 if targ.Type != sym.SDYNIMPORT {
208
209 if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
210
211 s.P[r.Off-2] = 0x8d
212
213 r.Type = objabi.R_GOTOFF
214 return true
215 }
216
217 if r.Off >= 2 && s.P[r.Off-2] == 0xff && s.P[r.Off-1] == 0xb3 {
218
219
220 s.P[r.Off-2] = 0x36
221
222 s.P[r.Off-1] = 0x68
223 r.Type = objabi.R_ADDR
224 return true
225 }
226
227 ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
228 return false
229 }
230
231 addgotsym(ctxt, targ)
232 r.Type = objabi.R_CONST
233 r.Sym = nil
234 r.Add += int64(targ.Got())
235 return true
236
237 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTOFF):
238 r.Type = objabi.R_GOTOFF
239 return true
240
241 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC):
242 r.Type = objabi.R_PCREL
243 r.Sym = ctxt.Syms.Lookup(".got", 0)
244 r.Add += 4
245 return true
246
247 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_32):
248 if targ.Type == sym.SDYNIMPORT {
249 ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
250 }
251 r.Type = objabi.R_ADDR
252 return true
253
254 case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
255 r.Type = objabi.R_ADDR
256 if targ.Type == sym.SDYNIMPORT {
257 ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
258 }
259 return true
260
261 case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
262 if targ.Type == sym.SDYNIMPORT {
263 addpltsym(ctxt, targ)
264 r.Sym = ctxt.Syms.Lookup(".plt", 0)
265 r.Add = int64(targ.Plt())
266 r.Type = objabi.R_PCREL
267 return true
268 }
269
270 r.Type = objabi.R_PCREL
271 return true
272
273 case objabi.MachoRelocOffset + ld.MACHO_FAKE_GOTPCREL:
274 if targ.Type != sym.SDYNIMPORT {
275
276
277 if r.Off < 2 || s.P[r.Off-2] != 0x8b {
278 ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
279 return false
280 }
281
282 s.P[r.Off-2] = 0x8d
283 r.Type = objabi.R_PCREL
284 return true
285 }
286
287 addgotsym(ctxt, targ)
288 r.Sym = ctxt.Syms.Lookup(".got", 0)
289 r.Add += int64(targ.Got())
290 r.Type = objabi.R_PCREL
291 return true
292 }
293
294
295 if targ.Type != sym.SDYNIMPORT {
296 return true
297 }
298 switch r.Type {
299 case objabi.R_CALL,
300 objabi.R_PCREL:
301 if ctxt.LinkMode == ld.LinkExternal {
302
303 return true
304 }
305 addpltsym(ctxt, targ)
306 r.Sym = ctxt.Syms.Lookup(".plt", 0)
307 r.Add = int64(targ.Plt())
308 return true
309
310 case objabi.R_ADDR:
311 if s.Type != sym.SDATA {
312 break
313 }
314 if ctxt.IsELF {
315 ld.Adddynsym(ctxt, targ)
316 rel := ctxt.Syms.Lookup(".rel", 0)
317 rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
318 rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
319 r.Type = objabi.R_CONST
320 r.Sym = nil
321 return true
322 }
323
324 if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
325
326
327
328
329
330
331
332
333
334
335 ld.Adddynsym(ctxt, targ)
336
337 got := ctxt.Syms.Lookup(".got", 0)
338 s.Type = got.Type
339 s.Attr |= sym.AttrSubSymbol
340 s.Outer = got
341 s.Sub = got.Sub
342 got.Sub = s
343 s.Value = got.Size
344 got.AddUint32(ctxt.Arch, 0)
345 ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
346 r.Type = objabi.ElfRelocOffset
347 return true
348 }
349 }
350
351 return false
352 }
353
354 func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
355 ctxt.Out.Write32(uint32(sectoff))
356
357 elfsym := r.Xsym.ElfsymForReloc()
358 switch r.Type {
359 default:
360 return false
361 case objabi.R_ADDR:
362 if r.Siz == 4 {
363 ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
364 } else {
365 return false
366 }
367 case objabi.R_GOTPCREL:
368 if r.Siz == 4 {
369 ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
370 if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
371 ctxt.Out.Write32(uint32(sectoff))
372 ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
373 }
374 } else {
375 return false
376 }
377 case objabi.R_CALL:
378 if r.Siz == 4 {
379 if r.Xsym.Type == sym.SDYNIMPORT {
380 ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
381 } else {
382 ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
383 }
384 } else {
385 return false
386 }
387 case objabi.R_PCREL:
388 if r.Siz == 4 {
389 ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
390 } else {
391 return false
392 }
393 case objabi.R_TLS_LE:
394 if r.Siz == 4 {
395 ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
396 } else {
397 return false
398 }
399 case objabi.R_TLS_IE:
400 if r.Siz == 4 {
401 ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
402 ctxt.Out.Write32(uint32(sectoff))
403 ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
404 } else {
405 return false
406 }
407 }
408
409 return true
410 }
411
412 func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
413 var v uint32
414
415 rs := r.Xsym
416
417 if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALL {
418 if rs.Dynid < 0 {
419 ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
420 return false
421 }
422
423 v = uint32(rs.Dynid)
424 v |= 1 << 27
425 } else {
426 v = uint32(rs.Sect.Extnum)
427 if v == 0 {
428 ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
429 return false
430 }
431 }
432
433 switch r.Type {
434 default:
435 return false
436 case objabi.R_ADDR:
437 v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
438 case objabi.R_CALL,
439 objabi.R_PCREL:
440 v |= 1 << 24
441 v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
442 }
443
444 switch r.Siz {
445 default:
446 return false
447 case 1:
448 v |= 0 << 25
449 case 2:
450 v |= 1 << 25
451 case 4:
452 v |= 2 << 25
453 case 8:
454 v |= 3 << 25
455 }
456
457 out.Write32(uint32(sectoff))
458 out.Write32(v)
459 return true
460 }
461
462 func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
463 var v uint32
464
465 rs := r.Xsym
466
467 if rs.Dynid < 0 {
468 ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
469 return false
470 }
471
472 out.Write32(uint32(sectoff))
473 out.Write32(uint32(rs.Dynid))
474
475 switch r.Type {
476 default:
477 return false
478
479 case objabi.R_DWARFSECREF:
480 v = ld.IMAGE_REL_I386_SECREL
481
482 case objabi.R_ADDR:
483 v = ld.IMAGE_REL_I386_DIR32
484
485 case objabi.R_CALL,
486 objabi.R_PCREL:
487 v = ld.IMAGE_REL_I386_REL32
488 }
489
490 out.Write16(uint16(v))
491
492 return true
493 }
494
495 func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
496 if ctxt.LinkMode == ld.LinkExternal {
497 return val, false
498 }
499 switch r.Type {
500 case objabi.R_CONST:
501 return r.Add, true
502 case objabi.R_GOTOFF:
503 return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
504 }
505
506 return val, false
507 }
508
509 func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
510 log.Fatalf("unexpected relocation variant")
511 return t
512 }
513
514 func elfsetupplt(ctxt *ld.Link) {
515 plt := ctxt.Syms.Lookup(".plt", 0)
516 got := ctxt.Syms.Lookup(".got.plt", 0)
517 if plt.Size == 0 {
518
519 plt.AddUint8(0xff)
520
521 plt.AddUint8(0x35)
522 plt.AddAddrPlus(ctxt.Arch, got, 4)
523
524
525 plt.AddUint8(0xff)
526
527 plt.AddUint8(0x25)
528 plt.AddAddrPlus(ctxt.Arch, got, 8)
529
530
531 plt.AddUint32(ctxt.Arch, 0)
532
533
534 got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
535
536 got.AddUint32(ctxt.Arch, 0)
537 got.AddUint32(ctxt.Arch, 0)
538 }
539 }
540
541 func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
542 if s.Plt() >= 0 {
543 return
544 }
545
546 ld.Adddynsym(ctxt, s)
547
548 if ctxt.IsELF {
549 plt := ctxt.Syms.Lookup(".plt", 0)
550 got := ctxt.Syms.Lookup(".got.plt", 0)
551 rel := ctxt.Syms.Lookup(".rel.plt", 0)
552 if plt.Size == 0 {
553 elfsetupplt(ctxt)
554 }
555
556
557 plt.AddUint8(0xff)
558
559 plt.AddUint8(0x25)
560 plt.AddAddrPlus(ctxt.Arch, got, got.Size)
561
562
563 got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
564
565
566 plt.AddUint8(0x68)
567
568 plt.AddUint32(ctxt.Arch, uint32(rel.Size))
569
570
571 plt.AddUint8(0xe9)
572
573 plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
574
575
576 rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
577
578 rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
579
580 s.SetPlt(int32(plt.Size - 16))
581 } else if ctxt.HeadType == objabi.Hdarwin {
582
583
584 plt := ctxt.Syms.Lookup(".plt", 0)
585
586 addgotsym(ctxt, s)
587
588 ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
589
590
591 s.SetPlt(int32(plt.Size))
592
593 plt.AddUint8(0xff)
594 plt.AddUint8(0x25)
595 plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
596 } else {
597 ld.Errorf(s, "addpltsym: unsupported binary format")
598 }
599 }
600
601 func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
602 if s.Got() >= 0 {
603 return
604 }
605
606 ld.Adddynsym(ctxt, s)
607 got := ctxt.Syms.Lookup(".got", 0)
608 s.SetGot(int32(got.Size))
609 got.AddUint32(ctxt.Arch, 0)
610
611 if ctxt.IsELF {
612 rel := ctxt.Syms.Lookup(".rel", 0)
613 rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
614 rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
615 } else if ctxt.HeadType == objabi.Hdarwin {
616 ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
617 } else {
618 ld.Errorf(s, "addgotsym: unsupported binary format")
619 }
620 }
621
622 func asmb(ctxt *ld.Link) {
623 if ctxt.Debugvlog != 0 {
624 ctxt.Logf("%5.2f asmb\n", ld.Cputime())
625 }
626
627 if ctxt.IsELF {
628 ld.Asmbelfsetup()
629 }
630
631 sect := ld.Segtext.Sections[0]
632 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
633
634 ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
635 for _, sect = range ld.Segtext.Sections[1:] {
636 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
637 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
638 }
639
640 if ld.Segrodata.Filelen > 0 {
641 if ctxt.Debugvlog != 0 {
642 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
643 }
644
645 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
646 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
647 }
648 if ld.Segrelrodata.Filelen > 0 {
649 if ctxt.Debugvlog != 0 {
650 ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
651 }
652 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
653 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
654 }
655
656 if ctxt.Debugvlog != 0 {
657 ctxt.Logf("%5.2f datblk\n", ld.Cputime())
658 }
659
660 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
661 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
662
663 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
664 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
665 }
666
667 func asmb2(ctxt *ld.Link) {
668 machlink := uint32(0)
669 if ctxt.HeadType == objabi.Hdarwin {
670 machlink = uint32(ld.Domacholink(ctxt))
671 }
672
673 ld.Symsize = 0
674 ld.Spsize = 0
675 ld.Lcsize = 0
676 symo := uint32(0)
677 if !*ld.FlagS {
678
679 if ctxt.Debugvlog != 0 {
680 ctxt.Logf("%5.2f sym\n", ld.Cputime())
681 }
682 switch ctxt.HeadType {
683 default:
684 if ctxt.IsELF {
685 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
686 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
687 }
688
689 case objabi.Hplan9:
690 symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
691
692 case objabi.Hdarwin:
693 symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
694
695 case objabi.Hwindows:
696 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
697 symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
698 }
699
700 ctxt.Out.SeekSet(int64(symo))
701 switch ctxt.HeadType {
702 default:
703 if ctxt.IsELF {
704 if ctxt.Debugvlog != 0 {
705 ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
706 }
707 ld.Asmelfsym(ctxt)
708 ctxt.Out.Flush()
709 ctxt.Out.Write(ld.Elfstrdat)
710
711 if ctxt.LinkMode == ld.LinkExternal {
712 ld.Elfemitreloc(ctxt)
713 }
714 }
715
716 case objabi.Hplan9:
717 ld.Asmplan9sym(ctxt)
718 ctxt.Out.Flush()
719
720 sym := ctxt.Syms.Lookup("pclntab", 0)
721 if sym != nil {
722 ld.Lcsize = int32(len(sym.P))
723 ctxt.Out.Write(sym.P)
724 ctxt.Out.Flush()
725 }
726
727 case objabi.Hwindows:
728 if ctxt.Debugvlog != 0 {
729 ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
730 }
731
732 case objabi.Hdarwin:
733 if ctxt.LinkMode == ld.LinkExternal {
734 ld.Machoemitreloc(ctxt)
735 }
736 }
737 }
738
739 if ctxt.Debugvlog != 0 {
740 ctxt.Logf("%5.2f headr\n", ld.Cputime())
741 }
742 ctxt.Out.SeekSet(0)
743 switch ctxt.HeadType {
744 default:
745 case objabi.Hplan9:
746 magic := int32(4*11*11 + 7)
747
748 ctxt.Out.Write32b(uint32(magic))
749 ctxt.Out.Write32b(uint32(ld.Segtext.Filelen))
750 ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
751 ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
752 ctxt.Out.Write32b(uint32(ld.Symsize))
753 ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt)))
754 ctxt.Out.Write32b(uint32(ld.Spsize))
755 ctxt.Out.Write32b(uint32(ld.Lcsize))
756
757 case objabi.Hdarwin:
758 ld.Asmbmacho(ctxt)
759
760 case objabi.Hlinux,
761 objabi.Hfreebsd,
762 objabi.Hnetbsd,
763 objabi.Hopenbsd,
764 objabi.Hnacl:
765 ld.Asmbelf(ctxt, int64(symo))
766
767 case objabi.Hwindows:
768 ld.Asmbpe(ctxt)
769 }
770
771 ctxt.Out.Flush()
772 }
773
View as plain text