Source file src/cmd/internal/dwarf/dwarf.go

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

View as plain text