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