github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/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  	"github.com/shogo82148/std/cmd/internal/src"
    12  )
    13  
    14  // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
    15  const InfoPrefix = "go:info."
    16  
    17  // ConstInfoPrefix is the prefix for all symbols containing DWARF info
    18  // entries that contain constants.
    19  const ConstInfoPrefix = "go:constinfo."
    20  
    21  // CUInfoPrefix is the prefix for symbols containing information to
    22  // populate the DWARF compilation unit info entries.
    23  const CUInfoPrefix = "go:cuinfo."
    24  
    25  // Used to form the symbol name assigned to the DWARF 'abstract subprogram"
    26  // info entry for a function
    27  const AbstractFuncSuffix = "$abstract"
    28  
    29  // Sym represents a symbol.
    30  type Sym interface {
    31  }
    32  
    33  // A Var represents a local variable or a function parameter.
    34  type Var struct {
    35  	Name          string
    36  	Tag           int
    37  	WithLoclist   bool
    38  	IsReturnValue bool
    39  	IsInlFormal   bool
    40  	DictIndex     uint16
    41  	StackOffset   int32
    42  	// This package can't use the ssa package, so it can't mention ssa.FuncDebug,
    43  	// so indirect through a closure.
    44  	PutLocationList func(listSym, startPC Sym)
    45  	Scope           int32
    46  	Type            Sym
    47  	DeclFile        string
    48  	DeclLine        uint
    49  	DeclCol         uint
    50  	InlIndex        int32
    51  	ChildIndex      int32
    52  	IsInAbstract    bool
    53  	ClosureOffset   int64
    54  }
    55  
    56  // A Scope represents a lexical scope. All variables declared within a
    57  // scope will only be visible to instructions covered by the scope.
    58  // Lexical scopes are contiguous in source files but can end up being
    59  // compiled to discontiguous blocks of instructions in the executable.
    60  // The Ranges field lists all the blocks of instructions that belong
    61  // in this scope.
    62  type Scope struct {
    63  	Parent int32
    64  	Ranges []Range
    65  	Vars   []*Var
    66  }
    67  
    68  // A Range represents a half-open interval [Start, End).
    69  type Range struct {
    70  	Start, End int64
    71  }
    72  
    73  // This container is used by the PutFunc* variants below when
    74  // creating the DWARF subprogram DIE(s) for a function.
    75  type FnState struct {
    76  	Name          string
    77  	Info          Sym
    78  	Loc           Sym
    79  	Ranges        Sym
    80  	Absfn         Sym
    81  	StartPC       Sym
    82  	StartPos      src.Pos
    83  	Size          int64
    84  	External      bool
    85  	Scopes        []Scope
    86  	InlCalls      InlCalls
    87  	UseBASEntries bool
    88  
    89  	dictIndexToOffset []int64
    90  }
    91  
    92  func EnableLogging(doit bool)
    93  
    94  // MergeRanges creates a new range list by merging the ranges from
    95  // its two arguments, then returns the new list.
    96  func MergeRanges(in1, in2 []Range) []Range
    97  
    98  // UnifyRanges merges the ranges from 'c' into the list of ranges for 's'.
    99  func (s *Scope) UnifyRanges(c *Scope)
   100  
   101  // AppendRange adds r to s, if r is non-empty.
   102  // If possible, it extends the last Range in s.Ranges; if not, it creates a new one.
   103  func (s *Scope) AppendRange(r Range)
   104  
   105  type InlCalls struct {
   106  	Calls []InlCall
   107  }
   108  
   109  type InlCall struct {
   110  	// index into ctx.InlTree describing the call inlined here
   111  	InlIndex int
   112  
   113  	// Position of the inlined call site.
   114  	CallPos src.Pos
   115  
   116  	// Dwarf abstract subroutine symbol (really *obj.LSym).
   117  	AbsFunSym Sym
   118  
   119  	// Indices of child inlines within Calls array above.
   120  	Children []int
   121  
   122  	// entries in this list are PAUTO's created by the inliner to
   123  	// capture the promoted formals and locals of the inlined callee.
   124  	InlVars []*Var
   125  
   126  	// PC ranges for this inlined call.
   127  	Ranges []Range
   128  
   129  	// Root call (not a child of some other call).
   130  	Root bool
   131  }
   132  
   133  // A Context specifies how to add data to a Sym.
   134  type Context interface {
   135  	PtrSize() int
   136  	Size(s Sym) int64
   137  	AddInt(s Sym, size int, i int64)
   138  	AddBytes(s Sym, b []byte)
   139  	AddAddress(s Sym, t interface{}, ofs int64)
   140  	AddCURelativeAddress(s Sym, t interface{}, ofs int64)
   141  	AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
   142  	AddDWARFAddrSectionOffset(s Sym, t interface{}, ofs int64)
   143  	CurrentOffset(s Sym) int64
   144  	RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
   145  	RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
   146  	AddString(s Sym, v string)
   147  	Logf(format string, args ...interface{})
   148  }
   149  
   150  // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
   151  func AppendUleb128(b []byte, v uint64) []byte
   152  
   153  // AppendSleb128 appends v to b using DWARF's signed LEB128 encoding.
   154  func AppendSleb128(b []byte, v int64) []byte
   155  
   156  // Uleb128put appends v to s using DWARF's unsigned LEB128 encoding.
   157  func Uleb128put(ctxt Context, s Sym, v int64)
   158  
   159  // Sleb128put appends v to s using DWARF's signed LEB128 encoding.
   160  func Sleb128put(ctxt Context, s Sym, v int64)
   161  
   162  // Go-specific type attributes.
   163  const (
   164  	DW_AT_go_kind = 0x2900
   165  	DW_AT_go_key  = 0x2901
   166  	DW_AT_go_elem = 0x2902
   167  	// Attribute for DW_TAG_member of a struct type.
   168  	// Nonzero value indicates the struct field is an embedded field.
   169  	DW_AT_go_embedded_field = 0x2903
   170  	DW_AT_go_runtime_type   = 0x2904
   171  
   172  	DW_AT_go_package_name   = 0x2905
   173  	DW_AT_go_dict_index     = 0x2906
   174  	DW_AT_go_closure_offset = 0x2907
   175  
   176  	DW_AT_internal_location = 253
   177  )
   178  
   179  // Index into the abbrevs table below.
   180  const (
   181  	DW_ABRV_NULL = iota
   182  	DW_ABRV_COMPUNIT
   183  	DW_ABRV_COMPUNIT_TEXTLESS
   184  	DW_ABRV_FUNCTION
   185  	DW_ABRV_WRAPPER
   186  	DW_ABRV_FUNCTION_ABSTRACT
   187  	DW_ABRV_FUNCTION_CONCRETE
   188  	DW_ABRV_WRAPPER_CONCRETE
   189  	DW_ABRV_INLINED_SUBROUTINE
   190  	DW_ABRV_INLINED_SUBROUTINE_RANGES
   191  	DW_ABRV_VARIABLE
   192  	DW_ABRV_INT_CONSTANT
   193  	DW_ABRV_LEXICAL_BLOCK_RANGES
   194  	DW_ABRV_LEXICAL_BLOCK_SIMPLE
   195  	DW_ABRV_STRUCTFIELD
   196  	DW_ABRV_FUNCTYPEPARAM
   197  	DW_ABRV_DOTDOTDOT
   198  	DW_ABRV_ARRAYRANGE
   199  	DW_ABRV_NULLTYPE
   200  	DW_ABRV_BASETYPE
   201  	DW_ABRV_ARRAYTYPE
   202  	DW_ABRV_CHANTYPE
   203  	DW_ABRV_FUNCTYPE
   204  	DW_ABRV_IFACETYPE
   205  	DW_ABRV_MAPTYPE
   206  	DW_ABRV_PTRTYPE
   207  	DW_ABRV_BARE_PTRTYPE
   208  	DW_ABRV_SLICETYPE
   209  	DW_ABRV_STRINGTYPE
   210  	DW_ABRV_STRUCTTYPE
   211  	DW_ABRV_TYPEDECL
   212  	DW_ABRV_DICT_INDEX
   213  	DW_ABRV_PUTVAR_START
   214  )
   215  
   216  // Abbrevs returns the finalized abbrev array for the platform,
   217  // expanding any DW_FORM pseudo-ops to real values.
   218  func Abbrevs() []dwAbbrev
   219  
   220  // GetAbbrev returns the contents of the .debug_abbrev section.
   221  func GetAbbrev() []byte
   222  
   223  // DWAttr represents an attribute of a DWDie.
   224  //
   225  // For DW_CLS_string and _block, value should contain the length, and
   226  // data the data, for _reference, value is 0 and data is a DWDie* to
   227  // the referenced instance, for all others, value is the whole thing
   228  // and data is null.
   229  type DWAttr struct {
   230  	Link  *DWAttr
   231  	Atr   uint16
   232  	Cls   uint8
   233  	Value int64
   234  	Data  interface{}
   235  }
   236  
   237  // DWDie represents a DWARF debug info entry.
   238  type DWDie struct {
   239  	Abbrev int
   240  	Link   *DWDie
   241  	Child  *DWDie
   242  	Attr   *DWAttr
   243  	Sym    Sym
   244  }
   245  
   246  // PutAttrs writes the attributes for a DIE to symbol 's'.
   247  //
   248  // Note that we can (and do) add arbitrary attributes to a DIE, but
   249  // only the ones actually listed in the Abbrev will be written out.
   250  func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr)
   251  
   252  // HasChildren reports whether 'die' uses an abbrev that supports children.
   253  func HasChildren(die *DWDie) bool
   254  
   255  // PutIntConst writes a DIE for an integer constant
   256  func PutIntConst(ctxt Context, info, typ Sym, name string, val int64)
   257  
   258  // PutGlobal writes a DIE for a global variable.
   259  func PutGlobal(ctxt Context, info, typ, gvar Sym, name string)
   260  
   261  // PutBasedRanges writes a range table to sym. All addresses in ranges are
   262  // relative to some base address, which must be arranged by the caller
   263  // (e.g., with a DW_AT_low_pc attribute, or in a BASE-prefixed range).
   264  func PutBasedRanges(ctxt Context, sym Sym, ranges []Range)
   265  
   266  // PutRanges writes a range table to s.Ranges.
   267  // All addresses in ranges are relative to s.base.
   268  func (s *FnState) PutRanges(ctxt Context, ranges []Range)
   269  
   270  // Emit DWARF attributes and child DIEs for an 'abstract' subprogram.
   271  // The abstract subprogram DIE for a function contains its
   272  // location-independent attributes (name, type, etc). Other instances
   273  // of the function (any inlined copy of it, or the single out-of-line
   274  // 'concrete' instance) will contain a pointer back to this abstract
   275  // DIE (as a space-saving measure, so that name/type etc doesn't have
   276  // to be repeated for each inlined copy).
   277  func PutAbstractFunc(ctxt Context, s *FnState) error
   278  
   279  // Emit DWARF attributes and child DIEs for a 'concrete' subprogram,
   280  // meaning the out-of-line copy of a function that was inlined at some
   281  // point during the compilation of its containing package. The first
   282  // attribute for a concrete DIE is a reference to the 'abstract' DIE
   283  // for the function (which holds location-independent attributes such
   284  // as name, type), then the remainder of the attributes are specific
   285  // to this instance (location, frame base, etc).
   286  func PutConcreteFunc(ctxt Context, s *FnState, isWrapper bool) error
   287  
   288  // Emit DWARF attributes and child DIEs for a subprogram. Here
   289  // 'default' implies that the function in question was not inlined
   290  // when its containing package was compiled (hence there is no need to
   291  // emit an abstract version for it to use as a base for inlined
   292  // routine records).
   293  func PutDefaultFunc(ctxt Context, s *FnState, isWrapper bool) error
   294  
   295  // IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
   296  // current extld.
   297  // AIX ld doesn't support DWARF with -bnoobjreorder with version
   298  // prior to 7.2.2.
   299  func IsDWARFEnabledOnAIXLd(extld []string) (bool, error)