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