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