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 name = mangleABIName(ctxt, ldr, s, name)
304 ctxt.Out.WriteString(name)
305 ctxt.Out.Write8(0)
306
307 symSize += int32(l) + 1 + int32(len(name)) + 1
308 }
309
310 func asmbPlan9Sym(ctxt *Link) {
311 ldr := ctxt.loader
312
313
314 s := ldr.Lookup("runtime.text", 0)
315 if ldr.SymType(s) == sym.STEXT {
316 putplan9sym(ctxt, ldr, s, TextSym)
317 }
318 s = ldr.Lookup("runtime.etext", 0)
319 if ldr.SymType(s) == sym.STEXT {
320 putplan9sym(ctxt, ldr, s, TextSym)
321 }
322
323
324 for _, s := range ctxt.Textp {
325 putplan9sym(ctxt, ldr, s, TextSym)
326 }
327
328 shouldBeInSymbolTable := func(s loader.Sym) bool {
329 if ldr.AttrNotInSymbolTable(s) {
330 return false
331 }
332 name := ldr.RawSymName(s)
333 if name == "" || name[0] == '.' {
334 return false
335 }
336 return true
337 }
338
339
340 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
341 if !ldr.AttrReachable(s) {
342 continue
343 }
344 t := ldr.SymType(s)
345 if t >= sym.SELFRXSECT && t < sym.SXREF {
346 if t == sym.STLSBSS {
347 continue
348 }
349 if !shouldBeInSymbolTable(s) {
350 continue
351 }
352 char := DataSym
353 if t == sym.SBSS || t == sym.SNOPTRBSS {
354 char = BSSSym
355 }
356 putplan9sym(ctxt, ldr, s, char)
357 }
358 }
359 }
360
361 type byPkg []*sym.Library
362
363 func (libs byPkg) Len() int {
364 return len(libs)
365 }
366
367 func (libs byPkg) Less(a, b int) bool {
368 return libs[a].Pkg < libs[b].Pkg
369 }
370
371 func (libs byPkg) Swap(a, b int) {
372 libs[a], libs[b] = libs[b], libs[a]
373 }
374
375
376
377 func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
378 ldr := ctxt.loader
379 t := ldr.CreateSymForUpdate("runtime.textsectionmap", 0)
380 t.SetType(sym.SRODATA)
381 nsections := int64(0)
382
383 for _, sect := range Segtext.Sections {
384 if sect.Name == ".text" {
385 nsections++
386 } else {
387 break
388 }
389 }
390 t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
391
392 off := int64(0)
393 n := 0
394
395
396
397
398
399
400
401
402
403
404 textbase := Segtext.Sections[0].Vaddr
405 for _, sect := range Segtext.Sections {
406 if sect.Name != ".text" {
407 break
408 }
409
410
411 vaddr := sect.Vaddr - textbase
412 off = t.SetUint(ctxt.Arch, off, vaddr)
413 end := vaddr + sect.Length
414 off = t.SetUint(ctxt.Arch, off, end)
415 name := "runtime.text"
416 if n != 0 {
417 name = fmt.Sprintf("runtime.text.%d", n)
418 }
419 s := ldr.Lookup(name, 0)
420 if s == 0 {
421 ctxt.Errorf(s, "Unable to find symbol %s\n", name)
422 }
423 off = t.SetAddr(ctxt.Arch, off, s)
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 symgofuncrel := symgofunc
510 if ctxt.UseRelro() {
511 symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
512 }
513
514 symt := ldr.CreateSymForUpdate("runtime.symtab", 0)
515 symt.SetType(sym.SSYMTAB)
516 symt.SetSize(0)
517 symt.SetLocal(true)
518
519
520
521
522
523
524
525 nsym := loader.Sym(ldr.NSym())
526 symGroupType := make([]sym.SymKind, nsym)
527 for s := loader.Sym(1); s < nsym; s++ {
528 if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "" {
529 ldr.SetAttrNotInSymbolTable(s, true)
530 }
531 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) {
532 continue
533 }
534
535 name := ldr.SymName(s)
536 switch {
537 case strings.HasPrefix(name, "go.string."):
538 symGroupType[s] = sym.SGOSTRING
539 ldr.SetAttrNotInSymbolTable(s, true)
540 ldr.SetCarrierSym(s, symgostring)
541
542 case strings.HasPrefix(name, "runtime.gcbits."),
543 strings.HasPrefix(name, "type..gcprog."):
544 symGroupType[s] = sym.SGCBITS
545 ldr.SetAttrNotInSymbolTable(s, true)
546 ldr.SetCarrierSym(s, symgcbits)
547
548 case strings.HasSuffix(name, "·f"):
549 if !ctxt.DynlinkingGo() {
550 ldr.SetAttrNotInSymbolTable(s, true)
551 }
552 if ctxt.UseRelro() {
553 symGroupType[s] = sym.SGOFUNCRELRO
554 if !ctxt.DynlinkingGo() {
555 ldr.SetCarrierSym(s, symgofuncrel)
556 }
557 } else {
558 symGroupType[s] = sym.SGOFUNC
559 ldr.SetCarrierSym(s, symgofunc)
560 }
561
562 case strings.HasPrefix(name, "gcargs."),
563 strings.HasPrefix(name, "gclocals."),
564 strings.HasPrefix(name, "gclocals·"),
565 ldr.SymType(s) == sym.SGOFUNC && s != symgofunc,
566 strings.HasSuffix(name, ".opendefer"),
567 strings.HasSuffix(name, ".arginfo0"),
568 strings.HasSuffix(name, ".arginfo1"),
569 strings.HasSuffix(name, ".argliveinfo"),
570 strings.HasSuffix(name, ".wrapinfo"),
571 strings.HasSuffix(name, ".args_stackmap"),
572 strings.HasSuffix(name, ".stkobj"):
573 ldr.SetAttrNotInSymbolTable(s, true)
574 symGroupType[s] = sym.SGOFUNC
575 ldr.SetCarrierSym(s, symgofunc)
576 if ctxt.Debugvlog != 0 {
577 align := ldr.SymAlign(s)
578 liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1)
579 }
580
581
582
583
584 case strings.HasPrefix(name, "type."):
585 if !ctxt.DynlinkingGo() {
586 ldr.SetAttrNotInSymbolTable(s, true)
587 }
588 if ctxt.UseRelro() {
589 symGroupType[s] = sym.STYPERELRO
590 if symtyperel != 0 {
591 ldr.SetCarrierSym(s, symtyperel)
592 }
593 } else {
594 symGroupType[s] = sym.STYPE
595 if symtyperel != 0 {
596 ldr.SetCarrierSym(s, symtype)
597 }
598 }
599 }
600 }
601
602 if ctxt.BuildMode == BuildModeShared {
603 abihashgostr := ldr.CreateSymForUpdate("go.link.abihash."+filepath.Base(*flagOutfile), 0)
604 abihashgostr.SetType(sym.SRODATA)
605 hashsym := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
606 abihashgostr.AddAddr(ctxt.Arch, hashsym)
607 abihashgostr.AddUint(ctxt.Arch, uint64(ldr.SymSize(hashsym)))
608 }
609 if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
610 for _, l := range ctxt.Library {
611 s := ldr.CreateSymForUpdate("go.link.pkghashbytes."+l.Pkg, 0)
612 s.SetType(sym.SRODATA)
613 s.SetSize(int64(len(l.Fingerprint)))
614 s.SetData(l.Fingerprint[:])
615 str := ldr.CreateSymForUpdate("go.link.pkghash."+l.Pkg, 0)
616 str.SetType(sym.SRODATA)
617 str.AddAddr(ctxt.Arch, s.Sym())
618 str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
619 }
620 }
621
622 textsectionmapSym, nsections := textsectionmap(ctxt)
623
624
625
626
627
628 moduledata := ldr.MakeSymbolUpdater(ctxt.Moduledata)
629
630 moduledata.AddAddr(ctxt.Arch, pcln.pcheader)
631
632 moduledata.AddAddr(ctxt.Arch, pcln.funcnametab)
633 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab)))
634 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab)))
635
636 moduledata.AddAddr(ctxt.Arch, pcln.cutab)
637 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab)))
638 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab)))
639
640 moduledata.AddAddr(ctxt.Arch, pcln.filetab)
641 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
642 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
643
644 moduledata.AddAddr(ctxt.Arch, pcln.pctab)
645 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
646 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
647
648 moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
649 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
650 moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
651
652 moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
653 moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1))
654 moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1))
655
656 moduledata.AddAddr(ctxt.Arch, pcln.findfunctab)
657
658 moduledata.AddAddr(ctxt.Arch, pcln.firstFunc)
659 moduledata.AddAddrPlus(ctxt.Arch, pcln.lastFunc, ldr.SymSize(pcln.lastFunc))
660
661 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.text", 0))
662 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etext", 0))
663 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrdata", 0))
664 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrdata", 0))
665 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.data", 0))
666 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.edata", 0))
667 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.bss", 0))
668 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ebss", 0))
669 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrbss", 0))
670 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrbss", 0))
671 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.end", 0))
672 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
673 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
674 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
675 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
676 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.rodata", 0))
677 moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go.func.*", 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
694
695 addRef("go.buildid")
696 }
697
698
699 moduledata.AddAddr(ctxt.Arch, textsectionmapSym)
700 moduledata.AddUint(ctxt.Arch, uint64(nsections))
701 moduledata.AddUint(ctxt.Arch, uint64(nsections))
702
703
704 typelinkSym := ldr.Lookup("runtime.typelink", 0)
705 ntypelinks := uint64(ldr.SymSize(typelinkSym)) / 4
706 moduledata.AddAddr(ctxt.Arch, typelinkSym)
707 moduledata.AddUint(ctxt.Arch, ntypelinks)
708 moduledata.AddUint(ctxt.Arch, ntypelinks)
709
710 itablinkSym := ldr.Lookup("runtime.itablink", 0)
711 nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize)
712 moduledata.AddAddr(ctxt.Arch, itablinkSym)
713 moduledata.AddUint(ctxt.Arch, nitablinks)
714 moduledata.AddUint(ctxt.Arch, nitablinks)
715
716 if ptab := ldr.Lookup("go.plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
717 ldr.SetAttrLocal(ptab, true)
718 if ldr.SymType(ptab) != sym.SRODATA {
719 panic(fmt.Sprintf("go.plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
720 }
721 nentries := uint64(len(ldr.Data(ptab)) / 8)
722 moduledata.AddAddr(ctxt.Arch, ptab)
723 moduledata.AddUint(ctxt.Arch, nentries)
724 moduledata.AddUint(ctxt.Arch, nentries)
725 } else {
726 moduledata.AddUint(ctxt.Arch, 0)
727 moduledata.AddUint(ctxt.Arch, 0)
728 moduledata.AddUint(ctxt.Arch, 0)
729 }
730 if ctxt.BuildMode == BuildModePlugin {
731 addgostring(ctxt, ldr, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
732
733 pkghashes := ldr.CreateSymForUpdate("go.link.pkghashes", 0)
734 pkghashes.SetLocal(true)
735 pkghashes.SetType(sym.SRODATA)
736
737 for i, l := range ctxt.Library {
738
739 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
740
741 addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
742
743 hash := ldr.Lookup("go.link.pkghash."+l.Pkg, 0)
744 pkghashes.AddAddr(ctxt.Arch, hash)
745 }
746 moduledata.AddAddr(ctxt.Arch, pkghashes.Sym())
747 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
748 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
749 } else {
750 moduledata.AddUint(ctxt.Arch, 0)
751 moduledata.AddUint(ctxt.Arch, 0)
752 moduledata.AddUint(ctxt.Arch, 0)
753 moduledata.AddUint(ctxt.Arch, 0)
754 moduledata.AddUint(ctxt.Arch, 0)
755 }
756 if len(ctxt.Shlibs) > 0 {
757 thismodulename := filepath.Base(*flagOutfile)
758 switch ctxt.BuildMode {
759 case BuildModeExe, BuildModePIE:
760
761
762 thismodulename = "the executable"
763 }
764 addgostring(ctxt, ldr, moduledata, "go.link.thismodulename", thismodulename)
765
766 modulehashes := ldr.CreateSymForUpdate("go.link.abihashes", 0)
767 modulehashes.SetLocal(true)
768 modulehashes.SetType(sym.SRODATA)
769
770 for i, shlib := range ctxt.Shlibs {
771
772 modulename := filepath.Base(shlib.Path)
773 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
774
775
776 addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
777
778
779 abihash := ldr.LookupOrCreateSym("go.link.abihash."+modulename, 0)
780 ldr.SetAttrReachable(abihash, true)
781 modulehashes.AddAddr(ctxt.Arch, abihash)
782 }
783
784 moduledata.AddAddr(ctxt.Arch, modulehashes.Sym())
785 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
786 moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
787 } else {
788 moduledata.AddUint(ctxt.Arch, 0)
789 moduledata.AddUint(ctxt.Arch, 0)
790 moduledata.AddUint(ctxt.Arch, 0)
791 moduledata.AddUint(ctxt.Arch, 0)
792 moduledata.AddUint(ctxt.Arch, 0)
793 }
794
795 hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
796 if hasmain {
797 moduledata.AddUint8(1)
798 } else {
799 moduledata.AddUint8(0)
800 }
801
802
803
804
805
806 moduledatatype := ldr.Lookup("type.runtime.moduledata", 0)
807 moduledata.SetSize(decodetypeSize(ctxt.Arch, ldr.Data(moduledatatype)))
808 moduledata.Grow(moduledata.Size())
809
810 lastmoduledatap := ldr.CreateSymForUpdate("runtime.lastmoduledatap", 0)
811 if lastmoduledatap.Type() != sym.SDYNIMPORT {
812 lastmoduledatap.SetType(sym.SNOPTRDATA)
813 lastmoduledatap.SetSize(0)
814 lastmoduledatap.SetData(nil)
815 lastmoduledatap.AddAddr(ctxt.Arch, moduledata.Sym())
816 }
817 return symGroupType
818 }
819
820
821 var CarrierSymByType [sym.SXREF]struct {
822 Sym loader.Sym
823 Size int64
824 }
825
826 func setCarrierSym(typ sym.SymKind, s loader.Sym) {
827 if CarrierSymByType[typ].Sym != 0 {
828 panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
829 }
830 CarrierSymByType[typ].Sym = s
831 }
832
833 func setCarrierSize(typ sym.SymKind, sz int64) {
834 if CarrierSymByType[typ].Size != 0 {
835 panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
836 }
837 CarrierSymByType[typ].Size = sz
838 }
839
840 func isStaticTmp(name string) bool {
841 return strings.Contains(name, "."+obj.StaticNamePref)
842 }
843
844
845 func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string {
846
847
848
849
850
851
852
853
854
855
856 if !buildcfg.Experiment.RegabiWrappers {
857 return name
858 }
859
860 if !ldr.IsExternal(x) && ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) != sym.SymVerABIInternal {
861 if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2) == sym.STEXT {
862 name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x))
863 }
864 }
865
866
867
868
869
870
871 if ctxt.IsShared() {
872 if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type.") {
873 name = fmt.Sprintf("%s.abiinternal", name)
874 }
875 }
876
877 return name
878 }
879
View as plain text