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