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