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)