1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ld
15
16 import (
17 "cmd/internal/dwarf"
18 "cmd/internal/obj"
19 "cmd/internal/objabi"
20 "cmd/internal/src"
21 "cmd/internal/sys"
22 "cmd/link/internal/loader"
23 "cmd/link/internal/sym"
24 "cmp"
25 "fmt"
26 "internal/abi"
27 "internal/buildcfg"
28 "log"
29 "path"
30 "runtime"
31 "slices"
32 "strings"
33 "sync"
34 )
35
36
37
38
39
40
41
42 type dwctxt struct {
43 linkctxt *Link
44 ldr *loader.Loader
45 arch *sys.Arch
46
47
48
49 tmap map[string]loader.Sym
50
51
52
53
54
55
56 rtmap map[loader.Sym]loader.Sym
57
58
59
60 tdmap map[loader.Sym]loader.Sym
61
62
63 typeRuntimeEface loader.Sym
64 typeRuntimeIface loader.Sym
65 uintptrInfoSym loader.Sym
66
67
68
69 dwmu *sync.Mutex
70 }
71
72
73
74
75 type dwSym loader.Sym
76
77 func (c dwctxt) PtrSize() int {
78 return c.arch.PtrSize
79 }
80
81 func (c dwctxt) Size(s dwarf.Sym) int64 {
82 return int64(len(c.ldr.Data(loader.Sym(s.(dwSym)))))
83 }
84
85 func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
86 ds := loader.Sym(s.(dwSym))
87 dsu := c.ldr.MakeSymbolUpdater(ds)
88 dsu.AddUintXX(c.arch, uint64(i), size)
89 }
90
91 func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
92 ds := loader.Sym(s.(dwSym))
93 dsu := c.ldr.MakeSymbolUpdater(ds)
94 dsu.AddBytes(b)
95 }
96
97 func (c dwctxt) AddString(s dwarf.Sym, v string) {
98 ds := loader.Sym(s.(dwSym))
99 dsu := c.ldr.MakeSymbolUpdater(ds)
100 dsu.Addstring(v)
101 }
102
103 func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
104 ds := loader.Sym(s.(dwSym))
105 dsu := c.ldr.MakeSymbolUpdater(ds)
106 if value != 0 {
107 value -= dsu.Value()
108 }
109 tgtds := loader.Sym(data.(dwSym))
110 dsu.AddAddrPlus(c.arch, tgtds, value)
111 }
112
113 func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
114 ds := loader.Sym(s.(dwSym))
115 dsu := c.ldr.MakeSymbolUpdater(ds)
116 if value != 0 {
117 value -= dsu.Value()
118 }
119 tgtds := loader.Sym(data.(dwSym))
120 dsu.AddCURelativeAddrPlus(c.arch, tgtds, value)
121 }
122
123 func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
124 ds := loader.Sym(s.(dwSym))
125 dsu := c.ldr.MakeSymbolUpdater(ds)
126 tds := loader.Sym(t.(dwSym))
127 switch size {
128 default:
129 c.linkctxt.Errorf(ds, "invalid size %d in adddwarfref\n", size)
130 case c.arch.PtrSize, 4:
131 }
132 dsu.AddSymRef(c.arch, tds, ofs, objabi.R_ADDROFF, size)
133 }
134
135 func (c dwctxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
136 size := 4
137 if isDwarf64(c.linkctxt) {
138 size = 8
139 }
140 ds := loader.Sym(s.(dwSym))
141 dsu := c.ldr.MakeSymbolUpdater(ds)
142 tds := loader.Sym(t.(dwSym))
143 switch size {
144 default:
145 c.linkctxt.Errorf(ds, "invalid size %d in adddwarfref\n", size)
146 case c.arch.PtrSize, 4:
147 }
148 dsu.AddSymRef(c.arch, tds, ofs, objabi.R_DWARFSECREF, size)
149 }
150
151 func (c dwctxt) AddIndirectTextRef(s dwarf.Sym, t interface{}) {
152 ds := loader.Sym(s.(dwSym))
153 dsu := c.ldr.MakeSymbolUpdater(ds)
154 tds := loader.Sym(t.(dwSym))
155 dsu.AddSymRef(c.arch, tds, 0, objabi.R_DWTXTADDR_U4, 4)
156 }
157
158 func (c dwctxt) Logf(format string, args ...interface{}) {
159 c.linkctxt.Logf(format, args...)
160 }
161
162
163
164 func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
165 panic("should be used only in the compiler")
166 }
167
168 func (c dwctxt) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
169 panic("should be used only in the compiler")
170 }
171
172 func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
173 panic("should be used only in the compiler")
174 }
175
176 func isDwarf64(ctxt *Link) bool {
177 return ctxt.HeadType == objabi.Haix
178 }
179
180
181
182
183 const (
184 GdbScriptPythonFileId = 1
185 GdbScriptSchemeFileId = 3
186 GdbScriptPythonTextId = 4
187 GdbScriptSchemeTextId = 6
188 )
189
190 var gdbscript string
191
192
193
194
195
196
197
198
199
200
201
202 type dwarfSecInfo struct {
203 syms []loader.Sym
204 }
205
206
207 func (dsi *dwarfSecInfo) secSym() loader.Sym {
208 if len(dsi.syms) == 0 {
209 return 0
210 }
211 return dsi.syms[0]
212 }
213
214
215 func (dsi *dwarfSecInfo) subSyms() []loader.Sym {
216 if len(dsi.syms) == 0 {
217 return []loader.Sym{}
218 }
219 return dsi.syms[1:]
220 }
221
222
223
224 var dwarfp []dwarfSecInfo
225
226 func (d *dwctxt) writeabbrev() dwarfSecInfo {
227 abrvs := d.ldr.CreateSymForUpdate(".debug_abbrev", 0)
228 abrvs.SetType(sym.SDWARFSECT)
229 abrvs.AddBytes(dwarf.GetAbbrev())
230 return dwarfSecInfo{syms: []loader.Sym{abrvs.Sym()}}
231 }
232
233 var dwtypes dwarf.DWDie
234
235
236
237
238
239
240
241
242 func newattr(die *dwarf.DWDie, attr uint16, cls int, value int64, data interface{}) {
243 a := new(dwarf.DWAttr)
244 a.Link = die.Attr
245 die.Attr = a
246 a.Atr = attr
247 a.Cls = uint8(cls)
248 a.Value = value
249 a.Data = data
250 }
251
252
253
254
255 func getattr(die *dwarf.DWDie, attr uint16) *dwarf.DWAttr {
256 if die.Attr.Atr == attr {
257 return die.Attr
258 }
259
260 a := die.Attr
261 b := a.Link
262 for b != nil {
263 if b.Atr == attr {
264 a.Link = b.Link
265 b.Link = die.Attr
266 die.Attr = b
267 return b
268 }
269
270 a = b
271 b = b.Link
272 }
273
274 return nil
275 }
276
277
278
279
280
281
282 func (d *dwctxt) newdie(parent *dwarf.DWDie, abbrev int, name string) *dwarf.DWDie {
283 die := new(dwarf.DWDie)
284 die.Abbrev = abbrev
285 die.Link = parent.Child
286 parent.Child = die
287
288 newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name)
289
290
291 if name == "" {
292 panic("nameless DWARF DIE")
293 }
294
295 var st sym.SymKind
296 switch abbrev {
297 case dwarf.DW_ABRV_FUNCTYPEPARAM, dwarf.DW_ABRV_FUNCTYPEOUTPARAM, dwarf.DW_ABRV_DOTDOTDOT, dwarf.DW_ABRV_STRUCTFIELD, dwarf.DW_ABRV_ARRAYRANGE:
298
299
300 return die
301 case dwarf.DW_ABRV_COMPUNIT, dwarf.DW_ABRV_COMPUNIT_TEXTLESS:
302
303 name = fmt.Sprintf(".pkg.%s.%d", name, len(d.linkctxt.compUnits))
304 st = sym.SDWARFCUINFO
305 case dwarf.DW_ABRV_VARIABLE:
306 st = sym.SDWARFVAR
307 default:
308
309
310 st = sym.SDWARFTYPE
311 }
312 ds := d.ldr.LookupOrCreateSym(dwarf.InfoPrefix+name, 0)
313 dsu := d.ldr.MakeSymbolUpdater(ds)
314 dsu.SetType(st)
315 d.ldr.SetAttrNotInSymbolTable(ds, true)
316 d.ldr.SetAttrReachable(ds, true)
317 die.Sym = dwSym(ds)
318 if abbrev >= dwarf.DW_ABRV_NULLTYPE && abbrev <= dwarf.DW_ABRV_TYPEDECL {
319 d.tmap[name] = ds
320 }
321
322 return die
323 }
324
325 func walktypedef(die *dwarf.DWDie) *dwarf.DWDie {
326 if die == nil {
327 return nil
328 }
329
330 if die.Abbrev == dwarf.DW_ABRV_TYPEDECL {
331 for attr := die.Attr; attr != nil; attr = attr.Link {
332 if attr.Atr == dwarf.DW_AT_type && attr.Cls == dwarf.DW_CLS_REFERENCE && attr.Data != nil {
333 return attr.Data.(*dwarf.DWDie)
334 }
335 }
336 }
337
338 return die
339 }
340
341 func (d *dwctxt) walksymtypedef(symIdx loader.Sym) loader.Sym {
342
343
344
345
346
347
348 if ts, ok := d.rtmap[symIdx]; ok {
349 if def, ok := d.tdmap[ts]; ok {
350 return def
351 }
352 d.linkctxt.Errorf(ts, "internal error: no entry for sym %d in tdmap\n", ts)
353 return 0
354 }
355 d.linkctxt.Errorf(symIdx, "internal error: no entry for sym %d in rtmap\n", symIdx)
356 return 0
357 }
358
359
360
361 func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie {
362 var prev *dwarf.DWDie
363 for ; die != prev; prev, die = die, walktypedef(die) {
364 for a := die.Child; a != nil; a = a.Link {
365 if name == getattr(a, dwarf.DW_AT_name).Data {
366 return a
367 }
368 }
369 continue
370 }
371 return nil
372 }
373
374
375
376 func (d *dwctxt) find(name string) loader.Sym {
377 return d.tmap[name]
378 }
379
380 func (d *dwctxt) mustFind(name string) loader.Sym {
381 r := d.find(name)
382 if r == 0 {
383 Exitf("dwarf find: cannot find %s", name)
384 }
385 return r
386 }
387
388 func (d *dwctxt) adddwarfref(sb *loader.SymbolBuilder, t loader.Sym, size int) {
389 switch size {
390 default:
391 d.linkctxt.Errorf(sb.Sym(), "invalid size %d in adddwarfref\n", size)
392 case d.arch.PtrSize, 4:
393 }
394 sb.AddSymRef(d.arch, t, 0, objabi.R_DWARFSECREF, size)
395 }
396
397 func (d *dwctxt) newrefattr(die *dwarf.DWDie, attr uint16, ref loader.Sym) {
398 if ref == 0 {
399 return
400 }
401 newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, dwSym(ref))
402 }
403
404 func (d *dwctxt) dtolsym(s dwarf.Sym) loader.Sym {
405 if s == nil {
406 return 0
407 }
408 dws := loader.Sym(s.(dwSym))
409 return dws
410 }
411
412 func (d *dwctxt) putdie(syms []loader.Sym, die *dwarf.DWDie) []loader.Sym {
413 s := d.dtolsym(die.Sym)
414 if s == 0 {
415 s = syms[len(syms)-1]
416 } else {
417 syms = append(syms, s)
418 }
419 sDwsym := dwSym(s)
420 dwarf.Uleb128put(d, sDwsym, int64(die.Abbrev))
421 dwarf.PutAttrs(d, sDwsym, die.Abbrev, die.Attr)
422 if dwarf.HasChildren(die) {
423 for die := die.Child; die != nil; die = die.Link {
424 syms = d.putdie(syms, die)
425 }
426 dsu := d.ldr.MakeSymbolUpdater(syms[len(syms)-1])
427 dsu.AddUint8(0)
428 }
429 return syms
430 }
431
432 func reverselist(list **dwarf.DWDie) {
433 curr := *list
434 var prev *dwarf.DWDie
435 for curr != nil {
436 next := curr.Link
437 curr.Link = prev
438 prev = curr
439 curr = next
440 }
441
442 *list = prev
443 }
444
445 func reversetree(list **dwarf.DWDie) {
446 reverselist(list)
447 for die := *list; die != nil; die = die.Link {
448 if dwarf.HasChildren(die) {
449 reversetree(&die.Child)
450 }
451 }
452 }
453
454 func newmemberoffsetattr(die *dwarf.DWDie, offs int32) {
455 newattr(die, dwarf.DW_AT_data_member_location, dwarf.DW_CLS_CONSTANT, int64(offs), nil)
456 }
457
458 func (d *dwctxt) lookupOrDiag(n string) loader.Sym {
459 symIdx := d.ldr.Lookup(n, 0)
460 if symIdx == 0 {
461 Exitf("dwarf: missing type: %s", n)
462 }
463 if len(d.ldr.Data(symIdx)) == 0 {
464 Exitf("dwarf: missing type (no data): %s", n)
465 }
466
467 return symIdx
468 }
469
470 func (d *dwctxt) dotypedef(parent *dwarf.DWDie, name string, def *dwarf.DWDie) *dwarf.DWDie {
471
472 if strings.HasPrefix(name, "map[") {
473 return nil
474 }
475 if strings.HasPrefix(name, "struct {") {
476 return nil
477 }
478
479
480 if strings.HasPrefix(name, "noalg.struct {") {
481 return nil
482 }
483 if strings.HasPrefix(name, "chan ") {
484 return nil
485 }
486 if name[0] == '[' || name[0] == '*' {
487 return nil
488 }
489 if def == nil {
490 Errorf("dwarf: bad def in dotypedef")
491 }
492
493
494
495
496 tds := d.ldr.CreateExtSym("", 0)
497 tdsu := d.ldr.MakeSymbolUpdater(tds)
498 tdsu.SetType(sym.SDWARFTYPE)
499 def.Sym = dwSym(tds)
500 d.ldr.SetAttrNotInSymbolTable(tds, true)
501 d.ldr.SetAttrReachable(tds, true)
502
503
504
505
506
507 die := d.newdie(parent, dwarf.DW_ABRV_TYPEDECL, name)
508
509 d.newrefattr(die, dwarf.DW_AT_type, tds)
510
511 return die
512 }
513
514
515 func (d *dwctxt) defgotype(gotype loader.Sym) loader.Sym {
516 if gotype == 0 {
517 return d.mustFind("<unspecified>")
518 }
519
520
521 if ds, ok := d.tdmap[gotype]; ok {
522 return ds
523 }
524
525 sn := d.ldr.SymName(gotype)
526 if !strings.HasPrefix(sn, "type:") {
527 d.linkctxt.Errorf(gotype, "dwarf: type name doesn't start with \"type:\"")
528 return d.mustFind("<unspecified>")
529 }
530 name := sn[len("type:"):]
531
532 sdie := d.find(name)
533 if sdie != 0 {
534 return sdie
535 }
536
537 gtdwSym := d.newtype(gotype)
538 d.tdmap[gotype] = loader.Sym(gtdwSym.Sym.(dwSym))
539 return loader.Sym(gtdwSym.Sym.(dwSym))
540 }
541
542 func (d *dwctxt) newtype(gotype loader.Sym) *dwarf.DWDie {
543 sn := d.ldr.SymName(gotype)
544 name := sn[len("type:"):]
545 tdata := d.ldr.Data(gotype)
546 if len(tdata) == 0 {
547 d.linkctxt.Errorf(gotype, "missing type")
548 }
549 kind := decodetypeKind(d.arch, tdata)
550 bytesize := decodetypeSize(d.arch, tdata)
551
552 var die, typedefdie *dwarf.DWDie
553 switch kind {
554 case abi.Bool:
555 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name)
556 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_boolean, 0)
557 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
558
559 case abi.Int,
560 abi.Int8,
561 abi.Int16,
562 abi.Int32,
563 abi.Int64:
564 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name)
565 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_signed, 0)
566 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
567
568 case abi.Uint,
569 abi.Uint8,
570 abi.Uint16,
571 abi.Uint32,
572 abi.Uint64,
573 abi.Uintptr:
574 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name)
575 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
576 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
577
578 case abi.Float32,
579 abi.Float64:
580 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name)
581 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_float, 0)
582 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
583
584 case abi.Complex64,
585 abi.Complex128:
586 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name)
587 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_complex_float, 0)
588 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
589
590 case abi.Array:
591 die = d.newdie(&dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name)
592 typedefdie = d.dotypedef(&dwtypes, name, die)
593 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
594 s := decodetypeArrayElem(d.linkctxt, d.arch, gotype)
595 d.newrefattr(die, dwarf.DW_AT_type, d.defgotype(s))
596 fld := d.newdie(die, dwarf.DW_ABRV_ARRAYRANGE, "range")
597
598
599 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetypeArrayLen(d.ldr, d.arch, gotype), 0)
600
601 d.newrefattr(fld, dwarf.DW_AT_type, d.uintptrInfoSym)
602
603 case abi.Chan:
604 die = d.newdie(&dwtypes, dwarf.DW_ABRV_CHANTYPE, name)
605 s := decodetypeChanElem(d.ldr, d.arch, gotype)
606 d.newrefattr(die, dwarf.DW_AT_go_elem, d.defgotype(s))
607
608
609 d.newrefattr(die, dwarf.DW_AT_type, s)
610
611 case abi.Func:
612 die = d.newdie(&dwtypes, dwarf.DW_ABRV_FUNCTYPE, name)
613 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
614 typedefdie = d.dotypedef(&dwtypes, name, die)
615 data := d.ldr.Data(gotype)
616
617 relocs := d.ldr.Relocs(gotype)
618 nfields := decodetypeFuncInCount(d.arch, data)
619 for i := 0; i < nfields; i++ {
620 s := decodetypeFuncInType(d.ldr, d.arch, gotype, &relocs, i)
621 sn := d.ldr.SymName(s)
622 fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, sn[5:])
623 d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
624 }
625
626 if decodetypeFuncDotdotdot(d.arch, data) {
627 d.newdie(die, dwarf.DW_ABRV_DOTDOTDOT, "...")
628 }
629 nfields = decodetypeFuncOutCount(d.arch, data)
630 for i := 0; i < nfields; i++ {
631 s := decodetypeFuncOutType(d.ldr, d.arch, gotype, &relocs, i)
632 sn := d.ldr.SymName(s)
633 fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEOUTPARAM, sn[5:])
634 newattr(fld, dwarf.DW_AT_variable_parameter, dwarf.DW_CLS_FLAG, 1, 0)
635 d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
636 }
637
638 case abi.Interface:
639 die = d.newdie(&dwtypes, dwarf.DW_ABRV_IFACETYPE, name)
640 typedefdie = d.dotypedef(&dwtypes, name, die)
641 data := d.ldr.Data(gotype)
642 nfields := int(decodetypeIfaceMethodCount(d.arch, data))
643 var s loader.Sym
644 if nfields == 0 {
645 s = d.typeRuntimeEface
646 } else {
647 s = d.typeRuntimeIface
648 }
649 d.newrefattr(die, dwarf.DW_AT_type, d.defgotype(s))
650
651 case abi.Map:
652 die = d.newdie(&dwtypes, dwarf.DW_ABRV_MAPTYPE, name)
653 s := decodetypeMapKey(d.ldr, d.arch, gotype)
654 d.newrefattr(die, dwarf.DW_AT_go_key, d.defgotype(s))
655 s = decodetypeMapValue(d.ldr, d.arch, gotype)
656 d.newrefattr(die, dwarf.DW_AT_go_elem, d.defgotype(s))
657
658
659 d.newrefattr(die, dwarf.DW_AT_type, gotype)
660
661 case abi.Pointer:
662 die = d.newdie(&dwtypes, dwarf.DW_ABRV_PTRTYPE, name)
663 typedefdie = d.dotypedef(&dwtypes, name, die)
664 s := decodetypePtrElem(d.ldr, d.arch, gotype)
665 d.newrefattr(die, dwarf.DW_AT_type, d.defgotype(s))
666
667 case abi.Slice:
668 die = d.newdie(&dwtypes, dwarf.DW_ABRV_SLICETYPE, name)
669 typedefdie = d.dotypedef(&dwtypes, name, die)
670 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
671 s := decodetypeArrayElem(d.linkctxt, d.arch, gotype)
672 elem := d.defgotype(s)
673 d.newrefattr(die, dwarf.DW_AT_go_elem, elem)
674
675 case abi.String:
676 die = d.newdie(&dwtypes, dwarf.DW_ABRV_STRINGTYPE, name)
677 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
678
679 case abi.Struct:
680 die = d.newdie(&dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name)
681 typedefdie = d.dotypedef(&dwtypes, name, die)
682 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
683 nfields := decodetypeStructFieldCount(d.ldr, d.arch, gotype)
684 for i := 0; i < nfields; i++ {
685 f := decodetypeStructFieldName(d.ldr, d.arch, gotype, i)
686 s := decodetypeStructFieldType(d.linkctxt, d.arch, gotype, i)
687 if f == "" {
688 sn := d.ldr.SymName(s)
689 f = sn[5:]
690 }
691 fld := d.newdie(die, dwarf.DW_ABRV_STRUCTFIELD, f)
692 d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
693 offset := decodetypeStructFieldOffset(d.ldr, d.arch, gotype, i)
694 newmemberoffsetattr(fld, int32(offset))
695 if decodetypeStructFieldEmbedded(d.ldr, d.arch, gotype, i) {
696 newattr(fld, dwarf.DW_AT_go_embedded_field, dwarf.DW_CLS_FLAG, 1, 0)
697 }
698 }
699
700 case abi.UnsafePointer:
701 die = d.newdie(&dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, name)
702
703 default:
704 d.linkctxt.Errorf(gotype, "dwarf: definition of unknown kind %d", kind)
705 die = d.newdie(&dwtypes, dwarf.DW_ABRV_TYPEDECL, name)
706 d.newrefattr(die, dwarf.DW_AT_type, d.mustFind("<unspecified>"))
707 }
708
709 newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0)
710
711 if d.ldr.AttrReachable(gotype) {
712 newattr(die, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, dwSym(gotype))
713 }
714
715
716 if _, ok := d.rtmap[gotype]; ok {
717 log.Fatalf("internal error: rtmap entry already installed\n")
718 }
719
720 ds := loader.Sym(die.Sym.(dwSym))
721 if typedefdie != nil {
722 ds = loader.Sym(typedefdie.Sym.(dwSym))
723 }
724 d.rtmap[ds] = gotype
725
726 if _, ok := prototypedies[sn]; ok {
727 prototypedies[sn] = die
728 }
729
730 if typedefdie != nil {
731 return typedefdie
732 }
733 return die
734 }
735
736 func (d *dwctxt) nameFromDIESym(dwtypeDIESym loader.Sym) string {
737 sn := d.ldr.SymName(dwtypeDIESym)
738 return sn[len(dwarf.InfoPrefix):]
739 }
740
741 func (d *dwctxt) defptrto(dwtype loader.Sym) loader.Sym {
742
743
744
745
746
747 ptrname := "*" + d.nameFromDIESym(dwtype)
748 if die := d.find(ptrname); die != 0 {
749 return die
750 }
751
752 pdie := d.newdie(&dwtypes, dwarf.DW_ABRV_PTRTYPE, ptrname)
753 d.newrefattr(pdie, dwarf.DW_AT_type, dwtype)
754
755
756
757
758 gts := d.ldr.Lookup("type:"+ptrname, 0)
759 if gts != 0 && d.ldr.AttrReachable(gts) {
760 newattr(pdie, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(abi.Pointer), 0)
761 newattr(pdie, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, dwSym(gts))
762 }
763
764 if gts != 0 {
765 ds := loader.Sym(pdie.Sym.(dwSym))
766 d.rtmap[ds] = gts
767 d.tdmap[gts] = ds
768 }
769
770 return d.dtolsym(pdie.Sym)
771 }
772
773
774
775
776 func (d *dwctxt) copychildrenexcept(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) {
777 for src = src.Child; src != nil; src = src.Link {
778 if src == except {
779 continue
780 }
781 c := d.newdie(dst, src.Abbrev, getattr(src, dwarf.DW_AT_name).Data.(string))
782 for a := src.Attr; a != nil; a = a.Link {
783 newattr(c, a.Atr, int(a.Cls), a.Value, a.Data)
784 }
785 d.copychildrenexcept(ctxt, c, src, nil)
786 }
787
788 reverselist(&dst.Child)
789 }
790
791 func (d *dwctxt) copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
792 d.copychildrenexcept(ctxt, dst, src, nil)
793 }
794
795
796
797 func (d *dwctxt) substitutetype(structdie *dwarf.DWDie, field string, dwtype loader.Sym) {
798 child := findchild(structdie, field)
799 if child == nil {
800 Exitf("dwarf substitutetype: %s does not have member %s",
801 getattr(structdie, dwarf.DW_AT_name).Data, field)
802 return
803 }
804
805 a := getattr(child, dwarf.DW_AT_type)
806 if a != nil {
807 a.Data = dwSym(dwtype)
808 } else {
809 d.newrefattr(child, dwarf.DW_AT_type, dwtype)
810 }
811 }
812
813 func (d *dwctxt) findprotodie(ctxt *Link, name string) *dwarf.DWDie {
814 die, ok := prototypedies[name]
815 if ok && die == nil {
816 d.defgotype(d.lookupOrDiag(name))
817 die = prototypedies[name]
818 }
819 if die == nil {
820 log.Fatalf("internal error: DIE generation failed for %s\n", name)
821 }
822 return die
823 }
824
825 func (d *dwctxt) synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
826 prototype := walktypedef(d.findprotodie(ctxt, "type:runtime.stringStructDWARF"))
827 if prototype == nil {
828 return
829 }
830
831 for ; die != nil; die = die.Link {
832 if die.Abbrev != dwarf.DW_ABRV_STRINGTYPE {
833 continue
834 }
835 d.copychildren(ctxt, die, prototype)
836 }
837 }
838
839 func (d *dwctxt) synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
840 prototype := walktypedef(d.findprotodie(ctxt, "type:runtime.slice"))
841 if prototype == nil {
842 return
843 }
844
845 for ; die != nil; die = die.Link {
846 if die.Abbrev != dwarf.DW_ABRV_SLICETYPE {
847 continue
848 }
849 d.copychildren(ctxt, die, prototype)
850 elem := loader.Sym(getattr(die, dwarf.DW_AT_go_elem).Data.(dwSym))
851 d.substitutetype(die, "array", d.defptrto(elem))
852 }
853 }
854
855 func mkinternaltypename(base string, arg1 string, arg2 string) string {
856 if arg2 == "" {
857 return fmt.Sprintf("%s<%s>", base, arg1)
858 }
859 return fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
860 }
861
862 func (d *dwctxt) mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) loader.Sym {
863 name := mkinternaltypename(typename, keyname, valname)
864 symname := dwarf.InfoPrefix + name
865 s := d.ldr.Lookup(symname, 0)
866 if s != 0 && d.ldr.SymType(s) == sym.SDWARFTYPE {
867 return s
868 }
869 die := d.newdie(&dwtypes, abbrev, name)
870 f(die)
871 return d.dtolsym(die.Sym)
872 }
873
874 func (d *dwctxt) synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
875 if buildcfg.Experiment.SwissMap {
876 d.synthesizemaptypesSwiss(ctxt, die)
877 } else {
878 d.synthesizemaptypesOld(ctxt, die)
879 }
880 }
881
882 func (d *dwctxt) synthesizemaptypesSwiss(ctxt *Link, die *dwarf.DWDie) {
883 mapType := walktypedef(d.findprotodie(ctxt, "type:internal/runtime/maps.Map"))
884 tableType := walktypedef(d.findprotodie(ctxt, "type:internal/runtime/maps.table"))
885 groupsReferenceType := walktypedef(d.findprotodie(ctxt, "type:internal/runtime/maps.groupsReference"))
886
887 for ; die != nil; die = die.Link {
888 if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
889 continue
890 }
891 gotype := loader.Sym(getattr(die, dwarf.DW_AT_type).Data.(dwSym))
892
893 keyType := decodetypeMapKey(d.ldr, d.arch, gotype)
894 valType := decodetypeMapValue(d.ldr, d.arch, gotype)
895 groupType := decodetypeMapSwissGroup(d.ldr, d.arch, gotype)
896
897 keyType = d.walksymtypedef(d.defgotype(keyType))
898 valType = d.walksymtypedef(d.defgotype(valType))
899 groupType = d.walksymtypedef(d.defgotype(groupType))
900
901 keyName := d.nameFromDIESym(keyType)
902 valName := d.nameFromDIESym(valType)
903
904
905 dwGroupsReference := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "groupReference", keyName, valName, func(dwh *dwarf.DWDie) {
906 d.copychildren(ctxt, dwh, groupsReferenceType)
907
908
909
910
911
912 d.substitutetype(dwh, "data", d.defptrto(groupType))
913 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(groupsReferenceType, dwarf.DW_AT_byte_size).Value, nil)
914 newattr(dwh, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(abi.Struct), 0)
915 })
916
917
918 dwTable := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "table", keyName, valName, func(dwh *dwarf.DWDie) {
919 d.copychildren(ctxt, dwh, tableType)
920 d.substitutetype(dwh, "groups", dwGroupsReference)
921 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(tableType, dwarf.DW_AT_byte_size).Value, nil)
922 newattr(dwh, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(abi.Struct), 0)
923 })
924
925
926 dwMap := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "map", keyName, valName, func(dwh *dwarf.DWDie) {
927 d.copychildren(ctxt, dwh, mapType)
928
929
930
931
932
933
934 d.substitutetype(dwh, "dirPtr", d.defptrto(d.defptrto(dwTable)))
935 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(mapType, dwarf.DW_AT_byte_size).Value, nil)
936 newattr(dwh, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(abi.Struct), 0)
937 })
938
939
940 d.newrefattr(die, dwarf.DW_AT_type, d.defptrto(dwMap))
941 }
942 }
943
944 func (d *dwctxt) synthesizemaptypesOld(ctxt *Link, die *dwarf.DWDie) {
945 hash := walktypedef(d.findprotodie(ctxt, "type:runtime.hmap"))
946 bucket := walktypedef(d.findprotodie(ctxt, "type:runtime.bmap"))
947
948 if hash == nil {
949 return
950 }
951
952 for ; die != nil; die = die.Link {
953 if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
954 continue
955 }
956 gotype := loader.Sym(getattr(die, dwarf.DW_AT_type).Data.(dwSym))
957 keytype := decodetypeMapKey(d.ldr, d.arch, gotype)
958 valtype := decodetypeMapValue(d.ldr, d.arch, gotype)
959 keydata := d.ldr.Data(keytype)
960 valdata := d.ldr.Data(valtype)
961 keysize, valsize := decodetypeSize(d.arch, keydata), decodetypeSize(d.arch, valdata)
962 keytype, valtype = d.walksymtypedef(d.defgotype(keytype)), d.walksymtypedef(d.defgotype(valtype))
963
964
965 indirectKey, indirectVal := false, false
966 if keysize > abi.OldMapMaxKeyBytes {
967 keysize = int64(d.arch.PtrSize)
968 indirectKey = true
969 }
970 if valsize > abi.OldMapMaxElemBytes {
971 valsize = int64(d.arch.PtrSize)
972 indirectVal = true
973 }
974
975
976 keyname := d.nameFromDIESym(keytype)
977 dwhks := d.mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *dwarf.DWDie) {
978 newattr(dwhk, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, abi.OldMapBucketCount*keysize, 0)
979 t := keytype
980 if indirectKey {
981 t = d.defptrto(keytype)
982 }
983 d.newrefattr(dwhk, dwarf.DW_AT_type, t)
984 fld := d.newdie(dwhk, dwarf.DW_ABRV_ARRAYRANGE, "size")
985 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, abi.OldMapBucketCount, 0)
986 d.newrefattr(fld, dwarf.DW_AT_type, d.uintptrInfoSym)
987 })
988
989
990 valname := d.nameFromDIESym(valtype)
991 dwhvs := d.mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *dwarf.DWDie) {
992 newattr(dwhv, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, abi.OldMapBucketCount*valsize, 0)
993 t := valtype
994 if indirectVal {
995 t = d.defptrto(valtype)
996 }
997 d.newrefattr(dwhv, dwarf.DW_AT_type, t)
998 fld := d.newdie(dwhv, dwarf.DW_ABRV_ARRAYRANGE, "size")
999 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, abi.OldMapBucketCount, 0)
1000 d.newrefattr(fld, dwarf.DW_AT_type, d.uintptrInfoSym)
1001 })
1002
1003
1004 dwhbs := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
1005
1006
1007 d.copychildrenexcept(ctxt, dwhb, bucket, findchild(bucket, "data"))
1008
1009 fld := d.newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys")
1010 d.newrefattr(fld, dwarf.DW_AT_type, dwhks)
1011 newmemberoffsetattr(fld, abi.OldMapBucketCount)
1012 fld = d.newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values")
1013 d.newrefattr(fld, dwarf.DW_AT_type, dwhvs)
1014 newmemberoffsetattr(fld, abi.OldMapBucketCount+abi.OldMapBucketCount*int32(keysize))
1015 fld = d.newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow")
1016 d.newrefattr(fld, dwarf.DW_AT_type, d.defptrto(d.dtolsym(dwhb.Sym)))
1017 newmemberoffsetattr(fld, abi.OldMapBucketCount+abi.OldMapBucketCount*(int32(keysize)+int32(valsize)))
1018 if d.arch.RegSize > d.arch.PtrSize {
1019 fld = d.newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad")
1020 d.newrefattr(fld, dwarf.DW_AT_type, d.uintptrInfoSym)
1021 newmemberoffsetattr(fld, abi.OldMapBucketCount+abi.OldMapBucketCount*(int32(keysize)+int32(valsize))+int32(d.arch.PtrSize))
1022 }
1023
1024 newattr(dwhb, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, abi.OldMapBucketCount+abi.OldMapBucketCount*keysize+abi.OldMapBucketCount*valsize+int64(d.arch.RegSize), 0)
1025 })
1026
1027
1028 dwhs := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
1029 d.copychildren(ctxt, dwh, hash)
1030 d.substitutetype(dwh, "buckets", d.defptrto(dwhbs))
1031 d.substitutetype(dwh, "oldbuckets", d.defptrto(dwhbs))
1032 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hash, dwarf.DW_AT_byte_size).Value, nil)
1033 })
1034
1035
1036 d.newrefattr(die, dwarf.DW_AT_type, d.defptrto(dwhs))
1037 }
1038 }
1039
1040 func (d *dwctxt) synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
1041 sudog := walktypedef(d.findprotodie(ctxt, "type:runtime.sudog"))
1042 waitq := walktypedef(d.findprotodie(ctxt, "type:runtime.waitq"))
1043 hchan := walktypedef(d.findprotodie(ctxt, "type:runtime.hchan"))
1044 if sudog == nil || waitq == nil || hchan == nil {
1045 return
1046 }
1047
1048 sudogsize := int(getattr(sudog, dwarf.DW_AT_byte_size).Value)
1049
1050 for ; die != nil; die = die.Link {
1051 if die.Abbrev != dwarf.DW_ABRV_CHANTYPE {
1052 continue
1053 }
1054 elemgotype := loader.Sym(getattr(die, dwarf.DW_AT_type).Data.(dwSym))
1055 tname := d.ldr.SymName(elemgotype)
1056 elemname := tname[5:]
1057 elemtype := d.walksymtypedef(d.defgotype(d.lookupOrDiag(tname)))
1058
1059
1060 dwss := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
1061 d.copychildren(ctxt, dws, sudog)
1062 d.substitutetype(dws, "elem", d.defptrto(elemtype))
1063 newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil)
1064 })
1065
1066
1067 dwws := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
1068
1069 d.copychildren(ctxt, dww, waitq)
1070 d.substitutetype(dww, "first", d.defptrto(dwss))
1071 d.substitutetype(dww, "last", d.defptrto(dwss))
1072 newattr(dww, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(waitq, dwarf.DW_AT_byte_size).Value, nil)
1073 })
1074
1075
1076 dwhs := d.mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
1077 d.copychildren(ctxt, dwh, hchan)
1078 d.substitutetype(dwh, "recvq", dwws)
1079 d.substitutetype(dwh, "sendq", dwws)
1080 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hchan, dwarf.DW_AT_byte_size).Value, nil)
1081 })
1082
1083 d.newrefattr(die, dwarf.DW_AT_type, d.defptrto(dwhs))
1084 }
1085 }
1086
1087
1088
1089 func (d *dwctxt) createUnitLength(su *loader.SymbolBuilder, v uint64) {
1090 if isDwarf64(d.linkctxt) {
1091 su.AddUint32(d.arch, 0xFFFFFFFF)
1092 }
1093 d.addDwarfAddrField(su, v)
1094 }
1095
1096
1097 func (d *dwctxt) addDwarfAddrField(sb *loader.SymbolBuilder, v uint64) {
1098 if isDwarf64(d.linkctxt) {
1099 sb.AddUint(d.arch, v)
1100 } else {
1101 sb.AddUint32(d.arch, uint32(v))
1102 }
1103 }
1104
1105
1106 func (d *dwctxt) addDwarfAddrRef(sb *loader.SymbolBuilder, t loader.Sym) {
1107 if isDwarf64(d.linkctxt) {
1108 d.adddwarfref(sb, t, 8)
1109 } else {
1110 d.adddwarfref(sb, t, 4)
1111 }
1112 }
1113
1114
1115 func (d *dwctxt) calcCompUnitRanges() {
1116 var prevUnit *sym.CompilationUnit
1117 for _, s := range d.linkctxt.Textp {
1118 sym := loader.Sym(s)
1119
1120 fi := d.ldr.FuncInfo(sym)
1121 if !fi.Valid() {
1122 continue
1123 }
1124
1125
1126
1127 unit := d.ldr.SymUnit(sym)
1128 if unit == nil {
1129 continue
1130 }
1131
1132
1133
1134
1135
1136
1137
1138
1139 sval := d.ldr.SymValue(sym)
1140 u0val := d.ldr.SymValue(loader.Sym(unit.Textp[0]))
1141 if prevUnit != unit {
1142 unit.PCs = append(unit.PCs, dwarf.Range{Start: sval - u0val})
1143 prevUnit = unit
1144 }
1145 unit.PCs[len(unit.PCs)-1].End = sval - u0val + int64(len(d.ldr.Data(sym)))
1146 }
1147 }
1148
1149 func movetomodule(ctxt *Link, parent *dwarf.DWDie) {
1150 die := ctxt.runtimeCU.DWInfo.Child
1151 if die == nil {
1152 ctxt.runtimeCU.DWInfo.Child = parent.Child
1153 return
1154 }
1155 for die.Link != nil {
1156 die = die.Link
1157 }
1158 die.Link = parent.Child
1159 }
1160
1161
1165 const (
1166 LINE_BASE = -4
1167 LINE_RANGE = 10
1168 PC_RANGE = (255 - OPCODE_BASE) / LINE_RANGE
1169 OPCODE_BASE = 11
1170 )
1171
1172
1175
1176 func getCompilationDir() string {
1177
1178
1179
1180
1181
1182
1183 return "."
1184 }
1185
1186 func (d *dwctxt) importInfoSymbol(dsym loader.Sym) {
1187 d.ldr.SetAttrReachable(dsym, true)
1188 d.ldr.SetAttrNotInSymbolTable(dsym, true)
1189 dst := d.ldr.SymType(dsym)
1190 if dst != sym.SDWARFCONST && dst != sym.SDWARFABSFCN {
1191 log.Fatalf("error: DWARF info sym %d/%s with incorrect type %s", dsym, d.ldr.SymName(dsym), d.ldr.SymType(dsym).String())
1192 }
1193 relocs := d.ldr.Relocs(dsym)
1194 for i := 0; i < relocs.Count(); i++ {
1195 r := relocs.At(i)
1196 if r.Type() != objabi.R_DWARFSECREF {
1197 continue
1198 }
1199 rsym := r.Sym()
1200
1201
1202 if _, ok := d.rtmap[rsym]; ok {
1203
1204 continue
1205 }
1206
1207
1208 sn := d.ldr.SymName(rsym)
1209 tn := sn[len(dwarf.InfoPrefix):]
1210 ts := d.ldr.Lookup("type:"+tn, 0)
1211 d.defgotype(ts)
1212 }
1213 }
1214
1215 func expandFile(fname string) string {
1216 fname = strings.TrimPrefix(fname, src.FileSymPrefix)
1217 return expandGoroot(fname)
1218 }
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 func (d *dwctxt) writeDirFileTables(unit *sym.CompilationUnit, lsu *loader.SymbolBuilder) {
1268 type fileDir struct {
1269 base string
1270 dir int
1271 }
1272 dirNums := make(map[string]int)
1273 dirs := []string{"."}
1274 dirNums["."] = 0
1275 files := []fileDir{}
1276 if buildcfg.Experiment.Dwarf5 {
1277
1278
1279
1280
1281
1282
1283
1284 files = append(files, fileDir{base: "?", dir: 0})
1285 }
1286
1287
1288
1289 for i, name := range unit.FileTable {
1290 name := expandFile(name)
1291 if len(name) == 0 {
1292
1293
1294 name = fmt.Sprintf("<missing>_%d", i)
1295 }
1296
1297
1298
1299 file := path.Base(name)
1300 dir := path.Dir(name)
1301 dirIdx, ok := dirNums[dir]
1302 if !ok && dir != "." {
1303 dirIdx = len(dirNums)
1304 dirNums[dir] = dirIdx
1305 dirs = append(dirs, dir)
1306 }
1307 files = append(files, fileDir{base: file, dir: dirIdx})
1308
1309
1310
1311
1312 if i := strings.Index(name, "runtime/proc.go"); i >= 0 && unit.Lib.Pkg == "runtime" {
1313 d.dwmu.Lock()
1314 if gdbscript == "" {
1315 k := strings.Index(name, "runtime/proc.go")
1316 gdbscript = name[:k] + "runtime/runtime-gdb.py"
1317 }
1318 d.dwmu.Unlock()
1319 }
1320 }
1321
1322 lsDwsym := dwSym(lsu.Sym())
1323 if buildcfg.Experiment.Dwarf5 {
1324
1325
1326
1327
1328
1329
1330 lsu.AddUint8(1)
1331
1332 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_LNCT_path)
1333 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_FORM_string)
1334
1335 dwarf.Uleb128put(d, lsDwsym, int64(len(dirs)))
1336 for k := 0; k < len(dirs); k++ {
1337 d.AddString(lsDwsym, dirs[k])
1338 }
1339
1340
1341
1342
1343
1344 lsu.AddUint8(2)
1345
1346 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_LNCT_path)
1347 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_FORM_string)
1348 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_LNCT_directory_index)
1349 dwarf.Uleb128put(d, lsDwsym, dwarf.DW_FORM_udata)
1350
1351 dwarf.Uleb128put(d, lsDwsym, int64(len(files)))
1352 for k := 0; k < len(files); k++ {
1353 d.AddString(lsDwsym, files[k].base)
1354 dwarf.Uleb128put(d, lsDwsym, int64(files[k].dir))
1355 }
1356 } else {
1357
1358
1359
1360
1361 for k := 1; k < len(dirs); k++ {
1362 d.AddString(lsDwsym, dirs[k])
1363 }
1364 lsu.AddUint8(0)
1365
1366
1367
1368
1369 for k := 0; k < len(files); k++ {
1370 d.AddString(lsDwsym, files[k].base)
1371 dwarf.Uleb128put(d, lsDwsym, int64(files[k].dir))
1372 lsu.AddUint8(0)
1373 lsu.AddUint8(0)
1374 }
1375 lsu.AddUint8(0)
1376 }
1377 }
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387 func (d *dwctxt) writelines(unit *sym.CompilationUnit, lineProlog loader.Sym) []loader.Sym {
1388 is_stmt := uint8(1)
1389
1390 unitstart := int64(-1)
1391 headerstart := int64(-1)
1392 headerend := int64(-1)
1393
1394 syms := make([]loader.Sym, 0, len(unit.Textp)+2)
1395 syms = append(syms, lineProlog)
1396 lsu := d.ldr.MakeSymbolUpdater(lineProlog)
1397 lsDwsym := dwSym(lineProlog)
1398 newattr(unit.DWInfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, lsDwsym)
1399
1400
1401
1402 unitLengthOffset := lsu.Size()
1403 d.createUnitLength(lsu, 0)
1404 unitstart = lsu.Size()
1405 if buildcfg.Experiment.Dwarf5 {
1406 lsu.AddUint16(d.arch, 5)
1407
1408
1409 lsu.AddUint8(uint8(d.arch.PtrSize))
1410 lsu.AddUint8(0)
1411 } else {
1412 lsu.AddUint16(d.arch, 2)
1413 }
1414 headerLengthOffset := lsu.Size()
1415 d.addDwarfAddrField(lsu, 0)
1416 headerstart = lsu.Size()
1417
1418 lsu.AddUint8(1)
1419 if buildcfg.Experiment.Dwarf5 {
1420 lsu.AddUint8(1)
1421 }
1422 lsu.AddUint8(is_stmt)
1423 lsu.AddUint8(LINE_BASE & 0xFF)
1424 lsu.AddUint8(LINE_RANGE)
1425 lsu.AddUint8(OPCODE_BASE)
1426 lsu.AddUint8(0)
1427 lsu.AddUint8(1)
1428 lsu.AddUint8(1)
1429 lsu.AddUint8(1)
1430 lsu.AddUint8(1)
1431 lsu.AddUint8(0)
1432 lsu.AddUint8(0)
1433 lsu.AddUint8(0)
1434 lsu.AddUint8(1)
1435 lsu.AddUint8(0)
1436
1437
1438 d.writeDirFileTables(unit, lsu)
1439
1440
1441 headerend = lsu.Size()
1442 unitlen := lsu.Size() - unitstart
1443
1444
1445 for _, s := range unit.Textp {
1446 fnSym := loader.Sym(s)
1447 _, _, _, lines := d.ldr.GetFuncDwarfAuxSyms(fnSym)
1448
1449
1450 if lines != 0 {
1451 syms = append(syms, lines)
1452 unitlen += int64(len(d.ldr.Data(lines)))
1453 }
1454 }
1455
1456 if d.linkctxt.HeadType == objabi.Haix {
1457 addDwsectCUSize(".debug_line", unit.Lib.Pkg, uint64(unitlen))
1458 }
1459
1460 if isDwarf64(d.linkctxt) {
1461 lsu.SetUint(d.arch, unitLengthOffset+4, uint64(unitlen))
1462 lsu.SetUint(d.arch, headerLengthOffset, uint64(headerend-headerstart))
1463 } else {
1464 lsu.SetUint32(d.arch, unitLengthOffset, uint32(unitlen))
1465 lsu.SetUint32(d.arch, headerLengthOffset, uint32(headerend-headerstart))
1466 }
1467
1468 return syms
1469 }
1470
1471
1472
1473
1474 func (d *dwctxt) writepcranges(unit *sym.CompilationUnit, base loader.Sym, pcs []dwarf.Range, rangeProlog loader.Sym, debugaddrsym loader.Sym) []loader.Sym {
1475
1476 syms := make([]loader.Sym, 0, len(unit.RangeSyms)+1)
1477 syms = append(syms, rangeProlog)
1478 rsu := d.ldr.MakeSymbolUpdater(rangeProlog)
1479 rDwSym := dwSym(rangeProlog)
1480
1481
1482 newattr(unit.DWInfo, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, rsu.Size(), rDwSym)
1483 newattr(unit.DWInfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, 0, dwSym(base))
1484 if buildcfg.Experiment.Dwarf5 && debugaddrsym != 0 {
1485 debugaddr := d.ldr.MakeSymbolUpdater(debugaddrsym)
1486
1487
1488
1489 dwarf.PutRngListRanges(d, rDwSym, dwSym(base), pcs)
1490 drelocs := d.ldr.Relocs(rangeProlog)
1491 for ri := 0; ri < drelocs.Count(); ri++ {
1492 r := drelocs.At(ri)
1493 if !r.Type().IsDwTxtAddr() {
1494 continue
1495 }
1496 cusym := d.dtolsym(unit.DWInfo.Sym)
1497 d.assignDebugAddrSlot(unit, cusym, r, debugaddr)
1498 }
1499 } else {
1500 dwarf.PutBasedRanges(d, rDwSym, pcs)
1501 }
1502
1503
1504 rsize := uint64(rsu.Size())
1505 for _, ls := range unit.RangeSyms {
1506 s := loader.Sym(ls)
1507 syms = append(syms, s)
1508 rsize += uint64(d.ldr.SymSize(s))
1509 }
1510
1511 if d.linkctxt.HeadType == objabi.Haix {
1512 addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, rsize)
1513 }
1514
1515 return syms
1516 }
1517
1518
1521 const (
1522 dataAlignmentFactor = -4
1523 )
1524
1525
1526 func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
1527 b = append(b, dwarf.DW_CFA_def_cfa_offset_sf)
1528 b = dwarf.AppendSleb128(b, cfa/dataAlignmentFactor)
1529
1530 switch {
1531 case deltapc < 0x40:
1532 b = append(b, uint8(dwarf.DW_CFA_advance_loc+deltapc))
1533 case deltapc < 0x100:
1534 b = append(b, dwarf.DW_CFA_advance_loc1)
1535 b = append(b, uint8(deltapc))
1536 case deltapc < 0x10000:
1537 b = append(b, dwarf.DW_CFA_advance_loc2, 0, 0)
1538 arch.ByteOrder.PutUint16(b[len(b)-2:], uint16(deltapc))
1539 default:
1540 b = append(b, dwarf.DW_CFA_advance_loc4, 0, 0, 0, 0)
1541 arch.ByteOrder.PutUint32(b[len(b)-4:], uint32(deltapc))
1542 }
1543 return b
1544 }
1545
1546 func (d *dwctxt) writeframes(fs loader.Sym) dwarfSecInfo {
1547 fsd := dwSym(fs)
1548 fsu := d.ldr.MakeSymbolUpdater(fs)
1549 fsu.SetType(sym.SDWARFSECT)
1550 isdw64 := isDwarf64(d.linkctxt)
1551 haslr := d.linkctxt.Arch.HasLR
1552
1553
1554 lengthFieldSize := int64(4)
1555 if isdw64 {
1556 lengthFieldSize += 8
1557 }
1558
1559
1560 cieReserve := uint32(16)
1561 if haslr {
1562 cieReserve = 32
1563 }
1564 if isdw64 {
1565 cieReserve += 4
1566 }
1567 d.createUnitLength(fsu, uint64(cieReserve))
1568 d.addDwarfAddrField(fsu, ^uint64(0))
1569 fsu.AddUint8(3)
1570 fsu.AddUint8(0)
1571 dwarf.Uleb128put(d, fsd, 1)
1572 dwarf.Sleb128put(d, fsd, dataAlignmentFactor)
1573 dwarf.Uleb128put(d, fsd, int64(thearch.Dwarfreglr))
1574
1575 fsu.AddUint8(dwarf.DW_CFA_def_cfa)
1576 dwarf.Uleb128put(d, fsd, int64(thearch.Dwarfregsp))
1577 if haslr {
1578 dwarf.Uleb128put(d, fsd, int64(0))
1579
1580 fsu.AddUint8(dwarf.DW_CFA_same_value)
1581 dwarf.Uleb128put(d, fsd, int64(thearch.Dwarfreglr))
1582
1583 fsu.AddUint8(dwarf.DW_CFA_val_offset)
1584 dwarf.Uleb128put(d, fsd, int64(thearch.Dwarfregsp))
1585 dwarf.Uleb128put(d, fsd, int64(0))
1586 } else {
1587 dwarf.Uleb128put(d, fsd, int64(d.arch.PtrSize))
1588
1589 fsu.AddUint8(dwarf.DW_CFA_offset_extended)
1590 dwarf.Uleb128put(d, fsd, int64(thearch.Dwarfreglr))
1591 dwarf.Uleb128put(d, fsd, int64(-d.arch.PtrSize)/dataAlignmentFactor)
1592 }
1593
1594 pad := int64(cieReserve) + lengthFieldSize - int64(len(d.ldr.Data(fs)))
1595
1596 if pad < 0 {
1597 Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
1598 }
1599
1600 internalExec := d.linkctxt.BuildMode == BuildModeExe && d.linkctxt.IsInternal()
1601 addAddrPlus := loader.GenAddAddrPlusFunc(internalExec)
1602
1603 fsu.AddBytes(zeros[:pad])
1604
1605 var deltaBuf []byte
1606 pcsp := obj.NewPCIter(uint32(d.arch.MinLC))
1607 for _, s := range d.linkctxt.Textp {
1608 fn := loader.Sym(s)
1609 fi := d.ldr.FuncInfo(fn)
1610 if !fi.Valid() {
1611 continue
1612 }
1613 fpcsp := d.ldr.Pcsp(s)
1614
1615
1616
1617 deltaBuf = deltaBuf[:0]
1618 if haslr && fi.TopFrame() {
1619
1620
1621
1622 deltaBuf = append(deltaBuf, dwarf.DW_CFA_undefined)
1623 deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
1624 }
1625
1626 for pcsp.Init(d.linkctxt.loader.Data(fpcsp)); !pcsp.Done; pcsp.Next() {
1627 nextpc := pcsp.NextPC
1628
1629
1630
1631 if int64(nextpc) == int64(len(d.ldr.Data(fn))) {
1632 nextpc--
1633 if nextpc < pcsp.PC {
1634 continue
1635 }
1636 }
1637
1638 spdelta := int64(pcsp.Value)
1639 if !haslr {
1640
1641 spdelta += int64(d.arch.PtrSize)
1642 }
1643
1644 if haslr && !fi.TopFrame() {
1645
1646
1647
1648 if pcsp.Value > 0 {
1649
1650
1651 deltaBuf = append(deltaBuf, dwarf.DW_CFA_offset_extended_sf)
1652 deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
1653 deltaBuf = dwarf.AppendSleb128(deltaBuf, -spdelta/dataAlignmentFactor)
1654 } else {
1655
1656
1657 deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value)
1658 deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
1659 }
1660 }
1661
1662 deltaBuf = appendPCDeltaCFA(d.arch, deltaBuf, int64(nextpc)-int64(pcsp.PC), spdelta)
1663 }
1664 pad := int(Rnd(int64(len(deltaBuf)), int64(d.arch.PtrSize))) - len(deltaBuf)
1665 deltaBuf = append(deltaBuf, zeros[:pad]...)
1666
1667
1668
1669
1670
1671
1672
1673 fdeLength := uint64(4 + 2*d.arch.PtrSize + len(deltaBuf))
1674 if isdw64 {
1675 fdeLength += 4
1676 }
1677 d.createUnitLength(fsu, fdeLength)
1678
1679 if d.linkctxt.LinkMode == LinkExternal {
1680 d.addDwarfAddrRef(fsu, fs)
1681 } else {
1682 d.addDwarfAddrField(fsu, 0)
1683 }
1684 addAddrPlus(fsu, d.arch, s, 0)
1685 fsu.AddUintXX(d.arch, uint64(len(d.ldr.Data(fn))), d.arch.PtrSize)
1686 fsu.AddBytes(deltaBuf)
1687
1688 if d.linkctxt.HeadType == objabi.Haix {
1689 addDwsectCUSize(".debug_frame", d.ldr.SymPkg(fn), fdeLength+uint64(lengthFieldSize))
1690 }
1691 }
1692
1693 return dwarfSecInfo{syms: []loader.Sym{fs}}
1694 }
1695
1696
1699
1700 func (d *dwctxt) writeUnitInfo(u *sym.CompilationUnit, abbrevsym loader.Sym, addrsym loader.Sym, infoEpilog loader.Sym) []loader.Sym {
1701 syms := []loader.Sym{}
1702 if len(u.Textp) == 0 && u.DWInfo.Child == nil && len(u.VarDIEs) == 0 {
1703 return syms
1704 }
1705
1706 compunit := u.DWInfo
1707 s := d.dtolsym(compunit.Sym)
1708 su := d.ldr.MakeSymbolUpdater(s)
1709
1710
1711
1712 d.createUnitLength(su, 0)
1713 dwver := 4
1714 if buildcfg.Experiment.Dwarf5 {
1715 dwver = 5
1716 }
1717 su.AddUint16(d.arch, uint16(dwver))
1718
1719 if buildcfg.Experiment.Dwarf5 {
1720
1721
1722
1723
1724 su.AddUint8(uint8(dwarf.DW_UT_compile))
1725 su.AddUint8(uint8(d.arch.PtrSize))
1726 d.addDwarfAddrRef(su, abbrevsym)
1727 } else {
1728
1729
1730
1731 d.addDwarfAddrRef(su, abbrevsym)
1732 su.AddUint8(uint8(d.arch.PtrSize))
1733 }
1734
1735 ds := dwSym(s)
1736 dwarf.Uleb128put(d, ds, int64(compunit.Abbrev))
1737 if buildcfg.Experiment.Dwarf5 {
1738
1739
1740 abattr := getattr(compunit, dwarf.DW_AT_addr_base)
1741 if abattr != nil {
1742 abattr.Data = dwSym(addrsym)
1743 }
1744 }
1745 dwarf.PutAttrs(d, ds, compunit.Abbrev, compunit.Attr)
1746
1747
1748 cu := make([]loader.Sym, 0, len(u.AbsFnDIEs)+len(u.FuncDIEs))
1749 cu = append(cu, s)
1750 cu = append(cu, u.AbsFnDIEs...)
1751 cu = append(cu, u.FuncDIEs...)
1752 if u.Consts != 0 {
1753 cu = append(cu, loader.Sym(u.Consts))
1754 }
1755 cu = append(cu, u.VarDIEs...)
1756 var cusize int64
1757 for _, child := range cu {
1758 cusize += int64(len(d.ldr.Data(child)))
1759 }
1760
1761 for die := compunit.Child; die != nil; die = die.Link {
1762 l := len(cu)
1763 lastSymSz := int64(len(d.ldr.Data(cu[l-1])))
1764 cu = d.putdie(cu, die)
1765 if lastSymSz != int64(len(d.ldr.Data(cu[l-1]))) {
1766
1767 cusize = cusize - lastSymSz + int64(len(d.ldr.Data(cu[l-1])))
1768 }
1769 for _, child := range cu[l:] {
1770 cusize += int64(len(d.ldr.Data(child)))
1771 }
1772 }
1773
1774 culu := d.ldr.MakeSymbolUpdater(infoEpilog)
1775 culu.AddUint8(0)
1776 cu = append(cu, infoEpilog)
1777 cusize++
1778
1779
1780 if d.linkctxt.HeadType == objabi.Haix {
1781 addDwsectCUSize(".debug_info", d.getPkgFromCUSym(s), uint64(cusize))
1782 }
1783 if isDwarf64(d.linkctxt) {
1784 cusize -= 12
1785 su.SetUint(d.arch, 4, uint64(cusize))
1786 } else {
1787 cusize -= 4
1788 su.SetUint32(d.arch, 0, uint32(cusize))
1789 }
1790 return append(syms, cu...)
1791 }
1792
1793 func (d *dwctxt) writegdbscript() dwarfSecInfo {
1794
1795 if d.linkctxt.HeadType == objabi.Haix {
1796 return dwarfSecInfo{}
1797 }
1798 if d.linkctxt.LinkMode == LinkExternal && d.linkctxt.HeadType == objabi.Hwindows && d.linkctxt.BuildMode == BuildModeCArchive {
1799
1800
1801
1802
1803
1804
1805 return dwarfSecInfo{}
1806 }
1807 if gdbscript == "" {
1808 return dwarfSecInfo{}
1809 }
1810
1811 gs := d.ldr.CreateSymForUpdate(".debug_gdb_scripts", 0)
1812 gs.SetType(sym.SDWARFSECT)
1813
1814 gs.AddUint8(GdbScriptPythonFileId)
1815 gs.Addstring(gdbscript)
1816 return dwarfSecInfo{syms: []loader.Sym{gs.Sym()}}
1817 }
1818
1819
1820
1821
1822 var prototypedies map[string]*dwarf.DWDie
1823
1824 func dwarfEnabled(ctxt *Link) bool {
1825 if *FlagW {
1826 return false
1827 }
1828 if ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hjs || ctxt.HeadType == objabi.Hwasip1 {
1829 return false
1830 }
1831
1832 if ctxt.LinkMode == LinkExternal {
1833 switch {
1834 case ctxt.IsELF:
1835 case ctxt.HeadType == objabi.Hdarwin:
1836 case ctxt.HeadType == objabi.Hwindows:
1837 case ctxt.HeadType == objabi.Haix:
1838 res, err := dwarf.IsDWARFEnabledOnAIXLd(ctxt.extld())
1839 if err != nil {
1840 Exitf("%v", err)
1841 }
1842 return res
1843 default:
1844 return false
1845 }
1846 }
1847
1848 return true
1849 }
1850
1851
1852
1853 func (d *dwctxt) mkBuiltinType(ctxt *Link, abrv int, tname string) *dwarf.DWDie {
1854
1855 die := d.newdie(&dwtypes, abrv, tname)
1856
1857
1858 gotype := d.lookupOrDiag("type:" + tname)
1859
1860
1861 ds := loader.Sym(die.Sym.(dwSym))
1862 d.rtmap[ds] = gotype
1863
1864
1865 d.tdmap[gotype] = ds
1866
1867 return die
1868 }
1869
1870
1871
1872
1873
1874 func (d *dwctxt) assignDebugAddrSlot(unit *sym.CompilationUnit, fnsym loader.Sym, r loader.Reloc, sb *loader.SymbolBuilder) {
1875 rsym := r.Sym()
1876 if unit.Addrs == nil {
1877 unit.Addrs = make(map[sym.LoaderSym]uint32)
1878 }
1879 if _, ok := unit.Addrs[sym.LoaderSym(rsym)]; ok {
1880
1881 } else {
1882 sl := len(unit.Addrs)
1883 rt := r.Type()
1884 lim, _ := rt.DwTxtAddrRelocParams()
1885 if sl > lim {
1886 log.Fatalf("internal error: %s relocation overflow on infosym for %s", rt.String(), d.ldr.SymName(fnsym))
1887 }
1888 unit.Addrs[sym.LoaderSym(rsym)] = uint32(sl)
1889 sb.AddAddrPlus(d.arch, rsym, 0)
1890 data := sb.Data()
1891 if d.arch.PtrSize == 4 {
1892 d.arch.ByteOrder.PutUint32(data[len(data)-4:], uint32(d.ldr.SymValue(rsym)))
1893 } else {
1894 d.arch.ByteOrder.PutUint64(data[len(data)-8:], uint64(d.ldr.SymValue(rsym)))
1895 }
1896 }
1897 }
1898
1899
1900
1901
1902 func (d *dwctxt) dwarfVisitFunction(fnSym loader.Sym, unit *sym.CompilationUnit) {
1903
1904
1905
1906 infosym, _, rangesym, _ := d.ldr.GetFuncDwarfAuxSyms(fnSym)
1907 if infosym == 0 {
1908 return
1909 }
1910 d.ldr.SetAttrNotInSymbolTable(infosym, true)
1911 d.ldr.SetAttrReachable(infosym, true)
1912 unit.FuncDIEs = append(unit.FuncDIEs, sym.LoaderSym(infosym))
1913 if rangesym != 0 {
1914 d.ldr.SetAttrNotInSymbolTable(rangesym, true)
1915 d.ldr.SetAttrReachable(rangesym, true)
1916 unit.RangeSyms = append(unit.RangeSyms, sym.LoaderSym(rangesym))
1917 }
1918
1919
1920
1921
1922
1923 drelocs := d.ldr.Relocs(infosym)
1924 for ri := 0; ri < drelocs.Count(); ri++ {
1925 r := drelocs.At(ri)
1926
1927 if r.Type() == objabi.R_USETYPE {
1928 d.defgotype(r.Sym())
1929 continue
1930 }
1931 if r.Type() != objabi.R_DWARFSECREF {
1932 continue
1933 }
1934
1935 rsym := r.Sym()
1936 rst := d.ldr.SymType(rsym)
1937
1938
1939 if rst == sym.SDWARFABSFCN {
1940 if !d.ldr.AttrOnList(rsym) {
1941
1942 d.ldr.SetAttrOnList(rsym, true)
1943 unit.AbsFnDIEs = append(unit.AbsFnDIEs, sym.LoaderSym(rsym))
1944 d.importInfoSymbol(rsym)
1945 }
1946 continue
1947 }
1948
1949
1950 if rst != sym.SDWARFTYPE && rst != sym.Sxxx {
1951 continue
1952 }
1953 if _, ok := d.rtmap[rsym]; ok {
1954
1955 continue
1956 }
1957
1958 rsn := d.ldr.SymName(rsym)
1959 tn := rsn[len(dwarf.InfoPrefix):]
1960 ts := d.ldr.Lookup("type:"+tn, 0)
1961 d.defgotype(ts)
1962 }
1963 }
1964
1965
1966
1967
1968
1969
1970
1971
1972 func dwarfGenerateDebugInfo(ctxt *Link) {
1973 if !dwarfEnabled(ctxt) {
1974 return
1975 }
1976
1977 d := &dwctxt{
1978 linkctxt: ctxt,
1979 ldr: ctxt.loader,
1980 arch: ctxt.Arch,
1981 tmap: make(map[string]loader.Sym),
1982 tdmap: make(map[loader.Sym]loader.Sym),
1983 rtmap: make(map[loader.Sym]loader.Sym),
1984 }
1985 d.typeRuntimeEface = d.lookupOrDiag("type:runtime.eface")
1986 d.typeRuntimeIface = d.lookupOrDiag("type:runtime.iface")
1987
1988 if ctxt.HeadType == objabi.Haix {
1989
1990 dwsectCUSize = make(map[string]uint64)
1991 }
1992
1993
1994 newattr(&dwtypes, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
1995
1996
1997 d.newdie(&dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>")
1998
1999
2000
2001 unsafeptrDie := d.mkBuiltinType(ctxt, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
2002 newattr(unsafeptrDie, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, dwSym(d.lookupOrDiag("type:unsafe.Pointer")))
2003 uintptrDie := d.mkBuiltinType(ctxt, dwarf.DW_ABRV_BASETYPE, "uintptr")
2004 newattr(uintptrDie, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
2005 newattr(uintptrDie, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(d.arch.PtrSize), 0)
2006 newattr(uintptrDie, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(abi.Uintptr), 0)
2007 newattr(uintptrDie, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, dwSym(d.lookupOrDiag("type:uintptr")))
2008
2009 d.uintptrInfoSym = d.mustFind("uintptr")
2010
2011
2012 prototypedies = map[string]*dwarf.DWDie{
2013 "type:runtime.stringStructDWARF": nil,
2014 "type:runtime.slice": nil,
2015 "type:runtime.sudog": nil,
2016 "type:runtime.waitq": nil,
2017 "type:runtime.hchan": nil,
2018 }
2019 if buildcfg.Experiment.SwissMap {
2020 prototypedies["type:internal/runtime/maps.Map"] = nil
2021 prototypedies["type:internal/runtime/maps.table"] = nil
2022 prototypedies["type:internal/runtime/maps.groupsReference"] = nil
2023 } else {
2024 prototypedies["type:runtime.hmap"] = nil
2025 prototypedies["type:runtime.bmap"] = nil
2026 }
2027
2028
2029 for _, typ := range []string{
2030 "type:internal/abi.Type",
2031 "type:internal/abi.ArrayType",
2032 "type:internal/abi.ChanType",
2033 "type:internal/abi.FuncType",
2034 "type:internal/abi.PtrType",
2035 "type:internal/abi.SliceType",
2036 "type:internal/abi.StructType",
2037 "type:internal/abi.InterfaceType",
2038 "type:internal/abi.ITab",
2039 "type:internal/abi.Imethod"} {
2040 d.defgotype(d.lookupOrDiag(typ))
2041 }
2042 if buildcfg.Experiment.SwissMap {
2043 d.defgotype(d.lookupOrDiag("type:internal/abi.SwissMapType"))
2044 } else {
2045 d.defgotype(d.lookupOrDiag("type:internal/abi.OldMapType"))
2046 }
2047
2048
2049 var dwroot dwarf.DWDie
2050 flagVariants := make(map[string]bool)
2051
2052 for _, lib := range ctxt.Library {
2053
2054 consts := d.ldr.Lookup(dwarf.ConstInfoPrefix+lib.Pkg, 0)
2055 for _, unit := range lib.Units {
2056
2057 if consts != 0 {
2058 unit.Consts = sym.LoaderSym(consts)
2059 d.importInfoSymbol(consts)
2060 consts = 0
2061 }
2062 ctxt.compUnits = append(ctxt.compUnits, unit)
2063
2064
2065 if unit.Lib.Pkg == "runtime" {
2066 ctxt.runtimeCU = unit
2067 }
2068
2069 cuabrv := dwarf.DW_ABRV_COMPUNIT
2070 if len(unit.Textp) == 0 {
2071 cuabrv = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
2072 }
2073 unit.DWInfo = d.newdie(&dwroot, cuabrv, unit.Lib.Pkg)
2074 newattr(unit.DWInfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(dwarf.DW_LANG_Go), 0)
2075
2076 compDir := getCompilationDir()
2077
2078
2079
2080 newattr(unit.DWInfo, dwarf.DW_AT_comp_dir, dwarf.DW_CLS_STRING, int64(len(compDir)), compDir)
2081
2082 var peData []byte
2083 if producerExtra := d.ldr.Lookup(dwarf.CUInfoPrefix+"producer."+unit.Lib.Pkg, 0); producerExtra != 0 {
2084 peData = d.ldr.Data(producerExtra)
2085 }
2086 producer := "Go cmd/compile " + buildcfg.Version
2087 if len(peData) > 0 {
2088
2089
2090
2091
2092
2093
2094 producer += "; " + string(peData)
2095 flagVariants[string(peData)] = true
2096 } else {
2097 flagVariants[""] = true
2098 }
2099
2100 newattr(unit.DWInfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer)
2101
2102 var pkgname string
2103 if pnSymIdx := d.ldr.Lookup(dwarf.CUInfoPrefix+"packagename."+unit.Lib.Pkg, 0); pnSymIdx != 0 {
2104 pnsData := d.ldr.Data(pnSymIdx)
2105 pkgname = string(pnsData)
2106 }
2107 newattr(unit.DWInfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname)
2108
2109 if buildcfg.Experiment.Dwarf5 && cuabrv == dwarf.DW_ABRV_COMPUNIT {
2110
2111
2112
2113
2114
2115
2116 newattr(unit.DWInfo, dwarf.DW_AT_addr_base, dwarf.DW_CLS_REFERENCE, 0, 0)
2117 }
2118
2119
2120
2121
2122
2123 for _, s := range unit.Textp {
2124 d.dwarfVisitFunction(loader.Sym(s), unit)
2125 }
2126 }
2127 }
2128
2129
2130
2131
2132 if checkStrictDups > 1 && len(flagVariants) > 1 {
2133 checkStrictDups = 1
2134 }
2135
2136
2137
2138
2139
2140
2141
2142
2143 for idx := loader.Sym(1); idx < loader.Sym(d.ldr.NDef()); idx++ {
2144 if !d.ldr.AttrReachable(idx) ||
2145 d.ldr.AttrNotInSymbolTable(idx) ||
2146 d.ldr.SymVersion(idx) >= sym.SymVerStatic {
2147 continue
2148 }
2149 t := d.ldr.SymType(idx)
2150 switch {
2151 case t.IsRODATA(), t.IsDATA(), t.IsNOPTRDATA(),
2152 t == sym.STYPE, t == sym.SBSS, t == sym.SNOPTRBSS, t == sym.STLSBSS:
2153
2154 default:
2155 continue
2156 }
2157
2158 gt := d.ldr.SymGoType(idx)
2159 if gt == 0 {
2160 if t == sym.SRODATA {
2161 if d.ldr.IsDict(idx) {
2162
2163 relocs := d.ldr.Relocs(idx)
2164 for i := 0; i < relocs.Count(); i++ {
2165 reloc := relocs.At(i)
2166 if reloc.Type() == objabi.R_USEIFACE {
2167 d.defgotype(reloc.Sym())
2168 }
2169 }
2170 }
2171 }
2172 continue
2173 }
2174
2175
2176 if d.ldr.IsFileLocal(idx) {
2177 continue
2178 }
2179
2180
2181
2182
2183
2184
2185 varDIE := d.ldr.GetVarDwarfAuxSym(idx)
2186 if varDIE != 0 {
2187 unit := d.ldr.SymUnit(idx)
2188 d.defgotype(gt)
2189 unit.VarDIEs = append(unit.VarDIEs, sym.LoaderSym(varDIE))
2190 }
2191 }
2192
2193 d.synthesizestringtypes(ctxt, dwtypes.Child)
2194 d.synthesizeslicetypes(ctxt, dwtypes.Child)
2195 d.synthesizemaptypes(ctxt, dwtypes.Child)
2196 d.synthesizechantypes(ctxt, dwtypes.Child)
2197 }
2198
2199
2200
2201
2202 func dwarfGenerateDebugSyms(ctxt *Link) {
2203 if !dwarfEnabled(ctxt) {
2204 return
2205 }
2206 d := &dwctxt{
2207 linkctxt: ctxt,
2208 ldr: ctxt.loader,
2209 arch: ctxt.Arch,
2210 dwmu: new(sync.Mutex),
2211 }
2212 d.dwarfGenerateDebugSyms()
2213 }
2214
2215
2216
2217 type dwUnitSyms struct {
2218
2219 lineProlog loader.Sym
2220 rangeProlog loader.Sym
2221 infoEpilog loader.Sym
2222
2223
2224 linesyms []loader.Sym
2225 infosyms []loader.Sym
2226 locsyms []loader.Sym
2227 rangessyms []loader.Sym
2228 addrsym loader.Sym
2229 }
2230
2231
2232
2233
2234
2235
2236
2237
2238 func (d *dwctxt) dwUnitPortion(u *sym.CompilationUnit, abbrevsym loader.Sym, us *dwUnitSyms) {
2239 if u.DWInfo.Abbrev != dwarf.DW_ABRV_COMPUNIT_TEXTLESS {
2240 us.linesyms = d.writelines(u, us.lineProlog)
2241 base := loader.Sym(u.Textp[0])
2242 if buildcfg.Experiment.Dwarf5 {
2243 d.writedebugaddr(u, us.addrsym)
2244 }
2245 us.rangessyms = d.writepcranges(u, base, u.PCs, us.rangeProlog, us.addrsym)
2246 us.locsyms = d.collectUnitLocs(u)
2247 }
2248 us.infosyms = d.writeUnitInfo(u, abbrevsym, us.addrsym, us.infoEpilog)
2249 }
2250
2251
2252
2253
2254
2255
2256 func (d *dwctxt) writedebugaddr(unit *sym.CompilationUnit, debugaddr loader.Sym) {
2257 dasu := d.ldr.MakeSymbolUpdater(debugaddr)
2258
2259 var dsyms []loader.Sym
2260 for _, s := range unit.Textp {
2261 fnSym := loader.Sym(s)
2262
2263
2264 infosym, locsym, rangessym, _ := d.ldr.GetFuncDwarfAuxSyms(fnSym)
2265
2266
2267
2268
2269 dsyms = dsyms[:0]
2270 dsyms = append(dsyms, infosym)
2271 if rangessym != 0 {
2272 dsyms = append(dsyms, rangessym)
2273 }
2274 if locsym != 0 {
2275 dsyms = append(dsyms, locsym)
2276 }
2277 for _, dsym := range dsyms {
2278 drelocs := d.ldr.Relocs(dsym)
2279 for ri := 0; ri < drelocs.Count(); ri++ {
2280 r := drelocs.At(ri)
2281 if !r.Type().IsDwTxtAddr() {
2282 continue
2283 }
2284 rsym := r.Sym()
2285 rst := d.ldr.SymType(rsym)
2286
2287 if !rst.IsText() {
2288
2289
2290
2291 log.Fatalf("internal error: R_DWTXTADDR_* relocation on dwinfosym for %s against non-function %s type:%s", d.ldr.SymName(fnSym), d.ldr.SymName(rsym), rst.String())
2292 }
2293 if runit := d.ldr.SymUnit(rsym); runit != unit {
2294 log.Fatalf("internal error: R_DWTXTADDR_* relocation target text sym unit mismatch (want %q got %q)", unit.Lib.Pkg, runit.Lib.Pkg)
2295 }
2296 d.assignDebugAddrSlot(unit, fnSym, r, dasu)
2297 }
2298 }
2299 }
2300 }
2301
2302 func (d *dwctxt) dwarfGenerateDebugSyms() {
2303 abbrevSec := d.writeabbrev()
2304 dwarfp = append(dwarfp, abbrevSec)
2305 d.calcCompUnitRanges()
2306 slices.SortFunc(d.linkctxt.compUnits, compilationUnitByStartPCCmp)
2307
2308
2309
2310
2311 for _, u := range d.linkctxt.compUnits {
2312 reversetree(&u.DWInfo.Child)
2313 }
2314 reversetree(&dwtypes.Child)
2315 movetomodule(d.linkctxt, &dwtypes)
2316
2317 mkSecSym := func(name string) loader.Sym {
2318 s := d.ldr.CreateSymForUpdate(name, 0)
2319 s.SetType(sym.SDWARFSECT)
2320 s.SetReachable(true)
2321 return s.Sym()
2322 }
2323
2324 mkAnonSym := func(kind sym.SymKind) loader.Sym {
2325 s := d.ldr.MakeSymbolUpdater(d.ldr.CreateExtSym("", 0))
2326 s.SetType(kind)
2327 s.SetReachable(true)
2328 return s.Sym()
2329 }
2330
2331
2332 frameSym := mkSecSym(".debug_frame")
2333 lineSym := mkSecSym(".debug_line")
2334 var rangesSym, locSym loader.Sym
2335 if buildcfg.Experiment.Dwarf5 {
2336 rangesSym = mkSecSym(".debug_rnglists")
2337 locSym = mkSecSym(".debug_loclists")
2338 } else {
2339 rangesSym = mkSecSym(".debug_ranges")
2340 locSym = mkSecSym(".debug_loc")
2341 }
2342 infoSym := mkSecSym(".debug_info")
2343 var addrSym loader.Sym
2344 if buildcfg.Experiment.Dwarf5 {
2345 addrSym = mkSecSym(".debug_addr")
2346 }
2347
2348
2349 lineSec := dwarfSecInfo{syms: []loader.Sym{lineSym}}
2350 frameSec := dwarfSecInfo{syms: []loader.Sym{frameSym}}
2351 infoSec := dwarfSecInfo{syms: []loader.Sym{infoSym}}
2352 var addrSec, rangesSec, locSec dwarfSecInfo
2353 if buildcfg.Experiment.Dwarf5 {
2354 addrHdr := d.writeDebugAddrHdr()
2355 addrSec.syms = []loader.Sym{addrSym, addrHdr}
2356 rnglistsHdr := d.writeDebugRngListsHdr()
2357 rangesSec.syms = []loader.Sym{rangesSym, rnglistsHdr}
2358 loclistsHdr := d.writeDebugLocListsHdr()
2359 locSec.syms = []loader.Sym{locSym, loclistsHdr}
2360 } else {
2361 rangesSec = dwarfSecInfo{syms: []loader.Sym{rangesSym}}
2362 locSec = dwarfSecInfo{syms: []loader.Sym{locSym}}
2363 }
2364
2365
2366
2367 ncu := len(d.linkctxt.compUnits)
2368 unitSyms := make([]dwUnitSyms, ncu)
2369 for i := 0; i < ncu; i++ {
2370 us := &unitSyms[i]
2371 us.lineProlog = mkAnonSym(sym.SDWARFLINES)
2372 us.rangeProlog = mkAnonSym(sym.SDWARFRANGE)
2373 us.infoEpilog = mkAnonSym(sym.SDWARFFCN)
2374 us.addrsym = mkAnonSym(sym.SDWARFADDR)
2375 }
2376
2377 var wg sync.WaitGroup
2378 sema := make(chan struct{}, runtime.GOMAXPROCS(0))
2379
2380
2381
2382 wg.Add(1)
2383 go func() {
2384 sema <- struct{}{}
2385 defer func() {
2386 <-sema
2387 wg.Done()
2388 }()
2389 frameSec = d.writeframes(frameSym)
2390 }()
2391
2392
2393
2394
2395 wg.Add(len(d.linkctxt.compUnits))
2396 for i := 0; i < ncu; i++ {
2397 go func(u *sym.CompilationUnit, us *dwUnitSyms) {
2398 sema <- struct{}{}
2399 defer func() {
2400 <-sema
2401 wg.Done()
2402 }()
2403 d.dwUnitPortion(u, abbrevSec.secSym(), us)
2404 }(d.linkctxt.compUnits[i], &unitSyms[i])
2405 }
2406 wg.Wait()
2407
2408 markReachable := func(syms []loader.Sym) []loader.Sym {
2409 for _, s := range syms {
2410 d.ldr.SetAttrNotInSymbolTable(s, true)
2411 d.ldr.SetAttrReachable(s, true)
2412 }
2413 return syms
2414 }
2415
2416 patchHdr := func(sec *dwarfSecInfo, len uint64) {
2417 hdrsym := sec.syms[1]
2418 len += uint64(d.ldr.SymSize(hdrsym))
2419 su := d.ldr.MakeSymbolUpdater(hdrsym)
2420 if isDwarf64(d.linkctxt) {
2421 len -= 12
2422 su.SetUint(d.arch, 4, uint64(len))
2423 } else {
2424 len -= 4
2425 su.SetUint32(d.arch, 0, uint32(len))
2426 }
2427 }
2428
2429 if buildcfg.Experiment.Dwarf5 {
2430
2431
2432 var rltot, addrtot, loctot uint64
2433 for i := 0; i < ncu; i++ {
2434 addrtot += uint64(d.ldr.SymSize(unitSyms[i].addrsym))
2435 rs := unitSyms[i].rangessyms
2436 for _, s := range rs {
2437 rltot += uint64(d.ldr.SymSize(s))
2438 }
2439 loc := unitSyms[i].locsyms
2440 for _, s := range loc {
2441 loctot += uint64(d.ldr.SymSize(s))
2442 }
2443 }
2444
2445 patchHdr(&addrSec, addrtot)
2446 patchHdr(&rangesSec, rltot)
2447 patchHdr(&locSec, loctot)
2448 }
2449
2450
2451 for i := 0; i < ncu; i++ {
2452 r := &unitSyms[i]
2453 lineSec.syms = append(lineSec.syms, markReachable(r.linesyms)...)
2454 infoSec.syms = append(infoSec.syms, markReachable(r.infosyms)...)
2455 locSec.syms = append(locSec.syms, markReachable(r.locsyms)...)
2456 rangesSec.syms = append(rangesSec.syms, markReachable(r.rangessyms)...)
2457 if buildcfg.Experiment.Dwarf5 && r.addrsym != 0 {
2458 addrSec.syms = append(addrSec.syms, r.addrsym)
2459 }
2460 }
2461 dwarfp = append(dwarfp, lineSec)
2462 dwarfp = append(dwarfp, frameSec)
2463 gdbScriptSec := d.writegdbscript()
2464 if gdbScriptSec.secSym() != 0 {
2465 dwarfp = append(dwarfp, gdbScriptSec)
2466 }
2467 dwarfp = append(dwarfp, infoSec)
2468 if len(locSec.syms) > 1 {
2469 dwarfp = append(dwarfp, locSec)
2470 }
2471 dwarfp = append(dwarfp, rangesSec)
2472 if buildcfg.Experiment.Dwarf5 {
2473 dwarfp = append(dwarfp, addrSec)
2474 }
2475
2476
2477
2478
2479
2480 seen := loader.MakeBitmap(d.ldr.NSym())
2481 for _, s := range infoSec.syms {
2482 if seen.Has(s) {
2483 log.Fatalf("dwarf symbol %s listed multiple times",
2484 d.ldr.SymName(s))
2485 }
2486 seen.Set(s)
2487 }
2488 }
2489
2490 func (d *dwctxt) collectUnitLocs(u *sym.CompilationUnit) []loader.Sym {
2491 syms := []loader.Sym{}
2492 for _, fn := range u.FuncDIEs {
2493 relocs := d.ldr.Relocs(loader.Sym(fn))
2494 for i := 0; i < relocs.Count(); i++ {
2495 reloc := relocs.At(i)
2496 if reloc.Type() != objabi.R_DWARFSECREF {
2497 continue
2498 }
2499 rsym := reloc.Sym()
2500 if d.ldr.SymType(rsym) == sym.SDWARFLOC {
2501 syms = append(syms, rsym)
2502
2503 break
2504 }
2505 }
2506 }
2507 return syms
2508 }
2509
2510
2511
2512 func dwarfaddshstrings(ctxt *Link, add func(string)) {
2513 if *FlagW {
2514 return
2515 }
2516
2517 secs := []string{"abbrev", "frame", "info", "loc", "line", "gdb_scripts"}
2518 if buildcfg.Experiment.Dwarf5 {
2519 secs = append(secs, "addr", "rnglists", "loclists")
2520 } else {
2521 secs = append(secs, "ranges", "loc")
2522 }
2523
2524 for _, sec := range secs {
2525 add(".debug_" + sec)
2526 if ctxt.IsExternal() {
2527 add(elfRelType + ".debug_" + sec)
2528 }
2529 }
2530 }
2531
2532 func dwarfaddelfsectionsyms(ctxt *Link) {
2533 if *FlagW {
2534 return
2535 }
2536 if ctxt.LinkMode != LinkExternal {
2537 return
2538 }
2539
2540 ldr := ctxt.loader
2541 for _, si := range dwarfp {
2542 s := si.secSym()
2543 sect := ldr.SymSect(si.secSym())
2544 putelfsectionsym(ctxt, ctxt.Out, s, sect.Elfsect.(*ElfShdr).shnum)
2545 }
2546 }
2547
2548
2549
2550
2551 func dwarfcompress(ctxt *Link) {
2552
2553 type compressedSect struct {
2554 index int
2555 compressed []byte
2556 syms []loader.Sym
2557 }
2558
2559 supported := ctxt.IsELF || ctxt.IsWindows() || ctxt.IsDarwin()
2560 if !ctxt.compressDWARF || !supported || ctxt.IsExternal() {
2561 return
2562 }
2563
2564 var compressedCount int
2565 resChannel := make(chan compressedSect)
2566 for i := range dwarfp {
2567 go func(resIndex int, syms []loader.Sym) {
2568 resChannel <- compressedSect{resIndex, compressSyms(ctxt, syms), syms}
2569 }(compressedCount, dwarfp[i].syms)
2570 compressedCount++
2571 }
2572 res := make([]compressedSect, compressedCount)
2573 for ; compressedCount > 0; compressedCount-- {
2574 r := <-resChannel
2575 res[r.index] = r
2576 }
2577
2578 ldr := ctxt.loader
2579 var newDwarfp []dwarfSecInfo
2580 Segdwarf.Sections = Segdwarf.Sections[:0]
2581 for _, z := range res {
2582 s := z.syms[0]
2583 if z.compressed == nil {
2584
2585 ds := dwarfSecInfo{syms: z.syms}
2586 newDwarfp = append(newDwarfp, ds)
2587 Segdwarf.Sections = append(Segdwarf.Sections, ldr.SymSect(s))
2588 } else {
2589 var compressedSegName string
2590 if ctxt.IsELF {
2591 compressedSegName = ldr.SymSect(s).Name
2592 } else {
2593 compressedSegName = ".zdebug_" + ldr.SymSect(s).Name[len(".debug_"):]
2594 }
2595 sect := addsection(ctxt.loader, ctxt.Arch, &Segdwarf, compressedSegName, 04)
2596 sect.Align = int32(ctxt.Arch.Alignment)
2597 sect.Length = uint64(len(z.compressed))
2598 sect.Compressed = true
2599 newSym := ldr.MakeSymbolBuilder(compressedSegName)
2600 ldr.SetAttrReachable(s, true)
2601 newSym.SetData(z.compressed)
2602 newSym.SetSize(int64(len(z.compressed)))
2603 ldr.SetSymSect(newSym.Sym(), sect)
2604 ds := dwarfSecInfo{syms: []loader.Sym{newSym.Sym()}}
2605 newDwarfp = append(newDwarfp, ds)
2606
2607
2608 for _, s := range z.syms {
2609 ldr.SetAttrReachable(s, false)
2610 ldr.FreeSym(s)
2611 }
2612 }
2613 }
2614 dwarfp = newDwarfp
2615
2616
2617
2618
2619 pos := Segdwarf.Vaddr
2620 var prevSect *sym.Section
2621 for _, si := range dwarfp {
2622 for _, s := range si.syms {
2623 ldr.SetSymValue(s, int64(pos))
2624 sect := ldr.SymSect(s)
2625 if sect != prevSect {
2626 sect.Vaddr = uint64(pos)
2627 prevSect = sect
2628 }
2629 if ldr.SubSym(s) != 0 {
2630 log.Fatalf("%s: unexpected sub-symbols", ldr.SymName(s))
2631 }
2632 pos += uint64(ldr.SymSize(s))
2633 if ctxt.IsWindows() {
2634 pos = uint64(Rnd(int64(pos), PEFILEALIGN))
2635 }
2636 }
2637 }
2638 Segdwarf.Length = pos - Segdwarf.Vaddr
2639 }
2640
2641 func compilationUnitByStartPCCmp(a, b *sym.CompilationUnit) int {
2642 switch {
2643 case len(a.Textp) == 0 && len(b.Textp) == 0:
2644 return strings.Compare(a.Lib.Pkg, b.Lib.Pkg)
2645 case len(a.Textp) != 0 && len(b.Textp) == 0:
2646 return -1
2647 case len(a.Textp) == 0 && len(b.Textp) != 0:
2648 return +1
2649 default:
2650 return cmp.Compare(a.PCs[0].Start, b.PCs[0].Start)
2651 }
2652 }
2653
2654
2655
2656
2657
2658 func (d *dwctxt) getPkgFromCUSym(s loader.Sym) string {
2659 return strings.TrimPrefix(d.ldr.SymName(s), dwarf.InfoPrefix+".pkg.")
2660 }
2661
2662
2663
2664
2665
2666
2667 var dwsectCUSizeMu sync.Mutex
2668 var dwsectCUSize map[string]uint64
2669
2670
2671 func getDwsectCUSize(sname string, pkgname string) uint64 {
2672 return dwsectCUSize[sname+"."+pkgname]
2673 }
2674
2675 func addDwsectCUSize(sname string, pkgname string, size uint64) {
2676 dwsectCUSizeMu.Lock()
2677 defer dwsectCUSizeMu.Unlock()
2678 dwsectCUSize[sname+"."+pkgname] += size
2679 }
2680
2681
2682
2683
2684
2685
2686 func (d *dwctxt) writeDebugMiscSecHdr(st sym.SymKind, addOffsetEntryCount bool) loader.Sym {
2687 su := d.ldr.MakeSymbolUpdater(d.ldr.CreateExtSym("", 0))
2688 su.SetType(st)
2689 su.SetReachable(true)
2690 d.createUnitLength(su, 0)
2691 su.AddUint16(d.arch, 5)
2692 su.AddUint8(uint8(d.arch.PtrSize))
2693 su.AddUint8(0)
2694 if addOffsetEntryCount {
2695 su.AddUint32(d.arch, 0)
2696 }
2697 return su.Sym()
2698 }
2699
2700 func (d *dwctxt) writeDebugRngListsHdr() loader.Sym {
2701 return d.writeDebugMiscSecHdr(sym.SDWARFRANGE, true)
2702 }
2703
2704 func (d *dwctxt) writeDebugLocListsHdr() loader.Sym {
2705 return d.writeDebugMiscSecHdr(sym.SDWARFLOC, true)
2706 }
2707
2708 func (d *dwctxt) writeDebugAddrHdr() loader.Sym {
2709 return d.writeDebugMiscSecHdr(sym.SDWARFADDR, false)
2710 }
2711
View as plain text