...

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

     1	// Copyright 2016 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package dwarf generates DWARF debugging information.
     6	// DWARF generation is split between the compiler and the linker,
     7	// this package contains the shared code.
     8	package dwarf
     9	
    10	import (
    11		"bytes"
    12		"cmd/internal/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	// IsStmtPrefix is the prefix for all the symbols containing DWARF is_stmt info for the line number table.
    31	const IsStmtPrefix = "go.isstmt."
    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		putattr(ctxt, s.Info, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(s.Name)), s.Name)
  1376		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
  1377		putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
  1378		putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
  1379		ctxt.AddFileRef(s.Info, s.Filesym)
  1380	
  1381		var ev int64
  1382		if s.External {
  1383			ev = 1
  1384		}
  1385		putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
  1386	
  1387		// Scopes
  1388		if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
  1389			return err
  1390		}
  1391	
  1392		// Inlined subroutines.
  1393		for _, sib := range inlChildren(-1, &s.InlCalls) {
  1394			absfn := s.InlCalls.Calls[sib].AbsFunSym
  1395			err := PutInlinedFunc(ctxt, s, absfn, sib)
  1396			if err != nil {
  1397				return err
  1398			}
  1399		}
  1400	
  1401		Uleb128put(ctxt, s.Info, 0)
  1402		return nil
  1403	}
  1404	
  1405	func putscope(ctxt Context, s *FnState, scopes []Scope, curscope int32, fnabbrev int, encbuf []byte) int32 {
  1406	
  1407		if logDwarf {
  1408			ctxt.Logf("putscope(%v,%d): vars:", s.Info, curscope)
  1409			for i, v := range scopes[curscope].Vars {
  1410				ctxt.Logf(" %d:%d:%s", i, v.ChildIndex, v.Name)
  1411			}
  1412			ctxt.Logf("\n")
  1413		}
  1414	
  1415		for _, v := range scopes[curscope].Vars {
  1416			putvar(ctxt, s, v, s.Absfn, fnabbrev, -1, encbuf)
  1417		}
  1418		this := curscope
  1419		curscope++
  1420		for curscope < int32(len(scopes)) {
  1421			scope := scopes[curscope]
  1422			if scope.Parent != this {
  1423				return curscope
  1424			}
  1425	
  1426			if len(scopes[curscope].Vars) == 0 {
  1427				curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
  1428				continue
  1429			}
  1430	
  1431			if len(scope.Ranges) == 1 {
  1432				Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
  1433				putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, s.StartPC)
  1434				putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, s.StartPC)
  1435			} else {
  1436				Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES)
  1437				putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, s.Ranges.Len(), s.Ranges)
  1438	
  1439				s.PutRanges(ctxt, scope.Ranges)
  1440			}
  1441	
  1442			curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
  1443	
  1444			Uleb128put(ctxt, s.Info, 0)
  1445		}
  1446		return curscope
  1447	}
  1448	
  1449	// Given a default var abbrev code, select corresponding concrete code.
  1450	func concreteVarAbbrev(varAbbrev int) int {
  1451		switch varAbbrev {
  1452		case DW_ABRV_AUTO:
  1453			return DW_ABRV_AUTO_CONCRETE
  1454		case DW_ABRV_PARAM:
  1455			return DW_ABRV_PARAM_CONCRETE
  1456		case DW_ABRV_AUTO_LOCLIST:
  1457			return DW_ABRV_AUTO_CONCRETE_LOCLIST
  1458		case DW_ABRV_PARAM_LOCLIST:
  1459			return DW_ABRV_PARAM_CONCRETE_LOCLIST
  1460		default:
  1461			panic("should never happen")
  1462		}
  1463	}
  1464	
  1465	// Pick the correct abbrev code for variable or parameter DIE.
  1466	func determineVarAbbrev(v *Var, fnabbrev int) (int, bool, bool) {
  1467		abbrev := v.Abbrev
  1468	
  1469		// If the variable was entirely optimized out, don't emit a location list;
  1470		// convert to an inline abbreviation and emit an empty location.
  1471		missing := false
  1472		switch {
  1473		case abbrev == DW_ABRV_AUTO_LOCLIST && v.PutLocationList == nil:
  1474			missing = true
  1475			abbrev = DW_ABRV_AUTO
  1476		case abbrev == DW_ABRV_PARAM_LOCLIST && v.PutLocationList == nil:
  1477			missing = true
  1478			abbrev = DW_ABRV_PARAM
  1479		}
  1480	
  1481		// Determine whether to use a concrete variable or regular variable DIE.
  1482		concrete := true
  1483		switch fnabbrev {
  1484		case DW_ABRV_FUNCTION:
  1485			concrete = false
  1486			break
  1487		case DW_ABRV_FUNCTION_CONCRETE:
  1488			// If we're emitting a concrete subprogram DIE and the variable
  1489			// in question is not part of the corresponding abstract function DIE,
  1490			// then use the default (non-concrete) abbrev for this param.
  1491			if !v.IsInAbstract {
  1492				concrete = false
  1493			}
  1494		case DW_ABRV_INLINED_SUBROUTINE, DW_ABRV_INLINED_SUBROUTINE_RANGES:
  1495		default:
  1496			panic("should never happen")
  1497		}
  1498	
  1499		// Select proper abbrev based on concrete/non-concrete
  1500		if concrete {
  1501			abbrev = concreteVarAbbrev(abbrev)
  1502		}
  1503	
  1504		return abbrev, missing, concrete
  1505	}
  1506	
  1507	func abbrevUsesLoclist(abbrev int) bool {
  1508		switch abbrev {
  1509		case DW_ABRV_AUTO_LOCLIST, DW_ABRV_AUTO_CONCRETE_LOCLIST,
  1510			DW_ABRV_PARAM_LOCLIST, DW_ABRV_PARAM_CONCRETE_LOCLIST:
  1511			return true
  1512		default:
  1513			return false
  1514		}
  1515	}
  1516	
  1517	// Emit DWARF attributes for a variable belonging to an 'abstract' subprogram.
  1518	func putAbstractVar(ctxt Context, info Sym, v *Var) {
  1519		// Remap abbrev
  1520		abbrev := v.Abbrev
  1521		switch abbrev {
  1522		case DW_ABRV_AUTO, DW_ABRV_AUTO_LOCLIST:
  1523			abbrev = DW_ABRV_AUTO_ABSTRACT
  1524		case DW_ABRV_PARAM, DW_ABRV_PARAM_LOCLIST:
  1525			abbrev = DW_ABRV_PARAM_ABSTRACT
  1526		}
  1527	
  1528		Uleb128put(ctxt, info, int64(abbrev))
  1529		putattr(ctxt, info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(v.Name)), v.Name)
  1530	
  1531		// Isreturn attribute if this is a param
  1532		if abbrev == DW_ABRV_PARAM_ABSTRACT {
  1533			var isReturn int64
  1534			if v.IsReturnValue {
  1535				isReturn = 1
  1536			}
  1537			putattr(ctxt, info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
  1538		}
  1539	
  1540		// Line
  1541		if abbrev != DW_ABRV_PARAM_ABSTRACT {
  1542			// See issue 23374 for more on why decl line is skipped for abs params.
  1543			putattr(ctxt, info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
  1544		}
  1545	
  1546		// Type
  1547		putattr(ctxt, info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
  1548	
  1549		// Var has no children => no terminator
  1550	}
  1551	
  1552	func putvar(ctxt Context, s *FnState, v *Var, absfn Sym, fnabbrev, inlIndex int, encbuf []byte) {
  1553		// Remap abbrev according to parent DIE abbrev
  1554		abbrev, missing, concrete := determineVarAbbrev(v, fnabbrev)
  1555	
  1556		Uleb128put(ctxt, s.Info, int64(abbrev))
  1557	
  1558		// Abstract origin for concrete / inlined case
  1559		if concrete {
  1560			// Here we are making a reference to a child DIE of an abstract
  1561			// function subprogram DIE. The child DIE has no LSym, so instead
  1562			// after the call to 'putattr' below we make a call to register
  1563			// the child DIE reference.
  1564			putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, absfn)
  1565			ctxt.RecordDclReference(s.Info, absfn, int(v.ChildIndex), inlIndex)
  1566		} else {
  1567			// Var name, line for abstract and default cases
  1568			n := v.Name
  1569			putattr(ctxt, s.Info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
  1570			if abbrev == DW_ABRV_PARAM || abbrev == DW_ABRV_PARAM_LOCLIST || abbrev == DW_ABRV_PARAM_ABSTRACT {
  1571				var isReturn int64
  1572				if v.IsReturnValue {
  1573					isReturn = 1
  1574				}
  1575				putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
  1576			}
  1577			putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
  1578			putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
  1579		}
  1580	
  1581		if abbrevUsesLoclist(abbrev) {
  1582			putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, s.Loc.Len(), s.Loc)
  1583			v.PutLocationList(s.Loc, s.StartPC)
  1584		} else {
  1585			loc := encbuf[:0]
  1586			switch {
  1587			case missing:
  1588				break // no location
  1589			case v.StackOffset == 0:
  1590				loc = append(loc, DW_OP_call_frame_cfa)
  1591			default:
  1592				loc = append(loc, DW_OP_fbreg)
  1593				loc = AppendSleb128(loc, int64(v.StackOffset))
  1594			}
  1595			putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
  1596		}
  1597	
  1598		// Var has no children => no terminator
  1599	}
  1600	
  1601	// VarsByOffset attaches the methods of sort.Interface to []*Var,
  1602	// sorting in increasing StackOffset.
  1603	type VarsByOffset []*Var
  1604	
  1605	func (s VarsByOffset) Len() int           { return len(s) }
  1606	func (s VarsByOffset) Less(i, j int) bool { return s[i].StackOffset < s[j].StackOffset }
  1607	func (s VarsByOffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
  1608	
  1609	// byChildIndex implements sort.Interface for []*dwarf.Var by child index.
  1610	type byChildIndex []*Var
  1611	
  1612	func (s byChildIndex) Len() int           { return len(s) }
  1613	func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
  1614	func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
  1615	
  1616	// IsDWARFEnabledOnAIX returns true if DWARF is possible on the
  1617	// current extld.
  1618	// AIX ld doesn't support DWARF with -bnoobjreorder with version
  1619	// prior to 7.2.2.
  1620	func IsDWARFEnabledOnAIXLd(extld string) (bool, error) {
  1621		out, err := exec.Command(extld, "-Wl,-V").CombinedOutput()
  1622		if err != nil {
  1623			// The normal output should display ld version and
  1624			// then fails because ".main" is not defined:
  1625			// ld: 0711-317 ERROR: Undefined symbol: .main
  1626			if !bytes.Contains(out, []byte("0711-317")) {
  1627				return false, fmt.Errorf("%s -Wl,-V failed: %v\n%s", extld, err, out)
  1628			}
  1629		}
  1630		// gcc -Wl,-V output should be:
  1631		//   /usr/bin/ld: LD X.X.X(date)
  1632		//   ...
  1633		out = bytes.TrimPrefix(out, []byte("/usr/bin/ld: LD "))
  1634		vers := string(bytes.Split(out, []byte("("))[0])
  1635		subvers := strings.Split(vers, ".")
  1636		if len(subvers) != 3 {
  1637			return false, fmt.Errorf("cannot parse %s -Wl,-V (%s): %v\n", extld, out, err)
  1638		}
  1639		if v, err := strconv.Atoi(subvers[0]); err != nil || v < 7 {
  1640			return false, nil
  1641		} else if v > 7 {
  1642			return true, nil
  1643		}
  1644		if v, err := strconv.Atoi(subvers[1]); err != nil || v < 2 {
  1645			return false, nil
  1646		} else if v > 2 {
  1647			return true, nil
  1648		}
  1649		if v, err := strconv.Atoi(subvers[2]); err != nil || v < 2 {
  1650			return false, nil
  1651		}
  1652		return true, nil
  1653	}
  1654	

View as plain text