1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package dwarf generates DWARF debugging information.
6// DWARF generation is split between the compiler and the linker,
7// this package contains the shared code.
8package dwarf
9
10import (
11	"bytes"
12	"cmd/internal/src"
13	"errors"
14	"fmt"
15	"internal/buildcfg"
16	"os/exec"
17	"sort"
18	"strconv"
19	"strings"
20)
21
22// InfoPrefix is the prefix for all the symbols containing DWARF info entries.
23const InfoPrefix = "go:info."
24
25// ConstInfoPrefix is the prefix for all symbols containing DWARF info
26// entries that contain constants.
27const ConstInfoPrefix = "go:constinfo."
28
29// CUInfoPrefix is the prefix for symbols containing information to
30// populate the DWARF compilation unit info entries.
31const CUInfoPrefix = "go:cuinfo."
32
33// Used to form the symbol name assigned to the DWARF 'abstract subprogram"
34// info entry for a function
35const AbstractFuncSuffix = "$abstract"
36
37// Controls logging/debugging for selected aspects of DWARF subprogram
38// generation (functions, scopes).
39var logDwarf bool
40
41// Sym represents a symbol.
42type Sym interface {
43}
44
45// A Var represents a local variable or a function parameter.
46type Var struct {
47	Name          string
48	Tag           int // Either DW_TAG_variable or DW_TAG_formal_parameter
49	WithLoclist   bool
50	IsReturnValue bool
51	IsInlFormal   bool
52	DictIndex     uint16 // index of the dictionary entry describing the type of this variable
53	StackOffset   int32
54	// This package can't use the ssa package, so it can't mention ssa.FuncDebug,
55	// so indirect through a closure.
56	PutLocationList func(listSym, startPC Sym)
57	Scope           int32
58	Type            Sym
59	DeclFile        string
60	DeclLine        uint
61	DeclCol         uint
62	InlIndex        int32 // subtract 1 to form real index into InlTree
63	ChildIndex      int32 // child DIE index in abstract function
64	IsInAbstract    bool  // variable exists in abstract function
65	ClosureOffset   int64 // if non-zero this is the offset of this variable in the closure struct
66}
67
68// A Scope represents a lexical scope. All variables declared within a
69// scope will only be visible to instructions covered by the scope.
70// Lexical scopes are contiguous in source files but can end up being
71// compiled to discontiguous blocks of instructions in the executable.
72// The Ranges field lists all the blocks of instructions that belong
73// in this scope.
74type Scope struct {
75	Parent int32
76	Ranges []Range
77	Vars   []*Var
78}
79
80// A Range represents a half-open interval [Start, End).
81type Range struct {
82	Start, End int64
83}
84
85// This container is used by the PutFunc* variants below when
86// creating the DWARF subprogram DIE(s) for a function.
87type FnState struct {
88	Name          string
89	Info          Sym
90	Loc           Sym
91	Ranges        Sym
92	Absfn         Sym
93	StartPC       Sym
94	StartPos      src.Pos
95	Size          int64
96	External      bool
97	Scopes        []Scope
98	InlCalls      InlCalls
99	UseBASEntries bool
100
101	dictIndexToOffset []int64
102}
103
104func EnableLogging(doit bool) {
105	logDwarf = doit
106}
107
108// MergeRanges creates a new range list by merging the ranges from
109// its two arguments, then returns the new list.
110func MergeRanges(in1, in2 []Range) []Range {
111	out := make([]Range, 0, len(in1)+len(in2))
112	i, j := 0, 0
113	for {
114		var cur Range
115		if i < len(in2) && j < len(in1) {
116			if in2[i].Start < in1[j].Start {
117				cur = in2[i]
118				i++
119			} else {
120				cur = in1[j]
121				j++
122			}
123		} else if i < len(in2) {
124			cur = in2[i]
125			i++
126		} else if j < len(in1) {
127			cur = in1[j]
128			j++
129		} else {
130			break
131		}
132
133		if n := len(out); n > 0 && cur.Start <= out[n-1].End {
134			out[n-1].End = cur.End
135		} else {
136			out = append(out, cur)
137		}
138	}
139
140	return out
141}
142
143// UnifyRanges merges the ranges from 'c' into the list of ranges for 's'.
144func (s *Scope) UnifyRanges(c *Scope) {
145	s.Ranges = MergeRanges(s.Ranges, c.Ranges)
146}
147
148// AppendRange adds r to s, if r is non-empty.
149// If possible, it extends the last Range in s.Ranges; if not, it creates a new one.
150func (s *Scope) AppendRange(r Range) {
151	if r.End <= r.Start {
152		return
153	}
154	i := len(s.Ranges)
155	if i > 0 && s.Ranges[i-1].End == r.Start {
156		s.Ranges[i-1].End = r.End
157		return
158	}
159	s.Ranges = append(s.Ranges, r)
160}
161
162type InlCalls struct {
163	Calls []InlCall
164}
165
166type InlCall struct {
167	// index into ctx.InlTree describing the call inlined here
168	InlIndex int
169
170	// Position of the inlined call site.
171	CallPos src.Pos
172
173	// Dwarf abstract subroutine symbol (really *obj.LSym).
174	AbsFunSym Sym
175
176	// Indices of child inlines within Calls array above.
177	Children []int
178
179	// entries in this list are PAUTO's created by the inliner to
180	// capture the promoted formals and locals of the inlined callee.
181	InlVars []*Var
182
183	// PC ranges for this inlined call.
184	Ranges []Range
185
186	// Root call (not a child of some other call).
187	Root bool
188}
189
190// A Context specifies how to add data to a Sym.
191type Context interface {
192	PtrSize() int
193	Size(s Sym) int64
194	AddInt(s Sym, size int, i int64)
195	AddBytes(s Sym, b []byte)
196	AddAddress(s Sym, t interface{}, ofs int64)
197	AddCURelativeAddress(s Sym, t interface{}, ofs int64)
198	AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
199	AddDWARFAddrSectionOffset(s Sym, t interface{}, ofs int64)
200	CurrentOffset(s Sym) int64
201	RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
202	RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
203	AddString(s Sym, v string)
204	Logf(format string, args ...interface{})
205}
206
207// AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
208func AppendUleb128(b []byte, v uint64) []byte {
209	for {
210		c := uint8(v & 0x7f)
211		v >>= 7
212		if v != 0 {
213			c |= 0x80
214		}
215		b = append(b, c)
216		if c&0x80 == 0 {
217			break
218		}
219	}
220	return b
221}
222
223// AppendSleb128 appends v to b using DWARF's signed LEB128 encoding.
224func AppendSleb128(b []byte, v int64) []byte {
225	for {
226		c := uint8(v & 0x7f)
227		s := uint8(v & 0x40)
228		v >>= 7
229		if (v != -1 || s == 0) && (v != 0 || s != 0) {
230			c |= 0x80
231		}
232		b = append(b, c)
233		if c&0x80 == 0 {
234			break
235		}
236	}
237	return b
238}
239
240// sevenbits contains all unsigned seven bit numbers, indexed by their value.
241var sevenbits = [...]byte{
242	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
243	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
244	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
245	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
246	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
247	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
248	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
249	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
250}
251
252// sevenBitU returns the unsigned LEB128 encoding of v if v is seven bits and nil otherwise.
253// The contents of the returned slice must not be modified.
254func sevenBitU(v int64) []byte {
255	if uint64(v) < uint64(len(sevenbits)) {
256		return sevenbits[v : v+1]
257	}
258	return nil
259}
260
261// sevenBitS returns the signed LEB128 encoding of v if v is seven bits and nil otherwise.
262// The contents of the returned slice must not be modified.
263func sevenBitS(v int64) []byte {
264	if uint64(v) <= 63 {
265		return sevenbits[v : v+1]
266	}
267	if uint64(-v) <= 64 {
268		return sevenbits[128+v : 128+v+1]
269	}
270	return nil
271}
272
273// Uleb128put appends v to s using DWARF's unsigned LEB128 encoding.
274func Uleb128put(ctxt Context, s Sym, v int64) {
275	b := sevenBitU(v)
276	if b == nil {
277		var encbuf [20]byte
278		b = AppendUleb128(encbuf[:0], uint64(v))
279	}
280	ctxt.AddBytes(s, b)
281}
282
283// Sleb128put appends v to s using DWARF's signed LEB128 encoding.
284func Sleb128put(ctxt Context, s Sym, v int64) {
285	b := sevenBitS(v)
286	if b == nil {
287		var encbuf [20]byte
288		b = AppendSleb128(encbuf[:0], v)
289	}
290	ctxt.AddBytes(s, b)
291}
292
293/*
294 * Defining Abbrevs. This is hardcoded on a per-platform basis (that is,
295 * each platform will see a fixed abbrev table for all objects); the number
296 * of abbrev entries is fairly small (compared to C++ objects).  The DWARF
297 * spec places no restriction on the ordering of attributes in the
298 * Abbrevs and DIEs, and we will always write them out in the order
299 * of declaration in the abbrev.
300 */
301type dwAttrForm struct {
302	attr uint16
303	form uint8
304}
305
306// Go-specific type attributes.
307const (
308	DW_AT_go_kind = 0x2900
309	DW_AT_go_key  = 0x2901
310	DW_AT_go_elem = 0x2902
311	// Attribute for DW_TAG_member of a struct type.
312	// Nonzero value indicates the struct field is an embedded field.
313	DW_AT_go_embedded_field = 0x2903
314	DW_AT_go_runtime_type   = 0x2904
315
316	DW_AT_go_package_name   = 0x2905 // Attribute for DW_TAG_compile_unit
317	DW_AT_go_dict_index     = 0x2906 // Attribute for DW_TAG_typedef_type, index of the dictionary entry describing the real type of this type shape
318	DW_AT_go_closure_offset = 0x2907 // Attribute for DW_TAG_variable, offset in the closure struct where this captured variable resides
319
320	DW_AT_internal_location = 253 // params and locals; not emitted
321)
322
323// Index into the abbrevs table below.
324const (
325	DW_ABRV_NULL = iota
326	DW_ABRV_COMPUNIT
327	DW_ABRV_COMPUNIT_TEXTLESS
328	DW_ABRV_FUNCTION
329	DW_ABRV_WRAPPER
330	DW_ABRV_FUNCTION_ABSTRACT
331	DW_ABRV_FUNCTION_CONCRETE
332	DW_ABRV_WRAPPER_CONCRETE
333	DW_ABRV_INLINED_SUBROUTINE
334	DW_ABRV_INLINED_SUBROUTINE_RANGES
335	DW_ABRV_VARIABLE
336	DW_ABRV_INT_CONSTANT
337	DW_ABRV_LEXICAL_BLOCK_RANGES
338	DW_ABRV_LEXICAL_BLOCK_SIMPLE
339	DW_ABRV_STRUCTFIELD
340	DW_ABRV_FUNCTYPEPARAM
341	DW_ABRV_DOTDOTDOT
342	DW_ABRV_ARRAYRANGE
343	DW_ABRV_NULLTYPE
344	DW_ABRV_BASETYPE
345	DW_ABRV_ARRAYTYPE
346	DW_ABRV_CHANTYPE
347	DW_ABRV_FUNCTYPE
348	DW_ABRV_IFACETYPE
349	DW_ABRV_MAPTYPE
350	DW_ABRV_PTRTYPE
351	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
352	DW_ABRV_SLICETYPE
353	DW_ABRV_STRINGTYPE
354	DW_ABRV_STRUCTTYPE
355	DW_ABRV_TYPEDECL
356	DW_ABRV_DICT_INDEX
357	DW_ABRV_PUTVAR_START
358)
359
360type dwAbbrev struct {
361	tag      uint8
362	children uint8
363	attr     []dwAttrForm
364}
365
366var abbrevsFinalized bool
367
368// expandPseudoForm takes an input DW_FORM_xxx value and translates it
369// into a platform-appropriate concrete form. Existing concrete/real
370// DW_FORM values are left untouched. For the moment the only
371// pseudo-form is DW_FORM_udata_pseudo, which gets expanded to
372// DW_FORM_data4 on Darwin and DW_FORM_udata everywhere else. See
373// issue #31459 for more context.
374func expandPseudoForm(form uint8) uint8 {
375	// Is this a pseudo-form?
376	if form != DW_FORM_udata_pseudo {
377		return form
378	}
379	expandedForm := DW_FORM_udata
380	if buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" {
381		expandedForm = DW_FORM_data4
382	}
383	return uint8(expandedForm)
384}
385
386// Abbrevs returns the finalized abbrev array for the platform,
387// expanding any DW_FORM pseudo-ops to real values.
388func Abbrevs() []dwAbbrev {
389	if abbrevsFinalized {
390		return abbrevs
391	}
392	abbrevs = append(abbrevs, putvarAbbrevs...)
393	for i := 1; i < len(abbrevs); i++ {
394		for j := 0; j < len(abbrevs[i].attr); j++ {
395			abbrevs[i].attr[j].form = expandPseudoForm(abbrevs[i].attr[j].form)
396		}
397	}
398	abbrevsFinalized = true
399	return abbrevs
400}
401
402// abbrevs is a raw table of abbrev entries; it needs to be post-processed
403// by the Abbrevs() function above prior to being consumed, to expand
404// the 'pseudo-form' entries below to real DWARF form values.
405
406var abbrevs = []dwAbbrev{
407	/* The mandatory DW_ABRV_NULL entry. */
408	{0, 0, []dwAttrForm{}},
409
410	/* COMPUNIT */
411	{
412		DW_TAG_compile_unit,
413		DW_CHILDREN_yes,
414		[]dwAttrForm{
415			{DW_AT_name, DW_FORM_string},
416			{DW_AT_language, DW_FORM_data1},
417			{DW_AT_stmt_list, DW_FORM_sec_offset},
418			{DW_AT_low_pc, DW_FORM_addr},
419			{DW_AT_ranges, DW_FORM_sec_offset},
420			{DW_AT_comp_dir, DW_FORM_string},
421			{DW_AT_producer, DW_FORM_string},
422			{DW_AT_go_package_name, DW_FORM_string},
423		},
424	},
425
426	/* COMPUNIT_TEXTLESS */
427	{
428		DW_TAG_compile_unit,
429		DW_CHILDREN_yes,
430		[]dwAttrForm{
431			{DW_AT_name, DW_FORM_string},
432			{DW_AT_language, DW_FORM_data1},
433			{DW_AT_comp_dir, DW_FORM_string},
434			{DW_AT_producer, DW_FORM_string},
435			{DW_AT_go_package_name, DW_FORM_string},
436		},
437	},
438
439	/* FUNCTION */
440	{
441		DW_TAG_subprogram,
442		DW_CHILDREN_yes,
443		[]dwAttrForm{
444			{DW_AT_name, DW_FORM_string},
445			{DW_AT_low_pc, DW_FORM_addr},
446			{DW_AT_high_pc, DW_FORM_addr},
447			{DW_AT_frame_base, DW_FORM_block1},
448			{DW_AT_decl_file, DW_FORM_data4},
449			{DW_AT_decl_line, DW_FORM_udata},
450			{DW_AT_external, DW_FORM_flag},
451		},
452	},
453
454	/* WRAPPER */
455	{
456		DW_TAG_subprogram,
457		DW_CHILDREN_yes,
458		[]dwAttrForm{
459			{DW_AT_name, DW_FORM_string},
460			{DW_AT_low_pc, DW_FORM_addr},
461			{DW_AT_high_pc, DW_FORM_addr},
462			{DW_AT_frame_base, DW_FORM_block1},
463			{DW_AT_trampoline, DW_FORM_flag},
464		},
465	},
466
467	/* FUNCTION_ABSTRACT */
468	{
469		DW_TAG_subprogram,
470		DW_CHILDREN_yes,
471		[]dwAttrForm{
472			{DW_AT_name, DW_FORM_string},
473			{DW_AT_inline, DW_FORM_data1},
474			{DW_AT_decl_line, DW_FORM_udata},
475			{DW_AT_external, DW_FORM_flag},
476		},
477	},
478
479	/* FUNCTION_CONCRETE */
480	{
481		DW_TAG_subprogram,
482		DW_CHILDREN_yes,
483		[]dwAttrForm{
484			{DW_AT_abstract_origin, DW_FORM_ref_addr},
485			{DW_AT_low_pc, DW_FORM_addr},
486			{DW_AT_high_pc, DW_FORM_addr},
487			{DW_AT_frame_base, DW_FORM_block1},
488		},
489	},
490
491	/* WRAPPER_CONCRETE */
492	{
493		DW_TAG_subprogram,
494		DW_CHILDREN_yes,
495		[]dwAttrForm{
496			{DW_AT_abstract_origin, DW_FORM_ref_addr},
497			{DW_AT_low_pc, DW_FORM_addr},
498			{DW_AT_high_pc, DW_FORM_addr},
499			{DW_AT_frame_base, DW_FORM_block1},
500			{DW_AT_trampoline, DW_FORM_flag},
501		},
502	},
503
504	/* INLINED_SUBROUTINE */
505	{
506		DW_TAG_inlined_subroutine,
507		DW_CHILDREN_yes,
508		[]dwAttrForm{
509			{DW_AT_abstract_origin, DW_FORM_ref_addr},
510			{DW_AT_low_pc, DW_FORM_addr},
511			{DW_AT_high_pc, DW_FORM_addr},
512			{DW_AT_call_file, DW_FORM_data4},
513			{DW_AT_call_line, DW_FORM_udata_pseudo}, // pseudo-form
514		},
515	},
516
517	/* INLINED_SUBROUTINE_RANGES */
518	{
519		DW_TAG_inlined_subroutine,
520		DW_CHILDREN_yes,
521		[]dwAttrForm{
522			{DW_AT_abstract_origin, DW_FORM_ref_addr},
523			{DW_AT_ranges, DW_FORM_sec_offset},
524			{DW_AT_call_file, DW_FORM_data4},
525			{DW_AT_call_line, DW_FORM_udata_pseudo}, // pseudo-form
526		},
527	},
528
529	/* VARIABLE */
530	{
531		DW_TAG_variable,
532		DW_CHILDREN_no,
533		[]dwAttrForm{
534			{DW_AT_name, DW_FORM_string},
535			{DW_AT_location, DW_FORM_block1},
536			{DW_AT_type, DW_FORM_ref_addr},
537			{DW_AT_external, DW_FORM_flag},
538		},
539	},
540
541	/* INT CONSTANT */
542	{
543		DW_TAG_constant,
544		DW_CHILDREN_no,
545		[]dwAttrForm{
546			{DW_AT_name, DW_FORM_string},
547			{DW_AT_type, DW_FORM_ref_addr},
548			{DW_AT_const_value, DW_FORM_sdata},
549		},
550	},
551
552	/* LEXICAL_BLOCK_RANGES */
553	{
554		DW_TAG_lexical_block,
555		DW_CHILDREN_yes,
556		[]dwAttrForm{
557			{DW_AT_ranges, DW_FORM_sec_offset},
558		},
559	},
560
561	/* LEXICAL_BLOCK_SIMPLE */
562	{
563		DW_TAG_lexical_block,
564		DW_CHILDREN_yes,
565		[]dwAttrForm{
566			{DW_AT_low_pc, DW_FORM_addr},
567			{DW_AT_high_pc, DW_FORM_addr},
568		},
569	},
570
571	/* STRUCTFIELD */
572	{
573		DW_TAG_member,
574		DW_CHILDREN_no,
575		[]dwAttrForm{
576			{DW_AT_name, DW_FORM_string},
577			{DW_AT_data_member_location, DW_FORM_udata},
578			{DW_AT_type, DW_FORM_ref_addr},
579			{DW_AT_go_embedded_field, DW_FORM_flag},
580		},
581	},
582
583	/* FUNCTYPEPARAM */
584	{
585		DW_TAG_formal_parameter,
586		DW_CHILDREN_no,
587
588		// No name!
589		[]dwAttrForm{
590			{DW_AT_type, DW_FORM_ref_addr},
591		},
592	},
593
594	/* DOTDOTDOT */
595	{
596		DW_TAG_unspecified_parameters,
597		DW_CHILDREN_no,
598		[]dwAttrForm{},
599	},
600
601	/* ARRAYRANGE */
602	{
603		DW_TAG_subrange_type,
604		DW_CHILDREN_no,
605
606		// No name!
607		[]dwAttrForm{
608			{DW_AT_type, DW_FORM_ref_addr},
609			{DW_AT_count, DW_FORM_udata},
610		},
611	},
612
613	// Below here are the types considered public by ispubtype
614	/* NULLTYPE */
615	{
616		DW_TAG_unspecified_type,
617		DW_CHILDREN_no,
618		[]dwAttrForm{
619			{DW_AT_name, DW_FORM_string},
620		},
621	},
622
623	/* BASETYPE */
624	{
625		DW_TAG_base_type,
626		DW_CHILDREN_no,
627		[]dwAttrForm{
628			{DW_AT_name, DW_FORM_string},
629			{DW_AT_encoding, DW_FORM_data1},
630			{DW_AT_byte_size, DW_FORM_data1},
631			{DW_AT_go_kind, DW_FORM_data1},
632			{DW_AT_go_runtime_type, DW_FORM_addr},
633		},
634	},
635
636	/* ARRAYTYPE */
637	// child is subrange with upper bound
638	{
639		DW_TAG_array_type,
640		DW_CHILDREN_yes,
641		[]dwAttrForm{
642			{DW_AT_name, DW_FORM_string},
643			{DW_AT_type, DW_FORM_ref_addr},
644			{DW_AT_byte_size, DW_FORM_udata},
645			{DW_AT_go_kind, DW_FORM_data1},
646			{DW_AT_go_runtime_type, DW_FORM_addr},
647		},
648	},
649
650	/* CHANTYPE */
651	{
652		DW_TAG_typedef,
653		DW_CHILDREN_no,
654		[]dwAttrForm{
655			{DW_AT_name, DW_FORM_string},
656			{DW_AT_type, DW_FORM_ref_addr},
657			{DW_AT_go_kind, DW_FORM_data1},
658			{DW_AT_go_runtime_type, DW_FORM_addr},
659			{DW_AT_go_elem, DW_FORM_ref_addr},
660		},
661	},
662
663	/* FUNCTYPE */
664	{
665		DW_TAG_subroutine_type,
666		DW_CHILDREN_yes,
667		[]dwAttrForm{
668			{DW_AT_name, DW_FORM_string},
669			{DW_AT_byte_size, DW_FORM_udata},
670			{DW_AT_go_kind, DW_FORM_data1},
671			{DW_AT_go_runtime_type, DW_FORM_addr},
672		},
673	},
674
675	/* IFACETYPE */
676	{
677		DW_TAG_typedef,
678		DW_CHILDREN_yes,
679		[]dwAttrForm{
680			{DW_AT_name, DW_FORM_string},
681			{DW_AT_type, DW_FORM_ref_addr},
682			{DW_AT_go_kind, DW_FORM_data1},
683			{DW_AT_go_runtime_type, DW_FORM_addr},
684		},
685	},
686
687	/* MAPTYPE */
688	{
689		DW_TAG_typedef,
690		DW_CHILDREN_no,
691		[]dwAttrForm{
692			{DW_AT_name, DW_FORM_string},
693			{DW_AT_type, DW_FORM_ref_addr},
694			{DW_AT_go_kind, DW_FORM_data1},
695			{DW_AT_go_runtime_type, DW_FORM_addr},
696			{DW_AT_go_key, DW_FORM_ref_addr},
697			{DW_AT_go_elem, DW_FORM_ref_addr},
698		},
699	},
700
701	/* PTRTYPE */
702	{
703		DW_TAG_pointer_type,
704		DW_CHILDREN_no,
705		[]dwAttrForm{
706			{DW_AT_name, DW_FORM_string},
707			{DW_AT_type, DW_FORM_ref_addr},
708			{DW_AT_go_kind, DW_FORM_data1},
709			{DW_AT_go_runtime_type, DW_FORM_addr},
710		},
711	},
712
713	/* BARE_PTRTYPE */
714	{
715		DW_TAG_pointer_type,
716		DW_CHILDREN_no,
717		[]dwAttrForm{
718			{DW_AT_name, DW_FORM_string},
719			{DW_AT_go_runtime_type, DW_FORM_addr},
720		},
721	},
722
723	/* SLICETYPE */
724	{
725		DW_TAG_structure_type,
726		DW_CHILDREN_yes,
727		[]dwAttrForm{
728			{DW_AT_name, DW_FORM_string},
729			{DW_AT_byte_size, DW_FORM_udata},
730			{DW_AT_go_kind, DW_FORM_data1},
731			{DW_AT_go_runtime_type, DW_FORM_addr},
732			{DW_AT_go_elem, DW_FORM_ref_addr},
733		},
734	},
735
736	/* STRINGTYPE */
737	{
738		DW_TAG_structure_type,
739		DW_CHILDREN_yes,
740		[]dwAttrForm{
741			{DW_AT_name, DW_FORM_string},
742			{DW_AT_byte_size, DW_FORM_udata},
743			{DW_AT_go_kind, DW_FORM_data1},
744			{DW_AT_go_runtime_type, DW_FORM_addr},
745		},
746	},
747
748	/* STRUCTTYPE */
749	{
750		DW_TAG_structure_type,
751		DW_CHILDREN_yes,
752		[]dwAttrForm{
753			{DW_AT_name, DW_FORM_string},
754			{DW_AT_byte_size, DW_FORM_udata},
755			{DW_AT_go_kind, DW_FORM_data1},
756			{DW_AT_go_runtime_type, DW_FORM_addr},
757		},
758	},
759
760	/* TYPEDECL */
761	{
762		DW_TAG_typedef,
763		DW_CHILDREN_no,
764		[]dwAttrForm{
765			{DW_AT_name, DW_FORM_string},
766			{DW_AT_type, DW_FORM_ref_addr},
767		},
768	},
769
770	/* DICT_INDEX */
771	{
772		DW_TAG_typedef,
773		DW_CHILDREN_no,
774		[]dwAttrForm{
775			{DW_AT_name, DW_FORM_string},
776			{DW_AT_type, DW_FORM_ref_addr},
777			{DW_AT_go_dict_index, DW_FORM_udata},
778		},
779	},
780}
781
782// GetAbbrev returns the contents of the .debug_abbrev section.
783func GetAbbrev() []byte {
784	abbrevs := Abbrevs()
785	var buf []byte
786	for i := 1; i < len(abbrevs); i++ {
787		// See section 7.5.3
788		buf = AppendUleb128(buf, uint64(i))
789		buf = AppendUleb128(buf, uint64(abbrevs[i].tag))
790		buf = append(buf, abbrevs[i].children)
791		for _, f := range abbrevs[i].attr {
792			buf = AppendUleb128(buf, uint64(f.attr))
793			buf = AppendUleb128(buf, uint64(f.form))
794		}
795		buf = append(buf, 0, 0)
796	}
797	return append(buf, 0)
798}
799
800/*
801 * Debugging Information Entries and their attributes.
802 */
803
804// DWAttr represents an attribute of a DWDie.
805//
806// For DW_CLS_string and _block, value should contain the length, and
807// data the data, for _reference, value is 0 and data is a DWDie* to
808// the referenced instance, for all others, value is the whole thing
809// and data is null.
810type DWAttr struct {
811	Link  *DWAttr
812	Atr   uint16 // DW_AT_
813	Cls   uint8  // DW_CLS_
814	Value int64
815	Data  interface{}
816}
817
818// DWDie represents a DWARF debug info entry.
819type DWDie struct {
820	Abbrev int
821	Link   *DWDie
822	Child  *DWDie
823	Attr   *DWAttr
824	Sym    Sym
825}
826
827func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error {
828	switch form {
829	case DW_FORM_addr: // address
830		// Allow nil addresses for DW_AT_go_runtime_type.
831		if data == nil && value == 0 {
832			ctxt.AddInt(s, ctxt.PtrSize(), 0)
833			break
834		}
835		if cls == DW_CLS_GO_TYPEREF {
836			ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, value)
837			break
838		}
839		ctxt.AddAddress(s, data, value)
840
841	case DW_FORM_block1: // block
842		if cls == DW_CLS_ADDRESS {
843			ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize()))
844			ctxt.AddInt(s, 1, DW_OP_addr)
845			ctxt.AddAddress(s, data, 0)
846			break
847		}
848
849		value &= 0xff
850		ctxt.AddInt(s, 1, value)
851		p := data.([]byte)[:value]
852		ctxt.AddBytes(s, p)
853
854	case DW_FORM_block2: // block
855		value &= 0xffff
856
857		ctxt.AddInt(s, 2, value)
858		p := data.([]byte)[:value]
859		ctxt.AddBytes(s, p)
860
861	case DW_FORM_block4: // block
862		value &= 0xffffffff
863
864		ctxt.AddInt(s, 4, value)
865		p := data.([]byte)[:value]
866		ctxt.AddBytes(s, p)
867
868	case DW_FORM_block: // block
869		Uleb128put(ctxt, s, value)
870
871		p := data.([]byte)[:value]
872		ctxt.AddBytes(s, p)
873
874	case DW_FORM_data1: // constant
875		ctxt.AddInt(s, 1, value)
876
877	case DW_FORM_data2: // constant
878		ctxt.AddInt(s, 2, value)
879
880	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
881		if cls == DW_CLS_PTR { // DW_AT_stmt_list and DW_AT_ranges
882			ctxt.AddDWARFAddrSectionOffset(s, data, value)
883			break
884		}
885		ctxt.AddInt(s, 4, value)
886
887	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
888		ctxt.AddInt(s, 8, value)
889
890	case DW_FORM_sdata: // constant
891		Sleb128put(ctxt, s, value)
892
893	case DW_FORM_udata: // constant
894		Uleb128put(ctxt, s, value)
895
896	case DW_FORM_string: // string
897		str := data.(string)
898		ctxt.AddString(s, str)
899		// TODO(ribrdb): verify padded strings are never used and remove this
900		for i := int64(len(str)); i < value; i++ {
901			ctxt.AddInt(s, 1, 0)
902		}
903
904	case DW_FORM_flag: // flag
905		if value != 0 {
906			ctxt.AddInt(s, 1, 1)
907		} else {
908			ctxt.AddInt(s, 1, 0)
909		}
910
911	// As of DWARF 3 the ref_addr is always 32 bits, unless emitting a large
912	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
913	case DW_FORM_ref_addr: // reference to a DIE in the .info section
914		fallthrough
915	case DW_FORM_sec_offset: // offset into a DWARF section other than .info
916		if data == nil {
917			return fmt.Errorf("dwarf: null reference in %d", abbrev)
918		}
919		ctxt.AddDWARFAddrSectionOffset(s, data, value)
920
921	case DW_FORM_ref1, // reference within the compilation unit
922		DW_FORM_ref2,      // reference
923		DW_FORM_ref4,      // reference
924		DW_FORM_ref8,      // reference
925		DW_FORM_ref_udata, // reference
926
927		DW_FORM_strp,     // string
928		DW_FORM_indirect: // (see Section 7.5.3)
929		fallthrough
930	default:
931		return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls)
932	}
933	return nil
934}
935
936// PutAttrs writes the attributes for a DIE to symbol 's'.
937//
938// Note that we can (and do) add arbitrary attributes to a DIE, but
939// only the ones actually listed in the Abbrev will be written out.
940func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) {
941	abbrevs := Abbrevs()
942Outer:
943	for _, f := range abbrevs[abbrev].attr {
944		for ap := attr; ap != nil; ap = ap.Link {
945			if ap.Atr == f.attr {
946				putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data)
947				continue Outer
948			}
949		}
950
951		putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil)
952	}
953}
954
955// HasChildren reports whether 'die' uses an abbrev that supports children.
956func HasChildren(die *DWDie) bool {
957	abbrevs := Abbrevs()
958	return abbrevs[die.Abbrev].children != 0
959}
960
961// PutIntConst writes a DIE for an integer constant
962func PutIntConst(ctxt Context, info, typ Sym, name string, val int64) {
963	Uleb128put(ctxt, info, DW_ABRV_INT_CONSTANT)
964	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
965	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
966	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_sdata, DW_CLS_CONSTANT, val, nil)
967}
968
969// PutGlobal writes a DIE for a global variable.
970func PutGlobal(ctxt Context, info, typ, gvar Sym, name string) {
971	Uleb128put(ctxt, info, DW_ABRV_VARIABLE)
972	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
973	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_block1, DW_CLS_ADDRESS, 0, gvar)
974	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
975	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_flag, DW_CLS_FLAG, 1, nil)
976}
977
978// PutBasedRanges writes a range table to sym. All addresses in ranges are
979// relative to some base address, which must be arranged by the caller
980// (e.g., with a DW_AT_low_pc attribute, or in a BASE-prefixed range).
981func PutBasedRanges(ctxt Context, sym Sym, ranges []Range) {
982	ps := ctxt.PtrSize()
983	// Write ranges.
984	for _, r := range ranges {
985		ctxt.AddInt(sym, ps, r.Start)
986		ctxt.AddInt(sym, ps, r.End)
987	}
988	// Write trailer.
989	ctxt.AddInt(sym, ps, 0)
990	ctxt.AddInt(sym, ps, 0)
991}
992
993// PutRanges writes a range table to s.Ranges.
994// All addresses in ranges are relative to s.base.
995func (s *FnState) PutRanges(ctxt Context, ranges []Range) {
996	ps := ctxt.PtrSize()
997	sym, base := s.Ranges, s.StartPC
998
999	if s.UseBASEntries {
1000		// Using a Base Address Selection Entry reduces the number of relocations, but
1001		// this is not done on macOS because it is not supported by dsymutil/dwarfdump/lldb
1002		ctxt.AddInt(sym, ps, -1)
1003		ctxt.AddAddress(sym, base, 0)
1004		PutBasedRanges(ctxt, sym, ranges)
1005		return
1006	}
1007
1008	// Write ranges full of relocations
1009	for _, r := range ranges {
1010		ctxt.AddCURelativeAddress(sym, base, r.Start)
1011		ctxt.AddCURelativeAddress(sym, base, r.End)
1012	}
1013	// Write trailer.
1014	ctxt.AddInt(sym, ps, 0)
1015	ctxt.AddInt(sym, ps, 0)
1016}
1017
1018// Return TRUE if the inlined call in the specified slot is empty,
1019// meaning it has a zero-length range (no instructions), and all
1020// of its children are empty.
1021func isEmptyInlinedCall(slot int, calls *InlCalls) bool {
1022	ic := &calls.Calls[slot]
1023	if ic.InlIndex == -2 {
1024		return true
1025	}
1026	live := false
1027	for _, k := range ic.Children {
1028		if !isEmptyInlinedCall(k, calls) {
1029			live = true
1030		}
1031	}
1032	if len(ic.Ranges) > 0 {
1033		live = true
1034	}
1035	if !live {
1036		ic.InlIndex = -2
1037	}
1038	return !live
1039}
1040
1041// Slot -1:    return top-level inlines.
1042// Slot >= 0:  return children of that slot.
1043func inlChildren(slot int, calls *InlCalls) []int {
1044	var kids []int
1045	if slot != -1 {
1046		for _, k := range calls.Calls[slot].Children {
1047			if !isEmptyInlinedCall(k, calls) {
1048				kids = append(kids, k)
1049			}
1050		}
1051	} else {
1052		for k := 0; k < len(calls.Calls); k += 1 {
1053			if calls.Calls[k].Root && !isEmptyInlinedCall(k, calls) {
1054				kids = append(kids, k)
1055			}
1056		}
1057	}
1058	return kids
1059}
1060
1061func inlinedVarTable(inlcalls *InlCalls) map[*Var]bool {
1062	vars := make(map[*Var]bool)
1063	for _, ic := range inlcalls.Calls {
1064		for _, v := range ic.InlVars {
1065			vars[v] = true
1066		}
1067	}
1068	return vars
1069}
1070
1071// The s.Scopes slice contains variables were originally part of the
1072// function being emitted, as well as variables that were imported
1073// from various callee functions during the inlining process. This
1074// function prunes out any variables from the latter category (since
1075// they will be emitted as part of DWARF inlined_subroutine DIEs) and
1076// then generates scopes for vars in the former category.
1077func putPrunedScopes(ctxt Context, s *FnState, fnabbrev int) error {
1078	if len(s.Scopes) == 0 {
1079		return nil
1080	}
1081	scopes := make([]Scope, len(s.Scopes), len(s.Scopes))
1082	pvars := inlinedVarTable(&s.InlCalls)
1083	for k, s := range s.Scopes {
1084		var pruned Scope = Scope{Parent: s.Parent, Ranges: s.Ranges}
1085		for i := 0; i < len(s.Vars); i++ {
1086			_, found := pvars[s.Vars[i]]
1087			if !found {
1088				pruned.Vars = append(pruned.Vars, s.Vars[i])
1089			}
1090		}
1091		sort.Sort(byChildIndex(pruned.Vars))
1092		scopes[k] = pruned
1093	}
1094
1095	s.dictIndexToOffset = putparamtypes(ctxt, s, scopes, fnabbrev)
1096
1097	var encbuf [20]byte
1098	if putscope(ctxt, s, scopes, 0, fnabbrev, encbuf[:0]) < int32(len(scopes)) {
1099		return errors.New("multiple toplevel scopes")
1100	}
1101	return nil
1102}
1103
1104// Emit DWARF attributes and child DIEs for an 'abstract' subprogram.
1105// The abstract subprogram DIE for a function contains its
1106// location-independent attributes (name, type, etc). Other instances
1107// of the function (any inlined copy of it, or the single out-of-line
1108// 'concrete' instance) will contain a pointer back to this abstract
1109// DIE (as a space-saving measure, so that name/type etc doesn't have
1110// to be repeated for each inlined copy).
1111func PutAbstractFunc(ctxt Context, s *FnState) error {
1112	if logDwarf {
1113		ctxt.Logf("PutAbstractFunc(%v)\n", s.Absfn)
1114	}
1115
1116	abbrev := DW_ABRV_FUNCTION_ABSTRACT
1117	Uleb128put(ctxt, s.Absfn, int64(abbrev))
1118
1119	fullname := s.Name
1120	if strings.HasPrefix(s.Name, `"".`) {
1121		return fmt.Errorf("unqualified symbol name: %v", s.Name)
1122	}
1123	putattr(ctxt, s.Absfn, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(fullname)), fullname)
1124
1125	// DW_AT_inlined value
1126	putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
1127
1128	// TODO(mdempsky): Shouldn't we write out StartPos.FileIndex() too?
1129	putattr(ctxt, s.Absfn, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartPos.RelLine()), nil)
1130
1131	var ev int64
1132	if s.External {
1133		ev = 1
1134	}
1135	putattr(ctxt, s.Absfn, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
1136
1137	// Child variables (may be empty)
1138	var flattened []*Var
1139
1140	// This slice will hold the offset in bytes for each child var DIE
1141	// with respect to the start of the parent subprogram DIE.
1142	var offsets []int32
1143
1144	// Scopes/vars
1145	if len(s.Scopes) > 0 {
1146		// For abstract subprogram DIEs we want to flatten out scope info:
1147		// lexical scope DIEs contain range and/or hi/lo PC attributes,
1148		// which we explicitly don't want for the abstract subprogram DIE.
1149		pvars := inlinedVarTable(&s.InlCalls)
1150		for _, scope := range s.Scopes {
1151			for i := 0; i < len(scope.Vars); i++ {
1152				_, found := pvars[scope.Vars[i]]
1153				if found || !scope.Vars[i].IsInAbstract {
1154					continue
1155				}
1156				flattened = append(flattened, scope.Vars[i])
1157			}
1158		}
1159		if len(flattened) > 0 {
1160			sort.Sort(byChildIndex(flattened))
1161
1162			if logDwarf {
1163				ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
1164				for i, v := range flattened {
1165					ctxt.Logf(" %d:%s", i, v.Name)
1166				}
1167				ctxt.Logf("\n")
1168			}
1169
1170			// This slice will hold the offset in bytes for each child
1171			// variable DIE with respect to the start of the parent
1172			// subprogram DIE.
1173			for _, v := range flattened {
1174				offsets = append(offsets, int32(ctxt.CurrentOffset(s.Absfn)))
1175				putAbstractVar(ctxt, s.Absfn, v)
1176			}
1177		}
1178	}
1179	ctxt.RecordChildDieOffsets(s.Absfn, flattened, offsets)
1180
1181	Uleb128put(ctxt, s.Absfn, 0)
1182	return nil
1183}
1184
1185// Emit DWARF attributes and child DIEs for an inlined subroutine. The
1186// first attribute of an inlined subroutine DIE is a reference back to
1187// its corresponding 'abstract' DIE (containing location-independent
1188// attributes such as name, type, etc). Inlined subroutine DIEs can
1189// have other inlined subroutine DIEs as children.
1190func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error {
1191	ic := s.InlCalls.Calls[callIdx]
1192	callee := ic.AbsFunSym
1193
1194	abbrev := DW_ABRV_INLINED_SUBROUTINE_RANGES
1195	if len(ic.Ranges) == 1 {
1196		abbrev = DW_ABRV_INLINED_SUBROUTINE
1197	}
1198	Uleb128put(ctxt, s.Info, int64(abbrev))
1199
1200	if logDwarf {
1201		ctxt.Logf("putInlinedFunc(callee=%v,abbrev=%d)\n", callee, abbrev)
1202	}
1203
1204	// Abstract origin.
1205	putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, callee)
1206
1207	if abbrev == DW_ABRV_INLINED_SUBROUTINE_RANGES {
1208		putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, ctxt.Size(s.Ranges), s.Ranges)
1209		s.PutRanges(ctxt, ic.Ranges)
1210	} else {
1211		st := ic.Ranges[0].Start
1212		en := ic.Ranges[0].End
1213		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, st, s.StartPC)
1214		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, en, s.StartPC)
1215	}
1216
1217	// Emit call file, line attrs.
1218	putattr(ctxt, s.Info, abbrev, DW_FORM_data4, DW_CLS_CONSTANT, int64(1+ic.CallPos.FileIndex()), nil) // 1-based file table
1219	form := int(expandPseudoForm(DW_FORM_udata_pseudo))
1220	putattr(ctxt, s.Info, abbrev, form, DW_CLS_CONSTANT, int64(ic.CallPos.RelLine()), nil)
1221
1222	// Variables associated with this inlined routine instance.
1223	vars := ic.InlVars
1224	sort.Sort(byChildIndex(vars))
1225	inlIndex := ic.InlIndex
1226	var encbuf [20]byte
1227	for _, v := range vars {
1228		if !v.IsInAbstract {
1229			continue
1230		}
1231		putvar(ctxt, s, v, callee, abbrev, inlIndex, encbuf[:0])
1232	}
1233
1234	// Children of this inline.
1235	for _, sib := range inlChildren(callIdx, &s.InlCalls) {
1236		err := putInlinedFunc(ctxt, s, sib)
1237		if err != nil {
1238			return err
1239		}
1240	}
1241
1242	Uleb128put(ctxt, s.Info, 0)
1243	return nil
1244}
1245
1246// Emit DWARF attributes and child DIEs for a 'concrete' subprogram,
1247// meaning the out-of-line copy of a function that was inlined at some
1248// point during the compilation of its containing package. The first
1249// attribute for a concrete DIE is a reference to the 'abstract' DIE
1250// for the function (which holds location-independent attributes such
1251// as name, type), then the remainder of the attributes are specific
1252// to this instance (location, frame base, etc).
1253func PutConcreteFunc(ctxt Context, s *FnState, isWrapper bool) error {
1254	if logDwarf {
1255		ctxt.Logf("PutConcreteFunc(%v)\n", s.Info)
1256	}
1257	abbrev := DW_ABRV_FUNCTION_CONCRETE
1258	if isWrapper {
1259		abbrev = DW_ABRV_WRAPPER_CONCRETE
1260	}
1261	Uleb128put(ctxt, s.Info, int64(abbrev))
1262
1263	// Abstract origin.
1264	putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, s.Absfn)
1265
1266	// Start/end PC.
1267	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
1268	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
1269
1270	// cfa / frame base
1271	putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
1272
1273	if isWrapper {
1274		putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
1275	}
1276
1277	// Scopes
1278	if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
1279		return err
1280	}
1281
1282	// Inlined subroutines.
1283	for _, sib := range inlChildren(-1, &s.InlCalls) {
1284		err := putInlinedFunc(ctxt, s, sib)
1285		if err != nil {
1286			return err
1287		}
1288	}
1289
1290	Uleb128put(ctxt, s.Info, 0)
1291	return nil
1292}
1293
1294// Emit DWARF attributes and child DIEs for a subprogram. Here
1295// 'default' implies that the function in question was not inlined
1296// when its containing package was compiled (hence there is no need to
1297// emit an abstract version for it to use as a base for inlined
1298// routine records).
1299func PutDefaultFunc(ctxt Context, s *FnState, isWrapper bool) error {
1300	if logDwarf {
1301		ctxt.Logf("PutDefaultFunc(%v)\n", s.Info)
1302	}
1303	abbrev := DW_ABRV_FUNCTION
1304	if isWrapper {
1305		abbrev = DW_ABRV_WRAPPER
1306	}
1307	Uleb128put(ctxt, s.Info, int64(abbrev))
1308
1309	name := s.Name
1310	if strings.HasPrefix(name, `"".`) {
1311		return fmt.Errorf("unqualified symbol name: %v", name)
1312	}
1313
1314	putattr(ctxt, s.Info, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
1315	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
1316	putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
1317	putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
1318	if isWrapper {
1319		putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
1320	} else {
1321		putattr(ctxt, s.Info, abbrev, DW_FORM_data4, DW_CLS_CONSTANT, int64(1+s.StartPos.FileIndex()), nil) // 1-based file index
1322		putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartPos.RelLine()), nil)
1323
1324		var ev int64
1325		if s.External {
1326			ev = 1
1327		}
1328		putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
1329	}
1330
1331	// Scopes
1332	if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
1333		return err
1334	}
1335
1336	// Inlined subroutines.
1337	for _, sib := range inlChildren(-1, &s.InlCalls) {
1338		err := putInlinedFunc(ctxt, s, sib)
1339		if err != nil {
1340			return err
1341		}
1342	}
1343
1344	Uleb128put(ctxt, s.Info, 0)
1345	return nil
1346}
1347
1348// putparamtypes writes typedef DIEs for any parametric types that are used by this function.
1349func putparamtypes(ctxt Context, s *FnState, scopes []Scope, fnabbrev int) []int64 {
1350	if fnabbrev == DW_ABRV_FUNCTION_CONCRETE {
1351		return nil
1352	}
1353
1354	maxDictIndex := uint16(0)
1355
1356	for i := range scopes {
1357		for _, v := range scopes[i].Vars {
1358			if v.DictIndex > maxDictIndex {
1359				maxDictIndex = v.DictIndex
1360			}
1361		}
1362	}
1363
1364	if maxDictIndex == 0 {
1365		return nil
1366	}
1367
1368	dictIndexToOffset := make([]int64, maxDictIndex)
1369
1370	for i := range scopes {
1371		for _, v := range scopes[i].Vars {
1372			if v.DictIndex == 0 || dictIndexToOffset[v.DictIndex-1] != 0 {
1373				continue
1374			}
1375
1376			dictIndexToOffset[v.DictIndex-1] = ctxt.CurrentOffset(s.Info)
1377
1378			Uleb128put(ctxt, s.Info, int64(DW_ABRV_DICT_INDEX))
1379			n := fmt.Sprintf(".param%d", v.DictIndex-1)
1380			putattr(ctxt, s.Info, DW_ABRV_DICT_INDEX, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
1381			putattr(ctxt, s.Info, DW_ABRV_DICT_INDEX, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
1382			putattr(ctxt, s.Info, DW_ABRV_DICT_INDEX, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DictIndex-1), nil)
1383		}
1384	}
1385
1386	return dictIndexToOffset
1387}
1388
1389func putscope(ctxt Context, s *FnState, scopes []Scope, curscope int32, fnabbrev int, encbuf []byte) int32 {
1390
1391	if logDwarf {
1392		ctxt.Logf("putscope(%v,%d): vars:", s.Info, curscope)
1393		for i, v := range scopes[curscope].Vars {
1394			ctxt.Logf(" %d:%d:%s", i, v.ChildIndex, v.Name)
1395		}
1396		ctxt.Logf("\n")
1397	}
1398
1399	for _, v := range scopes[curscope].Vars {
1400		putvar(ctxt, s, v, s.Absfn, fnabbrev, -1, encbuf)
1401	}
1402	this := curscope
1403	curscope++
1404	for curscope < int32(len(scopes)) {
1405		scope := scopes[curscope]
1406		if scope.Parent != this {
1407			return curscope
1408		}
1409
1410		if len(scopes[curscope].Vars) == 0 {
1411			curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
1412			continue
1413		}
1414
1415		if len(scope.Ranges) == 1 {
1416			Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
1417			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, s.StartPC)
1418			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, s.StartPC)
1419		} else {
1420			Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES)
1421			putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, ctxt.Size(s.Ranges), s.Ranges)
1422
1423			s.PutRanges(ctxt, scope.Ranges)
1424		}
1425
1426		curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
1427
1428		Uleb128put(ctxt, s.Info, 0)
1429	}
1430	return curscope
1431}
1432
1433func concreteVar(fnabbrev int, v *Var) bool {
1434	concrete := true
1435	switch fnabbrev {
1436	case DW_ABRV_FUNCTION, DW_ABRV_WRAPPER:
1437		concrete = false
1438	case DW_ABRV_FUNCTION_CONCRETE, DW_ABRV_WRAPPER_CONCRETE:
1439		// If we're emitting a concrete subprogram DIE and the variable
1440		// in question is not part of the corresponding abstract function DIE,
1441		// then use the default (non-concrete) abbrev for this param.
1442		if !v.IsInAbstract {
1443			concrete = false
1444		}
1445	case DW_ABRV_INLINED_SUBROUTINE, DW_ABRV_INLINED_SUBROUTINE_RANGES:
1446	default:
1447		panic("should never happen")
1448	}
1449	return concrete
1450}
1451
1452// Emit DWARF attributes for a variable belonging to an 'abstract' subprogram.
1453func putAbstractVar(ctxt Context, info Sym, v *Var) {
1454	// The contents of this functions are used to generate putAbstractVarAbbrev automatically, see TestPutVarAbbrevGenerator.
1455	abbrev := putAbstractVarAbbrev(v)
1456	Uleb128put(ctxt, info, int64(abbrev))
1457	putattr(ctxt, info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(v.Name)), v.Name) // DW_AT_name
1458
1459	// Isreturn attribute if this is a param
1460	if v.Tag == DW_TAG_formal_parameter {
1461		var isReturn int64
1462		if v.IsReturnValue {
1463			isReturn = 1
1464		}
1465		putattr(ctxt, info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil) // DW_AT_variable_parameter
1466	}
1467
1468	// Line
1469	if v.Tag == DW_TAG_variable {
1470		// See issue 23374 for more on why decl line is skipped for abs params.
1471		putattr(ctxt, info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil) // DW_AT_decl_line
1472	}
1473
1474	// Type
1475	putattr(ctxt, info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type) // DW_AT_type
1476
1477	// Var has no children => no terminator
1478}
1479
1480func putvar(ctxt Context, s *FnState, v *Var, absfn Sym, fnabbrev, inlIndex int, encbuf []byte) {
1481	// The contents of this functions are used to generate putvarAbbrev automatically, see TestPutVarAbbrevGenerator.
1482	concrete := concreteVar(fnabbrev, v)
1483	hasParametricType := !concrete && (v.DictIndex > 0 && s.dictIndexToOffset != nil && s.dictIndexToOffset[v.DictIndex-1] != 0)
1484	withLoclist := v.WithLoclist && v.PutLocationList != nil
1485
1486	abbrev := putvarAbbrev(v, concrete, withLoclist)
1487	Uleb128put(ctxt, s.Info, int64(abbrev))
1488
1489	// Abstract origin for concrete / inlined case
1490	if concrete {
1491		// Here we are making a reference to a child DIE of an abstract
1492		// function subprogram DIE. The child DIE has no LSym, so instead
1493		// after the call to 'putattr' below we make a call to register
1494		// the child DIE reference.
1495		putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, absfn) // DW_AT_abstract_origin
1496		ctxt.RecordDclReference(s.Info, absfn, int(v.ChildIndex), inlIndex)
1497	} else {
1498		// Var name, line for abstract and default cases
1499		n := v.Name
1500		putattr(ctxt, s.Info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n) // DW_AT_name
1501		if v.Tag == DW_TAG_formal_parameter {
1502			var isReturn int64
1503			if v.IsReturnValue {
1504				isReturn = 1
1505			}
1506			putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil) // DW_AT_variable_parameter
1507		}
1508		putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil) // DW_AT_decl_line
1509		if hasParametricType {
1510			// If the type of this variable is parametric use the entry emitted by putparamtypes
1511			putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, s.dictIndexToOffset[v.DictIndex-1], s.Info) // DW_AT_type
1512		} else {
1513			putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type) // DW_AT_type
1514		}
1515
1516		if v.ClosureOffset > 0 {
1517			putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, v.ClosureOffset, nil) // DW_AT_go_closure_offset
1518		}
1519	}
1520
1521	if withLoclist {
1522		putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, ctxt.Size(s.Loc), s.Loc) // DW_AT_location
1523		v.PutLocationList(s.Loc, s.StartPC)
1524	} else {
1525		loc := encbuf[:0]
1526		switch {
1527		case v.WithLoclist:
1528			break // no location
1529		case v.StackOffset == 0:
1530			loc = append(loc, DW_OP_call_frame_cfa)
1531		default:
1532			loc = append(loc, DW_OP_fbreg)
1533			loc = AppendSleb128(loc, int64(v.StackOffset))
1534		}
1535		putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc) // DW_AT_location
1536	}
1537
1538	// Var has no children => no terminator
1539}
1540
1541// byChildIndex implements sort.Interface for []*dwarf.Var by child index.
1542type byChildIndex []*Var
1543
1544func (s byChildIndex) Len() int           { return len(s) }
1545func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
1546func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
1547
1548// IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
1549// current extld.
1550// AIX ld doesn't support DWARF with -bnoobjreorder with version
1551// prior to 7.2.2.
1552func IsDWARFEnabledOnAIXLd(extld []string) (bool, error) {
1553	name, args := extld[0], extld[1:]
1554	args = append(args, "-Wl,-V")
1555	out, err := exec.Command(name, args...).CombinedOutput()
1556	if err != nil {
1557		// The normal output should display ld version and
1558		// then fails because ".main" is not defined:
1559		// ld: 0711-317 ERROR: Undefined symbol: .main
1560		if !bytes.Contains(out, []byte("0711-317")) {
1561			return false, fmt.Errorf("%s -Wl,-V failed: %v\n%s", extld, err, out)
1562		}
1563	}
1564	// gcc -Wl,-V output should be:
1565	//   /usr/bin/ld: LD X.X.X(date)
1566	//   ...
1567	out = bytes.TrimPrefix(out, []byte("/usr/bin/ld: LD "))
1568	vers := string(bytes.Split(out, []byte("("))[0])
1569	subvers := strings.Split(vers, ".")
1570	if len(subvers) != 3 {
1571		return false, fmt.Errorf("cannot parse %s -Wl,-V (%s): %v\n", extld, out, err)
1572	}
1573	if v, err := strconv.Atoi(subvers[0]); err != nil || v < 7 {
1574		return false, nil
1575	} else if v > 7 {
1576		return true, nil
1577	}
1578	if v, err := strconv.Atoi(subvers[1]); err != nil || v < 2 {
1579		return false, nil
1580	} else if v > 2 {
1581		return true, nil
1582	}
1583	if v, err := strconv.Atoi(subvers[2]); err != nil || v < 2 {
1584		return false, nil
1585	}
1586	return true, nil
1587}
1588