Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: cmd/internal/dwarf

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

View as plain text