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 ld
32
33 import (
34 "cmd/internal/obj"
35 "cmd/internal/objabi"
36 "cmd/link/internal/loader"
37 "cmd/link/internal/sym"
38 "debug/elf"
39 "fmt"
40 "internal/buildcfg"
41 "path/filepath"
42 "strings"
43 )
44
45
46
47 func putelfstr(s string) int {
48 if len(elfstrdat) == 0 {
49
50 elfstrdat = append(elfstrdat, 0)
51 elfstroff = map[string]int{"": 0}
52 }
53 if off, ok := elfstroff[s]; ok {
54 return off
55 }
56
57 off := len(elfstrdat)
58 elfstrdat = append(elfstrdat, s...)
59 elfstrdat = append(elfstrdat, 0)
60 elfstroff[s] = off
61 return off
62 }
63
64 func putelfsyment(out *OutBuf, off int, addr int64, size int64, info uint8, shndx elf.SectionIndex, other int) {
65 if elf64 {
66 out.Write32(uint32(off))
67 out.Write8(info)
68 out.Write8(uint8(other))
69 out.Write16(uint16(shndx))
70 out.Write64(uint64(addr))
71 out.Write64(uint64(size))
72 symSize += ELF64SYMSIZE
73 } else {
74 out.Write32(uint32(off))
75 out.Write32(uint32(addr))
76 out.Write32(uint32(size))
77 out.Write8(info)
78 out.Write8(uint8(other))
79 out.Write16(uint16(shndx))
80 symSize += ELF32SYMSIZE
81 }
82 }
83
84 func putelfsym(ctxt *Link, x loader.Sym, typ elf.SymType, curbind elf.SymBind) {
85 ldr := ctxt.loader
86 addr := ldr.SymValue(x)
87 size := ldr.SymSize(x)
88
89 xo := x
90 if ldr.OuterSym(x) != 0 {
91 xo = ldr.OuterSym(x)
92 }
93 xot := ldr.SymType(xo)
94 xosect := ldr.SymSect(xo)
95
96 var elfshnum elf.SectionIndex
97 if xot == sym.SDYNIMPORT || xot == sym.SHOSTOBJ || xot == sym.SUNDEFEXT {
98 elfshnum = elf.SHN_UNDEF
99 size = 0
100 } else {
101 if xosect == nil {
102 ldr.Errorf(x, "missing section in putelfsym")
103 return
104 }
105 if xosect.Elfsect == nil {
106 ldr.Errorf(x, "missing ELF section in putelfsym")
107 return
108 }
109 elfshnum = elfShdrShnum(xosect.Elfsect.(*ElfShdr))
110 }
111
112 sname := ldr.SymExtname(x)
113 sname = mangleABIName(ctxt, ldr, x, sname)
114
115
116
117 bind := elf.STB_GLOBAL
118 if ldr.IsFileLocal(x) && !isStaticTmp(sname) || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) ||
119 (ldr.IsContentHashed(x) && ldr.SymType(x).IsText()) {
120
121
122
123
124 bind = elf.STB_LOCAL
125 }
126
127
128
129
130
131
132 if !ctxt.DynlinkingGo() && ctxt.IsExternal() && !ldr.AttrCgoExportStatic(x) && elfshnum != elf.SHN_UNDEF {
133 bind = elf.STB_LOCAL
134 }
135
136 if ctxt.LinkMode == LinkExternal && elfshnum != elf.SHN_UNDEF {
137 addr -= int64(xosect.Vaddr)
138 }
139 other := int(elf.STV_DEFAULT)
140 if ldr.AttrVisibilityHidden(x) {
141
142
143
144
145
146 other = int(elf.STV_HIDDEN)
147 }
148 if ctxt.IsPPC64() && typ == elf.STT_FUNC && ldr.AttrShared(x) {
149
150
151
152 hasPCrel := buildcfg.GOPPC64 >= 10 && buildcfg.GOOS == "linux"
153
154
155
156 if !hasPCrel && ldr.SymName(x) != "runtime.duffzero" && ldr.SymName(x) != "runtime.duffcopy" {
157 other |= 3 << 5
158 }
159 }
160
161
162
163
164 if !ctxt.DynlinkingGo() {
165
166 sname = strings.ReplaceAll(sname, "·", ".")
167 }
168
169 if ctxt.DynlinkingGo() && bind == elf.STB_GLOBAL && curbind == elf.STB_LOCAL && ldr.SymType(x).IsText() {
170
171
172
173
174
175
176
177
178 putelfsyment(ctxt.Out, putelfstr("local."+sname), addr, size, elf.ST_INFO(elf.STB_LOCAL, typ), elfshnum, other)
179 ldr.SetSymLocalElfSym(x, int32(ctxt.numelfsym))
180 ctxt.numelfsym++
181 return
182 } else if bind != curbind {
183 return
184 }
185
186 putelfsyment(ctxt.Out, putelfstr(sname), addr, size, elf.ST_INFO(bind, typ), elfshnum, other)
187 ldr.SetSymElfSym(x, int32(ctxt.numelfsym))
188 ctxt.numelfsym++
189 }
190
191 func putelfsectionsym(ctxt *Link, out *OutBuf, s loader.Sym, shndx elf.SectionIndex) {
192 putelfsyment(out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_SECTION), shndx, 0)
193 ctxt.loader.SetSymElfSym(s, int32(ctxt.numelfsym))
194 ctxt.numelfsym++
195 }
196
197 func genelfsym(ctxt *Link, elfbind elf.SymBind) {
198 ldr := ctxt.loader
199
200
201 s := ldr.Lookup("runtime.text", 0)
202 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
203 for k, sect := range Segtext.Sections[1:] {
204 n := k + 1
205 if sect.Name != ".text" || (ctxt.IsAIX() && ctxt.IsExternal()) {
206
207 break
208 }
209 s = ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
210 if s == 0 {
211 break
212 }
213 if !ldr.SymType(s).IsText() {
214 panic("unexpected type for runtime.text symbol")
215 }
216 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
217 }
218
219
220 for _, s := range ctxt.Textp {
221 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
222 }
223
224
225 s = ldr.Lookup("runtime.etext", 0)
226 if ldr.SymType(s).IsText() {
227 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
228 }
229
230 shouldBeInSymbolTable := func(s loader.Sym) bool {
231 if ldr.AttrNotInSymbolTable(s) {
232 return false
233 }
234
235
236
237
238 sn := ldr.SymName(s)
239 if (sn == "" || sn[0] == '.') && ldr.IsFileLocal(s) {
240 panic(fmt.Sprintf("unexpected file local symbol %d %s<%d>\n",
241 s, sn, ldr.SymVersion(s)))
242 }
243 if (sn == "" || sn[0] == '.') && !ldr.IsFileLocal(s) {
244 return false
245 }
246 return true
247 }
248
249
250 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
251 if !ldr.AttrReachable(s) {
252 continue
253 }
254 st := ldr.SymType(s)
255 if st >= sym.SELFRXSECT && st < sym.SFirstUnallocated {
256 typ := elf.STT_OBJECT
257 if st == sym.STLSBSS {
258 if ctxt.IsInternal() {
259 continue
260 }
261 typ = elf.STT_TLS
262 }
263 if !shouldBeInSymbolTable(s) {
264 continue
265 }
266 putelfsym(ctxt, s, typ, elfbind)
267 continue
268 }
269 if st == sym.SHOSTOBJ || st == sym.SDYNIMPORT || st == sym.SUNDEFEXT {
270 putelfsym(ctxt, s, ldr.SymElfType(s), elfbind)
271 }
272 }
273 }
274
275 func asmElfSym(ctxt *Link) {
276
277
278 putelfsyment(ctxt.Out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_NOTYPE), 0, 0)
279
280 dwarfaddelfsectionsyms(ctxt)
281
282
283
284
285
286 putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_FILE), elf.SHN_ABS, 0)
287 ctxt.numelfsym++
288
289 bindings := []elf.SymBind{elf.STB_LOCAL, elf.STB_GLOBAL}
290 for _, elfbind := range bindings {
291 if elfbind == elf.STB_GLOBAL {
292 elfglobalsymndx = ctxt.numelfsym
293 }
294 genelfsym(ctxt, elfbind)
295 }
296 }
297
298 func putplan9sym(ctxt *Link, ldr *loader.Loader, s loader.Sym, char SymbolType) {
299 t := int(char)
300 if ldr.IsFileLocal(s) {
301 t += 'a' - 'A'
302 }
303 l := 4
304 addr := ldr.SymValue(s)
305 if ctxt.IsAMD64() && !flag8 {
306 ctxt.Out.Write32b(uint32(addr >> 32))
307 l = 8
308 }
309
310 ctxt.Out.Write32b(uint32(addr))
311 ctxt.Out.Write8(uint8(t + 0x80))
312
313 name := ldr.SymName(s)
314 name = mangleABIName(ctxt, ldr, s, name)
315 ctxt.Out.WriteString(name)
316 ctxt.Out.Write8(0)
317
318 symSize += int32(l) + 1 + int32(len(name)) + 1
319 }
320
321 func asmbPlan9Sym(ctxt *Link) {
322 ldr := ctxt.loader
323
324
325 s := ldr.Lookup("runtime.text", 0)
326 if ldr.SymType(s).IsText() {
327 putplan9sym(ctxt, ldr, s, TextSym)
328 }
329 s = ldr.Lookup("runtime.etext", 0)
330 if ldr.SymType(s).IsText() {
331 putplan9sym(ctxt, ldr, s, TextSym)
332 }
333
334
335 for _, s := range ctxt.Textp {
336 putplan9sym(ctxt, ldr, s, TextSym)
337 }
338
339 shouldBeInSymbolTable := func(s loader.Sym) bool {
340 if ldr.AttrNotInSymbolTable(s) {
341 return false
342 }
343 name := ldr.SymName(s)
344 if name == "" || name[0] == '.' {
345 return false
346 }
347 return true
348 }
349
350
351 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
352 if !ldr.AttrReachable(s) {
353 continue
354 }
355 t := ldr.SymType(s)
356 if t >= sym.SELFRXSECT && t < sym.SFirstUnallocated {
357 if t == sym.STLSBSS {
358 continue
359 }
360 if !shouldBeInSymbolTable(s) {
361 continue
362 }
363 char := DataSym
364 if t == sym.SBSS || t == sym.SNOPTRBSS {
365 char = BSSSym
366 }
367 putplan9sym(ctxt, ldr, s, char)
368 }
369 }
370 }
371
372
373
374 func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
375 ldr := ctxt.loader
376 t := ldr.CreateSymForUpdate("runtime.textsectionmap", 0)
377 t.SetType(sym.SRODATA)
378 nsections := int64(0)
379
380 for _, sect := range Segtext.Sections {
381 if sect.Name == ".text" {
382 nsections++
383 } else {
384 break
385 }
386 }
387 t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
388
389 off := int64(0)
390 n := 0
391
392
393
394
395
396
397
398
399
400
401 textbase := Segtext.Sections[0].Vaddr
402 for _, sect := range Segtext.Sections {
403 if sect.Name != ".text" {
404 break
405 }
406
407
408 vaddr := sect.Vaddr - textbase
409 off = t.SetUint(ctxt.Arch, off, vaddr)
410 end := vaddr + sect.Length
411 off = t.SetUint(ctxt.Arch, off, end)
412 name := "runtime.text"
413 if n != 0 {
414 name = fmt.Sprintf("runtime.text.%d", n)
415 }
416 s := ldr.Lookup(name, 0)
417 if s == 0 {
418 ctxt.Errorf(s, "Unable to find symbol %s\n", name)
419 }
420 off = t.SetAddr(ctxt.Arch, off, s)
421 n++
422 }
423 return t.Sym(), uint32(n)
424 }
425
426 func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
427 ldr := ctxt.loader
428
429 if !ctxt.IsAIX() && !ctxt.IsWasm() {
430 switch ctxt.BuildMode {
431 case BuildModeCArchive, BuildModeCShared:
432 s := ldr.Lookup(*flagEntrySymbol, sym.SymVerABI0)
433 if s != 0 {
434 addinitarrdata(ctxt, ldr, s)
435 }
436 }
437 }
438
439
440
441 ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
442 ctxt.xdefine("runtime.erodata", sym.SRODATAEND, 0)
443 ctxt.xdefine("runtime.types", sym.SRODATA, 0)
444 ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
445 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
446 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATAEND, 0)
447 ctxt.xdefine("runtime.data", sym.SDATA, 0)
448 ctxt.xdefine("runtime.edata", sym.SDATAEND, 0)
449 ctxt.xdefine("runtime.bss", sym.SBSS, 0)
450 ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
451 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
452 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
453 ctxt.xdefine("runtime.gcmask.*", sym.SNOPTRBSS, 0)
454 ctxt.xdefine("runtime.covctrs", sym.SNOPTRBSS, 0)
455 ctxt.xdefine("runtime.ecovctrs", sym.SNOPTRBSS, 0)
456 ctxt.xdefine("runtime.end", sym.SBSS, 0)
457 ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
458
459
460 s := ldr.CreateSymForUpdate("runtime.gcdata", 0)
461 s.SetType(sym.SRODATA)
462 s.SetSize(0)
463 ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
464
465 s = ldr.CreateSymForUpdate("runtime.gcbss", 0)
466 s.SetType(sym.SRODATA)
467 s.SetSize(0)
468 ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
469
470
471 s = ldr.CreateSymForUpdate("type:*", 0)
472 s.SetType(sym.STYPE)
473 s.SetSize(0)
474 s.SetAlign(int32(ctxt.Arch.PtrSize))
475 symtype := s.Sym()
476 setCarrierSym(sym.STYPE, symtype)
477
478 groupSym := func(name string, t sym.SymKind) loader.Sym {
479 s := ldr.CreateSymForUpdate(name, 0)
480 s.SetType(t)
481 s.SetSize(0)
482 s.SetAlign(int32(ctxt.Arch.PtrSize))
483 s.SetLocal(true)
484 setCarrierSym(t, s.Sym())
485 return s.Sym()
486 }
487 var (
488 symgostring = groupSym("go:string.*", sym.SGOSTRING)
489 symgofunc = groupSym("go:funcdesc", sym.SGOFUNC)
490 symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS)
491 symgcmask = groupSym("runtime.gcmask.*", sym.SGCMASK)
492 )
493
494
495
496
497
498
499
500 nsym := loader.Sym(ldr.NSym())
501 symGroupType := make([]sym.SymKind, nsym)
502 for s := loader.Sym(1); s < nsym; s++ {
503 if (!ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "") || (ctxt.LinkMode == LinkInternal && ldr.SymType(s) == sym.SCOVERAGE_COUNTER) {
504 ldr.SetAttrNotInSymbolTable(s, true)
505 }
506
507 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) {
508 continue
509 }
510
511 if ldr.SymType(s) == sym.SNOPTRBSS && strings.HasPrefix(ldr.SymName(s), "type:.gcmask.") {
512 symGroupType[s] = sym.SGCMASK
513 ldr.SetAttrNotInSymbolTable(s, true)
514 ldr.SetCarrierSym(s, symgcmask)
515 continue
516 }
517
518 if ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC {
519 continue
520 }
521
522 name := ldr.SymName(s)
523 switch {
524 case strings.HasPrefix(name, "go:string."):
525 symGroupType[s] = sym.SGOSTRING
526 ldr.SetAttrNotInSymbolTable(s, true)
527 ldr.SetCarrierSym(s, symgostring)
528
529 case strings.HasPrefix(name, "runtime.gcbits."):
530 symGroupType[s] = sym.SGCBITS
531 ldr.SetAttrNotInSymbolTable(s, true)
532 ldr.SetCarrierSym(s, symgcbits)
533
534 case strings.HasSuffix(name, "·f"):
535 if !ctxt.DynlinkingGo() {
536 ldr.SetAttrNotInSymbolTable(s, true)
537 ldr.SetCarrierSym(s, symgofunc)
538 }
539 symGroupType[s] = sym.SGOFUNC
540
541 case strings.HasPrefix(name, "type:"):
542 if !ctxt.DynlinkingGo() {
543 ldr.SetAttrNotInSymbolTable(s, true)
544 ldr.SetCarrierSym(s, symtype)
545 }
546 symGroupType[s] = sym.STYPE
547
548 case ldr.IsItab(s):
549 if !ctxt.DynlinkingGo() {
550 ldr.SetAttrNotInSymbolTable(s, true)
551 ldr.SetCarrierSym(s, symtype)
552 }
553 symGroupType[s] = sym.STYPE
554 }
555 }
556
557 if ctxt.BuildMode == BuildModeShared {
558 abihashgostr := ldr.CreateSymForUpdate("go:link.abihash."+filepath.Base(*flagOutfile), 0)
559 abihashgostr.SetType(sym.SRODATA)
560 hashsym := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
561 abihashgostr.AddAddr(ctxt.Arch, hashsym)
562 abihashgostr.AddUint(ctxt.Arch, uint64(ldr.SymSize(hashsym)))
563 }
564 if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
565 for _, l := range ctxt.Library {
566 s := ldr.CreateSymForUpdate("go:link.pkghashbytes."+l.Pkg, 0)
567 s.SetType(sym.SRODATA)
568 s.SetSize(int64(len(l.Fingerprint)))
569 s.SetData(l.Fingerprint[:])
570 str := ldr.CreateSymForUpdate("go:link.pkghash."+l.Pkg, 0)
571 str.SetType(sym.SRODATA)
572 str.AddAddr(ctxt.Arch, s.Sym())
573 str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
574 }
575 }
576
577 textsectionmapSym, nsections := textsectionmap(ctxt)
578
579
580
581
582
583 moduledata := ldr.MakeSymbolUpdater(ctxt.Moduledata)
584
585 slice := func(sym loader.Sym, len uint64) {
586 moduledata.AddAddr(ctxt.Arch, sym)
587 moduledata.AddUint(ctxt.Arch, len)
588 moduledata.AddUint(ctxt.Arch, len)
589 }
590
591 sliceSym := func(sym loader.Sym) {
592 slice(sym, uint64(ldr.SymSize(sym)))
593 }
594
595 nilSlice := func() {
596 moduledata.AddUint(ctxt.Arch, 0)
597 moduledata.AddUint(ctxt.Arch, 0)
598 moduledata.AddUint(ctxt.Arch, 0)
599 }
600
601
602 moduledata.AddAddr(ctxt.Arch, pcln.pcheader)
603
604
605 sliceSym(pcln.funcnametab)
606
607
608 slice(pcln.cutab, uint64(ldr.SymSize(pcln.cutab))/4)
609
610
611 sliceSym(pcln.filetab)
612
613
614 sliceSym(pcln.pctab)
615
616
617 sliceSym(pcln.pclntab)
618
619
620 slice(pcln.pclntab, uint64(pcln.nfunc+1))
621
622
623 moduledata.AddAddr(ctxt.Arch, pcln.findfunctab)
624
625 moduledata.AddAddr(ctxt.Arch, pcln.firstFunc)
626 moduledata.AddAddrPlus(ctxt.Arch, pcln.lastFunc, ldr.SymSize(pcln.lastFunc))
627
628 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.text", 0))
629 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etext", 0))
630 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrdata", 0))
631 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrdata", 0))
632 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
633 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.edata", 0))
634 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.bss", 0))
635 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ebss", 0))
636 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrbss", 0))
637 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrbss", 0))
638 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.covctrs", 0))
639 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ecovctrs", 0))
640 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.end", 0))
641 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
642 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
643 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
644 ctxt.moduledataTypeDescOffset = moduledata.Size()
645 moduledata.AddUint(ctxt.Arch, 0)
646 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
647 ctxt.moduledataItabOffset = moduledata.Size()
648 moduledata.AddUint(ctxt.Arch, 0)
649 ctxt.moduledataItabSizeOffset = moduledata.Size()
650 moduledata.AddUint(ctxt.Arch, 0)
651 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.rodata", 0))
652 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go:func.*", 0))
653 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.epclntab", 0))
654
655 if ctxt.IsAIX() && ctxt.IsExternal() {
656
657
658 addRef := func(name string) {
659 s := ldr.Lookup(name, 0)
660 if s == 0 {
661 return
662 }
663 r, _ := moduledata.AddRel(objabi.R_XCOFFREF)
664 r.SetSym(s)
665 r.SetSiz(uint8(ctxt.Arch.PtrSize))
666 }
667 addRef("runtime.rodata")
668 addRef("runtime.erodata")
669 addRef("runtime.epclntab")
670 addRef("go:func.*")
671
672
673
674
675
676 addRef("go:buildid")
677 }
678 if ctxt.IsAIX() {
679
680
681
682
683
684 sb := ldr.CreateSymForUpdate("runtime.aixStaticDataBase", 0)
685 sb.SetSize(0)
686 sb.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
687 sb.SetType(sym.SRODATA)
688 }
689
690
691 slice(textsectionmapSym, uint64(nsections))
692
693
694 if ptab := ldr.Lookup("go:plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
695 ldr.SetAttrLocal(ptab, true)
696 if ldr.SymType(ptab) != sym.SRODATA {
697 panic(fmt.Sprintf("go:plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
698 }
699 nentries := uint64(len(ldr.Data(ptab)) / 8)
700 slice(ptab, nentries)
701 } else {
702 nilSlice()
703 }
704
705 if ctxt.BuildMode == BuildModePlugin {
706 addgostring(ctxt, ldr, moduledata, "go:link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
707
708 pkghashes := ldr.CreateSymForUpdate("go:link.pkghashes", 0)
709 pkghashes.SetLocal(true)
710 pkghashes.SetType(sym.SRODATA)
711
712 for i, l := range ctxt.Library {
713
714 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkgname.%d", i), l.Pkg)
715
716 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
717
718 hash := ldr.Lookup("go:link.pkghash."+l.Pkg, 0)
719 pkghashes.AddAddr(ctxt.Arch, hash)
720 }
721 slice(pkghashes.Sym(), uint64(len(ctxt.Library)))
722 } else {
723 moduledata.AddUint(ctxt.Arch, 0)
724 moduledata.AddUint(ctxt.Arch, 0)
725 nilSlice()
726 }
727
728 t := ctxt.mainInittasks
729 if t != 0 {
730 moduledata.AddAddr(ctxt.Arch, t)
731 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(t)/int64(ctxt.Arch.PtrSize)))
732 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(t)/int64(ctxt.Arch.PtrSize)))
733 } else {
734
735
736
737
738 moduledata.AddUint(ctxt.Arch, 0)
739 moduledata.AddUint(ctxt.Arch, 0)
740 moduledata.AddUint(ctxt.Arch, 0)
741 }
742
743 if len(ctxt.Shlibs) > 0 {
744 thismodulename := filepath.Base(*flagOutfile)
745 switch ctxt.BuildMode {
746 case BuildModeExe, BuildModePIE:
747
748
749 thismodulename = "the executable"
750 }
751 addgostring(ctxt, ldr, moduledata, "go:link.thismodulename", thismodulename)
752
753 modulehashes := ldr.CreateSymForUpdate("go:link.abihashes", 0)
754 modulehashes.SetLocal(true)
755 modulehashes.SetType(sym.SRODATA)
756
757 for i, shlib := range ctxt.Shlibs {
758
759 modulename := filepath.Base(shlib.Path)
760 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.libname.%d", i), modulename)
761
762
763 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.linkhash.%d", i), string(shlib.Hash))
764
765
766 abihash := ldr.LookupOrCreateSym("go:link.abihash."+modulename, 0)
767 ldr.SetAttrReachable(abihash, true)
768 modulehashes.AddAddr(ctxt.Arch, abihash)
769 }
770
771 slice(modulehashes.Sym(), uint64(len(ctxt.Shlibs)))
772 } else {
773 moduledata.AddUint(ctxt.Arch, 0)
774 moduledata.AddUint(ctxt.Arch, 0)
775 nilSlice()
776 }
777
778 hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
779 if hasmain {
780 moduledata.AddUint8(1)
781 } else {
782 moduledata.AddUint8(0)
783 }
784
785
786
787
788
789 moduledatatype := ldr.Lookup("type:runtime.moduledata", 0)
790 moduledata.SetSize(decodetypeSize(ctxt.Arch, ldr.Data(moduledatatype)))
791 moduledata.Grow(moduledata.Size())
792
793 lastmoduledatap := ldr.CreateSymForUpdate("runtime.lastmoduledatap", 0)
794 if lastmoduledatap.Type() != sym.SDYNIMPORT {
795 lastmoduledatap.SetType(sym.SNOPTRDATA)
796 lastmoduledatap.SetSize(0)
797 lastmoduledatap.SetData(nil)
798 lastmoduledatap.AddAddr(ctxt.Arch, moduledata.Sym())
799 }
800 return symGroupType
801 }
802
803
804 var CarrierSymByType [sym.SFirstUnallocated]struct {
805 Sym loader.Sym
806 Size int64
807 }
808
809 func setCarrierSym(typ sym.SymKind, s loader.Sym) {
810 if CarrierSymByType[typ].Sym != 0 {
811 panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
812 }
813 CarrierSymByType[typ].Sym = s
814 }
815
816 func setCarrierSize(typ sym.SymKind, sz int64) {
817 if typ == sym.Sxxx {
818 panic("setCarrierSize(Sxxx)")
819 }
820 if CarrierSymByType[typ].Size != 0 {
821 panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
822 }
823 CarrierSymByType[typ].Size = sz
824 }
825
826 func isStaticTmp(name string) bool {
827 return strings.Contains(name, "."+obj.StaticNamePrefix)
828 }
829
830
831 func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string {
832
833
834
835
836
837
838
839
840
841
842 if !buildcfg.Experiment.RegabiWrappers {
843 return name
844 }
845
846 if ldr.SymType(x).IsText() && ldr.SymVersion(x) != sym.SymVerABIInternal && ldr.SymVersion(x) < sym.SymVerStatic {
847 if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2).IsText() {
848 name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x))
849 }
850 }
851
852
853
854
855
856
857 if ctxt.IsShared() {
858 if ldr.SymType(x).IsText() && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type:") {
859 name = fmt.Sprintf("%s.abiinternal", name)
860 }
861 }
862
863 return name
864 }
865
View as plain text