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