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) && ldr.SymName(x) != "runtime.duffzero" && ldr.SymName(x) != "runtime.duffcopy" {
141
142
143
144
145
146
147 other |= 3 << 5
148 }
149
150
151
152
153 if !ctxt.DynlinkingGo() {
154
155 sname = strings.Replace(sname, "·", ".", -1)
156 }
157
158 if ctxt.DynlinkingGo() && bind == elf.STB_GLOBAL && curbind == elf.STB_LOCAL && ldr.SymType(x) == sym.STEXT {
159
160
161
162
163
164
165
166
167 putelfsyment(ctxt.Out, putelfstr("local."+sname), addr, size, elf.ST_INFO(elf.STB_LOCAL, typ), elfshnum, other)
168 ldr.SetSymLocalElfSym(x, int32(ctxt.numelfsym))
169 ctxt.numelfsym++
170 return
171 } else if bind != curbind {
172 return
173 }
174
175 putelfsyment(ctxt.Out, putelfstr(sname), addr, size, elf.ST_INFO(bind, typ), elfshnum, other)
176 ldr.SetSymElfSym(x, int32(ctxt.numelfsym))
177 ctxt.numelfsym++
178 }
179
180 func putelfsectionsym(ctxt *Link, out *OutBuf, s loader.Sym, shndx elf.SectionIndex) {
181 putelfsyment(out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_SECTION), shndx, 0)
182 ctxt.loader.SetSymElfSym(s, int32(ctxt.numelfsym))
183 ctxt.numelfsym++
184 }
185
186 func genelfsym(ctxt *Link, elfbind elf.SymBind) {
187 ldr := ctxt.loader
188
189
190 s := ldr.Lookup("runtime.text", 0)
191 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
192 for k, sect := range Segtext.Sections[1:] {
193 n := k + 1
194 if sect.Name != ".text" || (ctxt.IsAIX() && ctxt.IsExternal()) {
195
196 break
197 }
198 s = ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
199 if s == 0 {
200 break
201 }
202 if ldr.SymType(s) != sym.STEXT {
203 panic("unexpected type for runtime.text symbol")
204 }
205 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
206 }
207
208
209 for _, s := range ctxt.Textp {
210 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
211 }
212
213
214 s = ldr.Lookup("runtime.etext", 0)
215 if ldr.SymType(s) == sym.STEXT {
216 putelfsym(ctxt, s, elf.STT_FUNC, elfbind)
217 }
218
219 shouldBeInSymbolTable := func(s loader.Sym) bool {
220 if ldr.AttrNotInSymbolTable(s) {
221 return false
222 }
223
224
225
226
227 sn := ldr.SymName(s)
228 if (sn == "" || sn[0] == '.') && ldr.IsFileLocal(s) {
229 panic(fmt.Sprintf("unexpected file local symbol %d %s<%d>\n",
230 s, sn, ldr.SymVersion(s)))
231 }
232 if (sn == "" || sn[0] == '.') && !ldr.IsFileLocal(s) {
233 return false
234 }
235 return true
236 }
237
238
239 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
240 if !ldr.AttrReachable(s) {
241 continue
242 }
243 st := ldr.SymType(s)
244 if st >= sym.SELFRXSECT && st < sym.SXREF {
245 typ := elf.STT_OBJECT
246 if st == sym.STLSBSS {
247 if ctxt.IsInternal() {
248 continue
249 }
250 typ = elf.STT_TLS
251 }
252 if !shouldBeInSymbolTable(s) {
253 continue
254 }
255 putelfsym(ctxt, s, typ, elfbind)
256 continue
257 }
258 if st == sym.SHOSTOBJ || st == sym.SDYNIMPORT || st == sym.SUNDEFEXT {
259 putelfsym(ctxt, s, ldr.SymElfType(s), elfbind)
260 }
261 }
262 }
263
264 func asmElfSym(ctxt *Link) {
265
266
267 putelfsyment(ctxt.Out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_NOTYPE), 0, 0)
268
269 dwarfaddelfsectionsyms(ctxt)
270
271
272
273
274
275 putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_FILE), elf.SHN_ABS, 0)
276 ctxt.numelfsym++
277
278 bindings := []elf.SymBind{elf.STB_LOCAL, elf.STB_GLOBAL}
279 for _, elfbind := range bindings {
280 if elfbind == elf.STB_GLOBAL {
281 elfglobalsymndx = ctxt.numelfsym
282 }
283 genelfsym(ctxt, elfbind)
284 }
285 }
286
287 func putplan9sym(ctxt *Link, ldr *loader.Loader, s loader.Sym, char SymbolType) {
288 t := int(char)
289 if ldr.IsFileLocal(s) {
290 t += 'a' - 'A'
291 }
292 l := 4
293 addr := ldr.SymValue(s)
294 if ctxt.IsAMD64() && !flag8 {
295 ctxt.Out.Write32b(uint32(addr >> 32))
296 l = 8
297 }
298
299 ctxt.Out.Write32b(uint32(addr))
300 ctxt.Out.Write8(uint8(t + 0x80))
301
302 name := ldr.SymName(s)
303 ctxt.Out.WriteString(name)
304 ctxt.Out.Write8(0)
305
306 symSize += int32(l) + 1 + int32(len(name)) + 1
307 }
308
309 func asmbPlan9Sym(ctxt *Link) {
310 ldr := ctxt.loader
311
312
313 s := ldr.Lookup("runtime.text", 0)
314 if ldr.SymType(s) == sym.STEXT {
315 putplan9sym(ctxt, ldr, s, TextSym)
316 }
317 s = ldr.Lookup("runtime.etext", 0)
318 if ldr.SymType(s) == sym.STEXT {
319 putplan9sym(ctxt, ldr, s, TextSym)
320 }
321
322
323 for _, s := range ctxt.Textp {
324 putplan9sym(ctxt, ldr, s, TextSym)
325 }
326
327 shouldBeInSymbolTable := func(s loader.Sym) bool {
328 if ldr.AttrNotInSymbolTable(s) {
329 return false
330 }
331 name := ldr.RawSymName(s)
332 if name == "" || name[0] == '.' {
333 return false
334 }
335 return true
336 }
337
338
339 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
340 if !ldr.AttrReachable(s) {
341 continue
342 }
343 t := ldr.SymType(s)
344 if t >= sym.SELFRXSECT && t < sym.SXREF {
345 if t == sym.STLSBSS {
346 continue
347 }
348 if !shouldBeInSymbolTable(s) {
349 continue
350 }
351 char := DataSym
352 if t == sym.SBSS || t == sym.SNOPTRBSS {
353 char = BSSSym
354 }
355 putplan9sym(ctxt, ldr, s, char)
356 }
357 }
358 }
359
360 type byPkg []*sym.Library
361
362 func (libs byPkg) Len() int {
363 return len(libs)
364 }
365
366 func (libs byPkg) Less(a, b int) bool {
367 return libs[a].Pkg < libs[b].Pkg
368 }
369
370 func (libs byPkg) Swap(a, b int) {
371 libs[a], libs[b] = libs[b], libs[a]
372 }
373
374
375
376 func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
377 ldr := ctxt.loader
378 t := ldr.CreateSymForUpdate("runtime.textsectionmap", 0)
379 t.SetType(sym.SRODATA)
380 nsections := int64(0)
381
382 for _, sect := range Segtext.Sections {
383 if sect.Name == ".text" {
384 nsections++
385 } else {
386 break
387 }
388 }
389 t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
390
391 off := int64(0)
392 n := 0
393
394
395
396
397
398
399
400
401
402
403 textbase := Segtext.Sections[0].Vaddr
404 for _, sect := range Segtext.Sections {
405 if sect.Name != ".text" {
406 break
407 }
408 off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
409 off = t.SetUint(ctxt.Arch, off, sect.Length)
410 if n == 0 {
411 s := ldr.Lookup("runtime.text", 0)
412 if s == 0 {
413 ctxt.Errorf(s, "Unable to find symbol runtime.text\n")
414 }
415 off = t.SetAddr(ctxt.Arch, off, s)
416
417 } else {
418 s := ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
419 if s == 0 {
420 ctxt.Errorf(s, "Unable to find symbol runtime.text.%d\n", n)
421 }
422 off = t.SetAddr(ctxt.Arch, off, s)
423 }
424 n++
425 }
426 return t.Sym(), uint32(n)
427 }
428
429 func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
430 ldr := ctxt.loader
431
432 if !ctxt.IsAIX() {
433 switch ctxt.BuildMode {
434 case BuildModeCArchive, BuildModeCShared:
435 s := ldr.Lookup(*flagEntrySymbol, sym.SymVerABI0)
436 if s != 0 {
437 addinitarrdata(ctxt, ldr, s)
438 }
439 }
440 }
441
442
443
444 ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
445 ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
446 ctxt.xdefine("runtime.types", sym.SRODATA, 0)
447 ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
448 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
449 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
450 ctxt.xdefine("runtime.data", sym.SDATA, 0)
451 ctxt.xdefine("runtime.edata", sym.SDATA, 0)
452 ctxt.xdefine("runtime.bss", sym.SBSS, 0)
453 ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
454 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
455 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
456 ctxt.xdefine("runtime.end", sym.SBSS, 0)
457 ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
458 ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
459
460
461 s := ldr.CreateSymForUpdate("runtime.gcdata", 0)
462 s.SetType(sym.SRODATA)
463 s.SetSize(0)
464 ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
465
466 s = ldr.CreateSymForUpdate("runtime.gcbss", 0)
467 s.SetType(sym.SRODATA)
468 s.SetSize(0)
469 ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
470
471
472 var symtype, symtyperel loader.Sym
473 if !ctxt.DynlinkingGo() {
474 if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
475 s = ldr.CreateSymForUpdate("type.*", 0)
476 s.SetType(sym.STYPE)
477 s.SetSize(0)
478 symtype = s.Sym()
479
480 s = ldr.CreateSymForUpdate("typerel.*", 0)
481 s.SetType(sym.STYPERELRO)
482 s.SetSize(0)
483 symtyperel = s.Sym()
484 } else {
485 s = ldr.CreateSymForUpdate("type.*", 0)
486 s.SetType(sym.STYPE)
487 s.SetSize(0)
488 symtype = s.Sym()
489 symtyperel = s.Sym()
490 }
491 setCarrierSym(sym.STYPE, symtype)
492 setCarrierSym(sym.STYPERELRO, symtyperel)
493 }
494
495 groupSym := func(name string, t sym.SymKind) loader.Sym {
496 s := ldr.CreateSymForUpdate(name, 0)
497 s.SetType(t)
498 s.SetSize(0)
499 s.SetLocal(true)
500 setCarrierSym(t, s.Sym())
501 return s.Sym()
502 }
503 var (
504 symgostring = groupSym("go.string.*", sym.SGOSTRING)
505 symgofunc = groupSym("go.func.*", sym.SGOFUNC)
506 symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS)
507 )
508
509 var symgofuncrel loader.Sym
510 if !ctxt.DynlinkingGo() {
511 if ctxt.UseRelro() {
512 symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
513 } else {
514 symgofuncrel = symgofunc
515 }
516 }
517
518 symt := ldr.CreateSymForUpdate("runtime.symtab", 0)
519 symt.SetType(sym.SSYMTAB)
520 symt.SetSize(0)
521 symt.SetLocal(true)
522
523
524
525
526
527 nsym := loader.Sym(ldr.NSym())
528 symGroupType := make([]sym.SymKind, nsym)
529 for s := loader.Sym(1); s < nsym; s++ {
530 if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "" {
531 ldr.SetAttrNotInSymbolTable(s, true)
532 }
533 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) {
534 continue
535 }
536
537 name := ldr.SymName(s)
538 switch {
539 case strings.HasPrefix(name, "type."):
540 if !ctxt.DynlinkingGo() {
541 ldr.SetAttrNotInSymbolTable(s, true)
542 }
543 if ctxt.UseRelro() {
544 symGroupType[s] = sym.STYPERELRO
545 if symtyperel != 0 {
546 ldr.SetCarrierSym(s, symtyperel)
547 }
548 } else {
549 symGroupType[s] = sym.STYPE
550 if symtyperel != 0 {
551 ldr.SetCarrierSym(s, symtype)
552 }
553 }
554
555 case strings.HasPrefix(name, "go.importpath.") && ctxt.UseRelro():
556
557
558 symGroupType[s] = sym.STYPERELRO
559
560 case strings.HasPrefix(name, "go.string."):
561 symGroupType[s] = sym.SGOSTRING
562 ldr.SetAttrNotInSymbolTable(s, true)
563 ldr.SetCarrierSym(s, symgostring)
564
565 case strings.HasPrefix(name, "runtime.gcbits."):
566 symGroupType[s] = sym.SGCBITS
567 ldr.SetAttrNotInSymbolTable(s, true)
568 ldr.SetCarrierSym(s, symgcbits)
569
570 case strings.HasSuffix(name, "·f"):
571 if !ctxt.DynlinkingGo() {
572 ldr.SetAttrNotInSymbolTable(s, true)
573 }
574 if ctxt.UseRelro() {
575 symGroupType[s] = sym.SGOFUNCRELRO
576 if symgofuncrel != 0 {
577 ldr.SetCarrierSym(s, symgofuncrel)
578 }
579 } else {
580 symGroupType[s] = sym.SGOFUNC
581 ldr.SetCarrierSym(s, symgofunc)
582 }
583
584 case strings.HasPrefix(name, "gcargs."),
585 strings.HasPrefix(name, "gclocals."),
586 strings.HasPrefix(name, "gclocals·"),
587 ldr.SymType(s) == sym.SGOFUNC && s != symgofunc,
588 strings.HasSuffix(name, ".opendefer"),
589 strings.HasSuffix(name, ".arginfo0"),
590 strings.HasSuffix(name, ".arginfo1"):
591 symGroupType[s] = sym.SGOFUNC
592 ldr.SetAttrNotInSymbolTable(s, true)
593 ldr.SetCarrierSym(s, symgofunc)
594 align := int32(4)
595 if a := ldr.SymAlign(s); a < align {
596 ldr.SetSymAlign(s, align)
597 } else {
598 align = a
599 }
600 liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1)
601 }
602 }
603
604 if ctxt.BuildMode == BuildModeShared {
605 abihashgostr := ldr.CreateSymForUpdate("go.link.abihash."+filepath.Base(*flagOutfile), 0)
606 abihashgostr.SetType(sym.SRODATA)
607 hashsym := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
608 abihashgostr.AddAddr(ctxt.Arch, hashsym)
609 abihashgostr.AddUint(ctxt.Arch, uint64(ldr.SymSize(hashsym)))
610 }
611 if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
612 for _, l := range ctxt.Library {
613 s := ldr.CreateSymForUpdate("go.link.pkghashbytes."+l.Pkg, 0)
614 s.SetType(sym.SRODATA)
615 s.SetSize(int64(len(l.Fingerprint)))
616 s.SetData(l.Fingerprint[:])
617 str := ldr.CreateSymForUpdate("go.link.pkghash."+l.Pkg, 0)
618 str.SetType(sym.SRODATA)
619 str.AddAddr(ctxt.Arch, s.Sym())
620 str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
621 }
622 }
623
624 textsectionmapSym, nsections := textsectionmap(ctxt)
625
626
627
628
629
630 moduledata := ldr.MakeSymbolUpdater(ctxt.Moduledata)
631
632 moduledata.AddAddr(ctxt.Arch, pcln.pcheader)
633
634 moduledata.AddAddr(ctxt.Arch, pcln.funcnametab)
635 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab)))
636 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab)))
637
638 moduledata.AddAddr(ctxt.Arch, pcln.cutab)
639 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab)))
640 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab)))
641
642 moduledata.AddAddr(ctxt.Arch, pcln.filetab)
643 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
644 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
645
646 moduledata.AddAddr(ctxt.Arch, pcln.pctab)
647 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
648 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
649
650 moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
651 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
652 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
653
654 moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
655 moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1))
656 moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1))
657
658 moduledata.AddAddr(ctxt.Arch, pcln.findfunctab)
659
660 moduledata.AddAddr(ctxt.Arch, pcln.firstFunc)
661 moduledata.AddAddrPlus(ctxt.Arch, pcln.lastFunc, ldr.SymSize(pcln.lastFunc))
662
663 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.text", 0))
664 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etext", 0))
665 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrdata", 0))
666 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrdata", 0))
667 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
668 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.edata", 0))
669 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.bss", 0))
670 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ebss", 0))
671 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrbss", 0))
672 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrbss", 0))
673 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.end", 0))
674 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
675 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
676 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
677 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
678
679 if ctxt.IsAIX() && ctxt.IsExternal() {
680
681
682 addRef := func(name string) {
683 r, _ := moduledata.AddRel(objabi.R_XCOFFREF)
684 r.SetSym(ldr.Lookup(name, 0))
685 r.SetSiz(uint8(ctxt.Arch.PtrSize))
686 }
687 addRef("runtime.rodata")
688 addRef("runtime.erodata")
689 addRef("runtime.epclntab")
690 }
691
692
693 moduledata.AddAddr(ctxt.Arch, textsectionmapSym)
694 moduledata.AddUint(ctxt.Arch, uint64(nsections))
695 moduledata.AddUint(ctxt.Arch, uint64(nsections))
696
697
698 typelinkSym := ldr.Lookup("runtime.typelink", 0)
699 ntypelinks := uint64(ldr.SymSize(typelinkSym)) / 4
700 moduledata.AddAddr(ctxt.Arch, typelinkSym)
701 moduledata.AddUint(ctxt.Arch, ntypelinks)
702 moduledata.AddUint(ctxt.Arch, ntypelinks)
703
704 itablinkSym := ldr.Lookup("runtime.itablink", 0)
705 nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize)
706 moduledata.AddAddr(ctxt.Arch, itablinkSym)
707 moduledata.AddUint(ctxt.Arch, nitablinks)
708 moduledata.AddUint(ctxt.Arch, nitablinks)
709
710 if ptab := ldr.Lookup("go.plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
711 ldr.SetAttrLocal(ptab, true)
712 if ldr.SymType(ptab) != sym.SRODATA {
713 panic(fmt.Sprintf("go.plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
714 }
715 nentries := uint64(len(ldr.Data(ptab)) / 8)
716 moduledata.AddAddr(ctxt.Arch, ptab)
717 moduledata.AddUint(ctxt.Arch, nentries)
718 moduledata.AddUint(ctxt.Arch, nentries)
719 } else {
720 moduledata.AddUint(ctxt.Arch, 0)
721 moduledata.AddUint(ctxt.Arch, 0)
722 moduledata.AddUint(ctxt.Arch, 0)
723 }
724 if ctxt.BuildMode == BuildModePlugin {
725 addgostring(ctxt, ldr, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
726
727 pkghashes := ldr.CreateSymForUpdate("go.link.pkghashes", 0)
728 pkghashes.SetLocal(true)
729 pkghashes.SetType(sym.SRODATA)
730
731 for i, l := range ctxt.Library {
732
733 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
734
735 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
736
737 hash := ldr.Lookup("go.link.pkghash."+l.Pkg, 0)
738 pkghashes.AddAddr(ctxt.Arch, hash)
739 }
740 moduledata.AddAddr(ctxt.Arch, pkghashes.Sym())
741 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
742 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
743 } else {
744 moduledata.AddUint(ctxt.Arch, 0)
745 moduledata.AddUint(ctxt.Arch, 0)
746 moduledata.AddUint(ctxt.Arch, 0)
747 moduledata.AddUint(ctxt.Arch, 0)
748 moduledata.AddUint(ctxt.Arch, 0)
749 }
750 if len(ctxt.Shlibs) > 0 {
751 thismodulename := filepath.Base(*flagOutfile)
752 switch ctxt.BuildMode {
753 case BuildModeExe, BuildModePIE:
754
755
756 thismodulename = "the executable"
757 }
758 addgostring(ctxt, ldr, moduledata, "go.link.thismodulename", thismodulename)
759
760 modulehashes := ldr.CreateSymForUpdate("go.link.abihashes", 0)
761 modulehashes.SetLocal(true)
762 modulehashes.SetType(sym.SRODATA)
763
764 for i, shlib := range ctxt.Shlibs {
765
766 modulename := filepath.Base(shlib.Path)
767 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
768
769
770 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
771
772
773 abihash := ldr.LookupOrCreateSym("go.link.abihash."+modulename, 0)
774 ldr.SetAttrReachable(abihash, true)
775 modulehashes.AddAddr(ctxt.Arch, abihash)
776 }
777
778 moduledata.AddAddr(ctxt.Arch, modulehashes.Sym())
779 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
780 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
781 } else {
782 moduledata.AddUint(ctxt.Arch, 0)
783 moduledata.AddUint(ctxt.Arch, 0)
784 moduledata.AddUint(ctxt.Arch, 0)
785 moduledata.AddUint(ctxt.Arch, 0)
786 moduledata.AddUint(ctxt.Arch, 0)
787 }
788
789 hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
790 if hasmain {
791 moduledata.AddUint8(1)
792 } else {
793 moduledata.AddUint8(0)
794 }
795
796
797
798
799
800 moduledatatype := ldr.Lookup("type.runtime.moduledata", 0)
801 moduledata.SetSize(decodetypeSize(ctxt.Arch, ldr.Data(moduledatatype)))
802 moduledata.Grow(moduledata.Size())
803
804 lastmoduledatap := ldr.CreateSymForUpdate("runtime.lastmoduledatap", 0)
805 if lastmoduledatap.Type() != sym.SDYNIMPORT {
806 lastmoduledatap.SetType(sym.SNOPTRDATA)
807 lastmoduledatap.SetSize(0)
808 lastmoduledatap.SetData(nil)
809 lastmoduledatap.AddAddr(ctxt.Arch, moduledata.Sym())
810 }
811 return symGroupType
812 }
813
814
815 var CarrierSymByType [sym.SXREF]struct {
816 Sym loader.Sym
817 Size int64
818 }
819
820 func setCarrierSym(typ sym.SymKind, s loader.Sym) {
821 if CarrierSymByType[typ].Sym != 0 {
822 panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
823 }
824 CarrierSymByType[typ].Sym = s
825 }
826
827 func setCarrierSize(typ sym.SymKind, sz int64) {
828 if CarrierSymByType[typ].Size != 0 {
829 panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
830 }
831 CarrierSymByType[typ].Size = sz
832 }
833
834 func isStaticTmp(name string) bool {
835 return strings.Contains(name, "."+obj.StaticNamePref)
836 }
837
838
839 func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string {
840
841
842
843
844
845
846
847
848
849
850 if !buildcfg.Experiment.RegabiWrappers {
851 return name
852 }
853
854 if !ldr.IsExternal(x) && ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) != sym.SymVerABIInternal {
855 if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2) == sym.STEXT {
856 name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x))
857 }
858 }
859
860
861
862
863
864
865 if ctxt.IsShared() {
866 if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type.") {
867 name = fmt.Sprintf("%s.abiinternal", name)
868 }
869 }
870
871 return name
872 }
873
View as plain text