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