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