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