github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/dwarf/dwarf.go (about)

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