gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

dwarf.go (43976B)


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