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