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.covctrs", sym.SNOPTRBSS, 0)
446 ctxt.xdefine("runtime.ecovctrs", sym.SNOPTRBSS, 0)
447 ctxt.xdefine("runtime.end", sym.SBSS, 0)
448 ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
449
450
451 s := ldr.CreateSymForUpdate("runtime.gcdata", 0)
452 s.SetType(sym.SRODATA)
453 s.SetSize(0)
454 ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
455
456 s = ldr.CreateSymForUpdate("runtime.gcbss", 0)
457 s.SetType(sym.SRODATA)
458 s.SetSize(0)
459 ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
460
461
462 var symtype loader.Sym
463 if !ctxt.DynlinkingGo() {
464 s = ldr.CreateSymForUpdate("type:*", 0)
465 s.SetType(sym.STYPE)
466 s.SetSize(0)
467 s.SetAlign(int32(ctxt.Arch.PtrSize))
468 symtype = s.Sym()
469 setCarrierSym(sym.STYPE, symtype)
470 }
471
472 groupSym := func(name string, t sym.SymKind) loader.Sym {
473 s := ldr.CreateSymForUpdate(name, 0)
474 s.SetType(t)
475 s.SetSize(0)
476 s.SetAlign(int32(ctxt.Arch.PtrSize))
477 s.SetLocal(true)
478 setCarrierSym(t, s.Sym())
479 return s.Sym()
480 }
481 var (
482 symgostring = groupSym("go:string.*", sym.SGOSTRING)
483 symgofunc = groupSym("go:funcdesc", sym.SGOFUNC)
484 symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS)
485 )
486
487
488
489
490
491
492
493 nsym := loader.Sym(ldr.NSym())
494 symGroupType := make([]sym.SymKind, nsym)
495 for s := loader.Sym(1); s < nsym; s++ {
496 if (!ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "") || (ctxt.LinkMode == LinkInternal && ldr.SymType(s) == sym.SCOVERAGE_COUNTER) {
497 ldr.SetAttrNotInSymbolTable(s, true)
498 }
499 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) {
500 continue
501 }
502
503 name := ldr.SymName(s)
504 switch {
505 case strings.HasPrefix(name, "go:string."):
506 symGroupType[s] = sym.SGOSTRING
507 ldr.SetAttrNotInSymbolTable(s, true)
508 ldr.SetCarrierSym(s, symgostring)
509
510 case strings.HasPrefix(name, "runtime.gcbits."),
511 strings.HasPrefix(name, "type:.gcprog."):
512 symGroupType[s] = sym.SGCBITS
513 ldr.SetAttrNotInSymbolTable(s, true)
514 ldr.SetCarrierSym(s, symgcbits)
515
516 case strings.HasSuffix(name, "·f"):
517 if !ctxt.DynlinkingGo() {
518 ldr.SetAttrNotInSymbolTable(s, true)
519 ldr.SetCarrierSym(s, symgofunc)
520 }
521 symGroupType[s] = sym.SGOFUNC
522
523 case strings.HasPrefix(name, "type:"):
524 if !ctxt.DynlinkingGo() {
525 ldr.SetAttrNotInSymbolTable(s, true)
526 }
527 symGroupType[s] = sym.STYPE
528 if symtype != 0 {
529 ldr.SetCarrierSym(s, symtype)
530 }
531 if ctxt.HeadType == objabi.Haix {
532
533
534
535
536 if symalign(ldr, s) > 8 {
537 ldr.SetSymAlign(s, 8)
538 }
539 }
540 }
541 }
542
543 if ctxt.BuildMode == BuildModeShared {
544 abihashgostr := ldr.CreateSymForUpdate("go:link.abihash."+filepath.Base(*flagOutfile), 0)
545 abihashgostr.SetType(sym.SRODATA)
546 hashsym := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
547 abihashgostr.AddAddr(ctxt.Arch, hashsym)
548 abihashgostr.AddUint(ctxt.Arch, uint64(ldr.SymSize(hashsym)))
549 }
550 if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
551 for _, l := range ctxt.Library {
552 s := ldr.CreateSymForUpdate("go:link.pkghashbytes."+l.Pkg, 0)
553 s.SetType(sym.SRODATA)
554 s.SetSize(int64(len(l.Fingerprint)))
555 s.SetData(l.Fingerprint[:])
556 str := ldr.CreateSymForUpdate("go:link.pkghash."+l.Pkg, 0)
557 str.SetType(sym.SRODATA)
558 str.AddAddr(ctxt.Arch, s.Sym())
559 str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
560 }
561 }
562
563 textsectionmapSym, nsections := textsectionmap(ctxt)
564
565
566
567
568
569 moduledata := ldr.MakeSymbolUpdater(ctxt.Moduledata)
570
571 slice := func(sym loader.Sym, len uint64) {
572 moduledata.AddAddr(ctxt.Arch, sym)
573 moduledata.AddUint(ctxt.Arch, len)
574 moduledata.AddUint(ctxt.Arch, len)
575 }
576
577 sliceSym := func(sym loader.Sym) {
578 slice(sym, uint64(ldr.SymSize(sym)))
579 }
580
581 nilSlice := func() {
582 moduledata.AddUint(ctxt.Arch, 0)
583 moduledata.AddUint(ctxt.Arch, 0)
584 moduledata.AddUint(ctxt.Arch, 0)
585 }
586
587
588 moduledata.AddAddr(ctxt.Arch, pcln.pcheader)
589
590
591 sliceSym(pcln.funcnametab)
592
593
594 slice(pcln.cutab, uint64(ldr.SymSize(pcln.cutab))/4)
595
596
597 sliceSym(pcln.filetab)
598
599
600 sliceSym(pcln.pctab)
601
602
603 sliceSym(pcln.pclntab)
604
605
606 slice(pcln.pclntab, uint64(pcln.nfunc+1))
607
608
609 moduledata.AddAddr(ctxt.Arch, pcln.findfunctab)
610
611 moduledata.AddAddr(ctxt.Arch, pcln.firstFunc)
612 moduledata.AddAddrPlus(ctxt.Arch, pcln.lastFunc, ldr.SymSize(pcln.lastFunc))
613
614 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.text", 0))
615 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etext", 0))
616 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrdata", 0))
617 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrdata", 0))
618 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
619 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.edata", 0))
620 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.bss", 0))
621 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ebss", 0))
622 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrbss", 0))
623 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrbss", 0))
624 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.covctrs", 0))
625 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ecovctrs", 0))
626 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.end", 0))
627 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
628 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
629 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
630 ctxt.moduledataTypeDescOffset = moduledata.Size()
631 moduledata.AddUint(ctxt.Arch, 0)
632 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
633 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.rodata", 0))
634 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go:func.*", 0))
635 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.epclntab", 0))
636
637 if ctxt.IsAIX() && ctxt.IsExternal() {
638
639
640 addRef := func(name string) {
641 s := ldr.Lookup(name, 0)
642 if s == 0 {
643 return
644 }
645 r, _ := moduledata.AddRel(objabi.R_XCOFFREF)
646 r.SetSym(s)
647 r.SetSiz(uint8(ctxt.Arch.PtrSize))
648 }
649 addRef("runtime.rodata")
650 addRef("runtime.erodata")
651 addRef("runtime.epclntab")
652 addRef("go:func.*")
653
654
655
656
657
658 addRef("go:buildid")
659 }
660 if ctxt.IsAIX() {
661
662
663
664
665
666 sb := ldr.CreateSymForUpdate("runtime.aixStaticDataBase", 0)
667 sb.SetSize(0)
668 sb.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
669 sb.SetType(sym.SRODATA)
670 }
671
672
673 slice(textsectionmapSym, uint64(nsections))
674
675
676 itablinkSym := ldr.Lookup("runtime.itablink", 0)
677 nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize)
678 slice(itablinkSym, nitablinks)
679
680
681 if ptab := ldr.Lookup("go:plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
682 ldr.SetAttrLocal(ptab, true)
683 if ldr.SymType(ptab) != sym.SRODATA {
684 panic(fmt.Sprintf("go:plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
685 }
686 nentries := uint64(len(ldr.Data(ptab)) / 8)
687 slice(ptab, nentries)
688 } else {
689 nilSlice()
690 }
691
692 if ctxt.BuildMode == BuildModePlugin {
693 addgostring(ctxt, ldr, moduledata, "go:link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
694
695 pkghashes := ldr.CreateSymForUpdate("go:link.pkghashes", 0)
696 pkghashes.SetLocal(true)
697 pkghashes.SetType(sym.SRODATA)
698
699 for i, l := range ctxt.Library {
700
701 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkgname.%d", i), l.Pkg)
702
703 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
704
705 hash := ldr.Lookup("go:link.pkghash."+l.Pkg, 0)
706 pkghashes.AddAddr(ctxt.Arch, hash)
707 }
708 slice(pkghashes.Sym(), uint64(len(ctxt.Library)))
709 } else {
710 moduledata.AddUint(ctxt.Arch, 0)
711 moduledata.AddUint(ctxt.Arch, 0)
712 nilSlice()
713 }
714
715 t := ctxt.mainInittasks
716 if t != 0 {
717 moduledata.AddAddr(ctxt.Arch, t)
718 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(t)/int64(ctxt.Arch.PtrSize)))
719 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(t)/int64(ctxt.Arch.PtrSize)))
720 } else {
721
722
723
724
725 moduledata.AddUint(ctxt.Arch, 0)
726 moduledata.AddUint(ctxt.Arch, 0)
727 moduledata.AddUint(ctxt.Arch, 0)
728 }
729
730 if len(ctxt.Shlibs) > 0 {
731 thismodulename := filepath.Base(*flagOutfile)
732 switch ctxt.BuildMode {
733 case BuildModeExe, BuildModePIE:
734
735
736 thismodulename = "the executable"
737 }
738 addgostring(ctxt, ldr, moduledata, "go:link.thismodulename", thismodulename)
739
740 modulehashes := ldr.CreateSymForUpdate("go:link.abihashes", 0)
741 modulehashes.SetLocal(true)
742 modulehashes.SetType(sym.SRODATA)
743
744 for i, shlib := range ctxt.Shlibs {
745
746 modulename := filepath.Base(shlib.Path)
747 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.libname.%d", i), modulename)
748
749
750 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.linkhash.%d", i), string(shlib.Hash))
751
752
753 abihash := ldr.LookupOrCreateSym("go:link.abihash."+modulename, 0)
754 ldr.SetAttrReachable(abihash, true)
755 modulehashes.AddAddr(ctxt.Arch, abihash)
756 }
757
758 slice(modulehashes.Sym(), uint64(len(ctxt.Shlibs)))
759 } else {
760 moduledata.AddUint(ctxt.Arch, 0)
761 moduledata.AddUint(ctxt.Arch, 0)
762 nilSlice()
763 }
764
765 hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
766 if hasmain {
767 moduledata.AddUint8(1)
768 } else {
769 moduledata.AddUint8(0)
770 }
771
772
773
774
775
776 moduledatatype := ldr.Lookup("type:runtime.moduledata", 0)
777 moduledata.SetSize(decodetypeSize(ctxt.Arch, ldr.Data(moduledatatype)))
778 moduledata.Grow(moduledata.Size())
779
780 lastmoduledatap := ldr.CreateSymForUpdate("runtime.lastmoduledatap", 0)
781 if lastmoduledatap.Type() != sym.SDYNIMPORT {
782 lastmoduledatap.SetType(sym.SNOPTRDATA)
783 lastmoduledatap.SetSize(0)
784 lastmoduledatap.SetData(nil)
785 lastmoduledatap.AddAddr(ctxt.Arch, moduledata.Sym())
786 }
787 return symGroupType
788 }
789
790
791 var CarrierSymByType [sym.SFirstUnallocated]struct {
792 Sym loader.Sym
793 Size int64
794 }
795
796 func setCarrierSym(typ sym.SymKind, s loader.Sym) {
797 if CarrierSymByType[typ].Sym != 0 {
798 panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
799 }
800 CarrierSymByType[typ].Sym = s
801 }
802
803 func setCarrierSize(typ sym.SymKind, sz int64) {
804 if typ == sym.Sxxx {
805 panic("setCarrierSize(Sxxx)")
806 }
807 if CarrierSymByType[typ].Size != 0 {
808 panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
809 }
810 CarrierSymByType[typ].Size = sz
811 }
812
813 func isStaticTmp(name string) bool {
814 return strings.Contains(name, "."+obj.StaticNamePrefix)
815 }
816
817
818 func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string {
819
820
821
822
823
824
825
826
827
828
829 if !buildcfg.Experiment.RegabiWrappers {
830 return name
831 }
832
833 if ldr.SymType(x).IsText() && ldr.SymVersion(x) != sym.SymVerABIInternal && ldr.SymVersion(x) < sym.SymVerStatic {
834 if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2).IsText() {
835 name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x))
836 }
837 }
838
839
840
841
842
843
844 if ctxt.IsShared() {
845 if ldr.SymType(x).IsText() && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type:") {
846 name = fmt.Sprintf("%s.abiinternal", name)
847 }
848 }
849
850 return name
851 }
852
View as plain text