github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/cmd/internal/dwarf/dwarf.go (about)

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