github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/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 "errors" 12 "fmt" 13 ) 14 15 // InfoPrefix is the prefix for all the symbols containing DWARF info entries. 16 const InfoPrefix = "go.info." 17 18 // RangePrefix is the prefix for all the symbols containing DWARF range lists. 19 const RangePrefix = "go.range." 20 21 // Sym represents a symbol. 22 type Sym interface { 23 Len() int64 24 } 25 26 // A Var represents a local variable or a function parameter. 27 type Var struct { 28 Name string 29 Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM 30 Offset int32 31 Scope int32 32 Type Sym 33 } 34 35 // A Scope represents a lexical scope. All variables declared within a 36 // scope will only be visible to instructions covered by the scope. 37 // Lexical scopes are contiguous in source files but can end up being 38 // compiled to discontiguous blocks of instructions in the executable. 39 // The Ranges field lists all the blocks of instructions that belong 40 // in this scope. 41 type Scope struct { 42 Parent int32 43 Ranges []Range 44 Vars []*Var 45 } 46 47 // A Range represents a half-open interval [Start, End). 48 type Range struct { 49 Start, End int64 50 } 51 52 // UnifyRanges merges the list of ranges of c into the list of ranges of s 53 func (s *Scope) UnifyRanges(c *Scope) { 54 out := make([]Range, 0, len(s.Ranges)+len(c.Ranges)) 55 56 i, j := 0, 0 57 for { 58 var cur Range 59 if i < len(s.Ranges) && j < len(c.Ranges) { 60 if s.Ranges[i].Start < c.Ranges[j].Start { 61 cur = s.Ranges[i] 62 i++ 63 } else { 64 cur = c.Ranges[j] 65 j++ 66 } 67 } else if i < len(s.Ranges) { 68 cur = s.Ranges[i] 69 i++ 70 } else if j < len(c.Ranges) { 71 cur = c.Ranges[j] 72 j++ 73 } else { 74 break 75 } 76 77 if n := len(out); n > 0 && cur.Start <= out[n-1].End { 78 out[n-1].End = cur.End 79 } else { 80 out = append(out, cur) 81 } 82 } 83 84 s.Ranges = out 85 } 86 87 // A Context specifies how to add data to a Sym. 88 type Context interface { 89 PtrSize() int 90 AddInt(s Sym, size int, i int64) 91 AddBytes(s Sym, b []byte) 92 AddAddress(s Sym, t interface{}, ofs int64) 93 AddSectionOffset(s Sym, size int, t interface{}, ofs int64) 94 AddString(s Sym, v string) 95 SymValue(s Sym) int64 96 } 97 98 // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding. 99 func AppendUleb128(b []byte, v uint64) []byte { 100 for { 101 c := uint8(v & 0x7f) 102 v >>= 7 103 if v != 0 { 104 c |= 0x80 105 } 106 b = append(b, c) 107 if c&0x80 == 0 { 108 break 109 } 110 } 111 return b 112 } 113 114 // AppendSleb128 appends v to b using DWARF's signed LEB128 encoding. 115 func AppendSleb128(b []byte, v int64) []byte { 116 for { 117 c := uint8(v & 0x7f) 118 s := uint8(v & 0x40) 119 v >>= 7 120 if (v != -1 || s == 0) && (v != 0 || s != 0) { 121 c |= 0x80 122 } 123 b = append(b, c) 124 if c&0x80 == 0 { 125 break 126 } 127 } 128 return b 129 } 130 131 // sevenbits contains all unsigned seven bit numbers, indexed by their value. 132 var sevenbits = [...]byte{ 133 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 134 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 135 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 136 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 137 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 138 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 139 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 140 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 141 } 142 143 // sevenBitU returns the unsigned LEB128 encoding of v if v is seven bits and nil otherwise. 144 // The contents of the returned slice must not be modified. 145 func sevenBitU(v int64) []byte { 146 if uint64(v) < uint64(len(sevenbits)) { 147 return sevenbits[v : v+1] 148 } 149 return nil 150 } 151 152 // sevenBitS returns the signed LEB128 encoding of v if v is seven bits and nil otherwise. 153 // The contents of the returned slice must not be modified. 154 func sevenBitS(v int64) []byte { 155 if uint64(v) <= 63 { 156 return sevenbits[v : v+1] 157 } 158 if uint64(-v) <= 64 { 159 return sevenbits[128+v : 128+v+1] 160 } 161 return nil 162 } 163 164 // Uleb128put appends v to s using DWARF's unsigned LEB128 encoding. 165 func Uleb128put(ctxt Context, s Sym, v int64) { 166 b := sevenBitU(v) 167 if b == nil { 168 var encbuf [20]byte 169 b = AppendUleb128(encbuf[:0], uint64(v)) 170 } 171 ctxt.AddBytes(s, b) 172 } 173 174 // Sleb128put appends v to s using DWARF's signed LEB128 encoding. 175 func Sleb128put(ctxt Context, s Sym, v int64) { 176 b := sevenBitS(v) 177 if b == nil { 178 var encbuf [20]byte 179 b = AppendSleb128(encbuf[:0], v) 180 } 181 ctxt.AddBytes(s, b) 182 } 183 184 /* 185 * Defining Abbrevs. This is hardcoded, and there will be 186 * only a handful of them. The DWARF spec places no restriction on 187 * the ordering of attributes in the Abbrevs and DIEs, and we will 188 * always write them out in the order of declaration in the abbrev. 189 */ 190 type dwAttrForm struct { 191 attr uint16 192 form uint8 193 } 194 195 // Go-specific type attributes. 196 const ( 197 DW_AT_go_kind = 0x2900 198 DW_AT_go_key = 0x2901 199 DW_AT_go_elem = 0x2902 200 // Attribute for DW_TAG_member of a struct type. 201 // Nonzero value indicates the struct field is an embedded field. 202 DW_AT_go_embedded_field = 0x2903 203 204 DW_AT_internal_location = 253 // params and locals; not emitted 205 ) 206 207 // Index into the abbrevs table below. 208 // Keep in sync with ispubname() and ispubtype() below. 209 // ispubtype considers >= NULLTYPE public 210 const ( 211 DW_ABRV_NULL = iota 212 DW_ABRV_COMPUNIT 213 DW_ABRV_FUNCTION 214 DW_ABRV_VARIABLE 215 DW_ABRV_AUTO 216 DW_ABRV_PARAM 217 DW_ABRV_LEXICAL_BLOCK_RANGES 218 DW_ABRV_LEXICAL_BLOCK_SIMPLE 219 DW_ABRV_STRUCTFIELD 220 DW_ABRV_FUNCTYPEPARAM 221 DW_ABRV_DOTDOTDOT 222 DW_ABRV_ARRAYRANGE 223 DW_ABRV_NULLTYPE 224 DW_ABRV_BASETYPE 225 DW_ABRV_ARRAYTYPE 226 DW_ABRV_CHANTYPE 227 DW_ABRV_FUNCTYPE 228 DW_ABRV_IFACETYPE 229 DW_ABRV_MAPTYPE 230 DW_ABRV_PTRTYPE 231 DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. 232 DW_ABRV_SLICETYPE 233 DW_ABRV_STRINGTYPE 234 DW_ABRV_STRUCTTYPE 235 DW_ABRV_TYPEDECL 236 DW_NABRV 237 ) 238 239 type dwAbbrev struct { 240 tag uint8 241 children uint8 242 attr []dwAttrForm 243 } 244 245 var abbrevs = [DW_NABRV]dwAbbrev{ 246 /* The mandatory DW_ABRV_NULL entry. */ 247 {0, 0, []dwAttrForm{}}, 248 249 /* COMPUNIT */ 250 { 251 DW_TAG_compile_unit, 252 DW_CHILDREN_yes, 253 []dwAttrForm{ 254 {DW_AT_name, DW_FORM_string}, 255 {DW_AT_language, DW_FORM_data1}, 256 {DW_AT_low_pc, DW_FORM_addr}, 257 {DW_AT_high_pc, DW_FORM_addr}, 258 {DW_AT_stmt_list, DW_FORM_sec_offset}, 259 {DW_AT_comp_dir, DW_FORM_string}, 260 {DW_AT_producer, DW_FORM_string}, 261 }, 262 }, 263 264 /* FUNCTION */ 265 { 266 DW_TAG_subprogram, 267 DW_CHILDREN_yes, 268 []dwAttrForm{ 269 {DW_AT_name, DW_FORM_string}, 270 {DW_AT_low_pc, DW_FORM_addr}, 271 {DW_AT_high_pc, DW_FORM_addr}, 272 {DW_AT_frame_base, DW_FORM_block1}, 273 {DW_AT_external, DW_FORM_flag}, 274 }, 275 }, 276 277 /* VARIABLE */ 278 { 279 DW_TAG_variable, 280 DW_CHILDREN_no, 281 []dwAttrForm{ 282 {DW_AT_name, DW_FORM_string}, 283 {DW_AT_location, DW_FORM_block1}, 284 {DW_AT_type, DW_FORM_ref_addr}, 285 {DW_AT_external, DW_FORM_flag}, 286 }, 287 }, 288 289 /* AUTO */ 290 { 291 DW_TAG_variable, 292 DW_CHILDREN_no, 293 []dwAttrForm{ 294 {DW_AT_name, DW_FORM_string}, 295 {DW_AT_location, DW_FORM_block1}, 296 {DW_AT_type, DW_FORM_ref_addr}, 297 }, 298 }, 299 300 /* PARAM */ 301 { 302 DW_TAG_formal_parameter, 303 DW_CHILDREN_no, 304 []dwAttrForm{ 305 {DW_AT_name, DW_FORM_string}, 306 {DW_AT_location, DW_FORM_block1}, 307 {DW_AT_type, DW_FORM_ref_addr}, 308 }, 309 }, 310 /* LEXICAL_BLOCK_RANGES */ 311 { 312 DW_TAG_lexical_block, 313 DW_CHILDREN_yes, 314 []dwAttrForm{ 315 {DW_AT_ranges, DW_FORM_sec_offset}, 316 }, 317 }, 318 319 /* LEXICAL_BLOCK_SIMPLE */ 320 { 321 DW_TAG_lexical_block, 322 DW_CHILDREN_yes, 323 []dwAttrForm{ 324 {DW_AT_low_pc, DW_FORM_addr}, 325 {DW_AT_high_pc, DW_FORM_addr}, 326 }, 327 }, 328 329 /* STRUCTFIELD */ 330 { 331 DW_TAG_member, 332 DW_CHILDREN_no, 333 []dwAttrForm{ 334 {DW_AT_name, DW_FORM_string}, 335 {DW_AT_data_member_location, DW_FORM_block1}, 336 {DW_AT_type, DW_FORM_ref_addr}, 337 {DW_AT_go_embedded_field, DW_FORM_flag}, 338 }, 339 }, 340 341 /* FUNCTYPEPARAM */ 342 { 343 DW_TAG_formal_parameter, 344 DW_CHILDREN_no, 345 346 // No name! 347 []dwAttrForm{ 348 {DW_AT_type, DW_FORM_ref_addr}, 349 }, 350 }, 351 352 /* DOTDOTDOT */ 353 { 354 DW_TAG_unspecified_parameters, 355 DW_CHILDREN_no, 356 []dwAttrForm{}, 357 }, 358 359 /* ARRAYRANGE */ 360 { 361 DW_TAG_subrange_type, 362 DW_CHILDREN_no, 363 364 // No name! 365 []dwAttrForm{ 366 {DW_AT_type, DW_FORM_ref_addr}, 367 {DW_AT_count, DW_FORM_udata}, 368 }, 369 }, 370 371 // Below here are the types considered public by ispubtype 372 /* NULLTYPE */ 373 { 374 DW_TAG_unspecified_type, 375 DW_CHILDREN_no, 376 []dwAttrForm{ 377 {DW_AT_name, DW_FORM_string}, 378 }, 379 }, 380 381 /* BASETYPE */ 382 { 383 DW_TAG_base_type, 384 DW_CHILDREN_no, 385 []dwAttrForm{ 386 {DW_AT_name, DW_FORM_string}, 387 {DW_AT_encoding, DW_FORM_data1}, 388 {DW_AT_byte_size, DW_FORM_data1}, 389 {DW_AT_go_kind, DW_FORM_data1}, 390 }, 391 }, 392 393 /* ARRAYTYPE */ 394 // child is subrange with upper bound 395 { 396 DW_TAG_array_type, 397 DW_CHILDREN_yes, 398 []dwAttrForm{ 399 {DW_AT_name, DW_FORM_string}, 400 {DW_AT_type, DW_FORM_ref_addr}, 401 {DW_AT_byte_size, DW_FORM_udata}, 402 {DW_AT_go_kind, DW_FORM_data1}, 403 }, 404 }, 405 406 /* CHANTYPE */ 407 { 408 DW_TAG_typedef, 409 DW_CHILDREN_no, 410 []dwAttrForm{ 411 {DW_AT_name, DW_FORM_string}, 412 {DW_AT_type, DW_FORM_ref_addr}, 413 {DW_AT_go_kind, DW_FORM_data1}, 414 {DW_AT_go_elem, DW_FORM_ref_addr}, 415 }, 416 }, 417 418 /* FUNCTYPE */ 419 { 420 DW_TAG_subroutine_type, 421 DW_CHILDREN_yes, 422 []dwAttrForm{ 423 {DW_AT_name, DW_FORM_string}, 424 // {DW_AT_type, DW_FORM_ref_addr}, 425 {DW_AT_go_kind, DW_FORM_data1}, 426 }, 427 }, 428 429 /* IFACETYPE */ 430 { 431 DW_TAG_typedef, 432 DW_CHILDREN_yes, 433 []dwAttrForm{ 434 {DW_AT_name, DW_FORM_string}, 435 {DW_AT_type, DW_FORM_ref_addr}, 436 {DW_AT_go_kind, DW_FORM_data1}, 437 }, 438 }, 439 440 /* MAPTYPE */ 441 { 442 DW_TAG_typedef, 443 DW_CHILDREN_no, 444 []dwAttrForm{ 445 {DW_AT_name, DW_FORM_string}, 446 {DW_AT_type, DW_FORM_ref_addr}, 447 {DW_AT_go_kind, DW_FORM_data1}, 448 {DW_AT_go_key, DW_FORM_ref_addr}, 449 {DW_AT_go_elem, DW_FORM_ref_addr}, 450 }, 451 }, 452 453 /* PTRTYPE */ 454 { 455 DW_TAG_pointer_type, 456 DW_CHILDREN_no, 457 []dwAttrForm{ 458 {DW_AT_name, DW_FORM_string}, 459 {DW_AT_type, DW_FORM_ref_addr}, 460 {DW_AT_go_kind, DW_FORM_data1}, 461 }, 462 }, 463 464 /* BARE_PTRTYPE */ 465 { 466 DW_TAG_pointer_type, 467 DW_CHILDREN_no, 468 []dwAttrForm{ 469 {DW_AT_name, DW_FORM_string}, 470 }, 471 }, 472 473 /* SLICETYPE */ 474 { 475 DW_TAG_structure_type, 476 DW_CHILDREN_yes, 477 []dwAttrForm{ 478 {DW_AT_name, DW_FORM_string}, 479 {DW_AT_byte_size, DW_FORM_udata}, 480 {DW_AT_go_kind, DW_FORM_data1}, 481 {DW_AT_go_elem, DW_FORM_ref_addr}, 482 }, 483 }, 484 485 /* STRINGTYPE */ 486 { 487 DW_TAG_structure_type, 488 DW_CHILDREN_yes, 489 []dwAttrForm{ 490 {DW_AT_name, DW_FORM_string}, 491 {DW_AT_byte_size, DW_FORM_udata}, 492 {DW_AT_go_kind, DW_FORM_data1}, 493 }, 494 }, 495 496 /* STRUCTTYPE */ 497 { 498 DW_TAG_structure_type, 499 DW_CHILDREN_yes, 500 []dwAttrForm{ 501 {DW_AT_name, DW_FORM_string}, 502 {DW_AT_byte_size, DW_FORM_udata}, 503 {DW_AT_go_kind, DW_FORM_data1}, 504 }, 505 }, 506 507 /* TYPEDECL */ 508 { 509 DW_TAG_typedef, 510 DW_CHILDREN_no, 511 []dwAttrForm{ 512 {DW_AT_name, DW_FORM_string}, 513 {DW_AT_type, DW_FORM_ref_addr}, 514 }, 515 }, 516 } 517 518 // GetAbbrev returns the contents of the .debug_abbrev section. 519 func GetAbbrev() []byte { 520 var buf []byte 521 for i := 1; i < DW_NABRV; i++ { 522 // See section 7.5.3 523 buf = AppendUleb128(buf, uint64(i)) 524 buf = AppendUleb128(buf, uint64(abbrevs[i].tag)) 525 buf = append(buf, byte(abbrevs[i].children)) 526 for _, f := range abbrevs[i].attr { 527 buf = AppendUleb128(buf, uint64(f.attr)) 528 buf = AppendUleb128(buf, uint64(f.form)) 529 } 530 buf = append(buf, 0, 0) 531 } 532 return append(buf, 0) 533 } 534 535 /* 536 * Debugging Information Entries and their attributes. 537 */ 538 539 // DWAttr represents an attribute of a DWDie. 540 // 541 // For DW_CLS_string and _block, value should contain the length, and 542 // data the data, for _reference, value is 0 and data is a DWDie* to 543 // the referenced instance, for all others, value is the whole thing 544 // and data is null. 545 type DWAttr struct { 546 Link *DWAttr 547 Atr uint16 // DW_AT_ 548 Cls uint8 // DW_CLS_ 549 Value int64 550 Data interface{} 551 } 552 553 // DWDie represents a DWARF debug info entry. 554 type DWDie struct { 555 Abbrev int 556 Link *DWDie 557 Child *DWDie 558 Attr *DWAttr 559 Sym Sym 560 } 561 562 func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error { 563 switch form { 564 case DW_FORM_addr: // address 565 ctxt.AddAddress(s, data, value) 566 567 case DW_FORM_block1: // block 568 if cls == DW_CLS_ADDRESS { 569 ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize())) 570 ctxt.AddInt(s, 1, DW_OP_addr) 571 ctxt.AddAddress(s, data, 0) 572 break 573 } 574 575 value &= 0xff 576 ctxt.AddInt(s, 1, value) 577 p := data.([]byte)[:value] 578 ctxt.AddBytes(s, p) 579 580 case DW_FORM_block2: // block 581 value &= 0xffff 582 583 ctxt.AddInt(s, 2, value) 584 p := data.([]byte)[:value] 585 ctxt.AddBytes(s, p) 586 587 case DW_FORM_block4: // block 588 value &= 0xffffffff 589 590 ctxt.AddInt(s, 4, value) 591 p := data.([]byte)[:value] 592 ctxt.AddBytes(s, p) 593 594 case DW_FORM_block: // block 595 Uleb128put(ctxt, s, value) 596 597 p := data.([]byte)[:value] 598 ctxt.AddBytes(s, p) 599 600 case DW_FORM_data1: // constant 601 ctxt.AddInt(s, 1, value) 602 603 case DW_FORM_data2: // constant 604 ctxt.AddInt(s, 2, value) 605 606 case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr 607 if cls == DW_CLS_PTR { // DW_AT_stmt_list and DW_AT_ranges 608 ctxt.AddSectionOffset(s, 4, data, value) 609 break 610 } 611 ctxt.AddInt(s, 4, value) 612 613 case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr 614 ctxt.AddInt(s, 8, value) 615 616 case DW_FORM_sdata: // constant 617 Sleb128put(ctxt, s, value) 618 619 case DW_FORM_udata: // constant 620 Uleb128put(ctxt, s, value) 621 622 case DW_FORM_string: // string 623 str := data.(string) 624 ctxt.AddString(s, str) 625 // TODO(ribrdb): verify padded strings are never used and remove this 626 for i := int64(len(str)); i < value; i++ { 627 ctxt.AddInt(s, 1, 0) 628 } 629 630 case DW_FORM_flag: // flag 631 if value != 0 { 632 ctxt.AddInt(s, 1, 1) 633 } else { 634 ctxt.AddInt(s, 1, 0) 635 } 636 637 // As of DWARF 3 the ref_addr is always 32 bits, unless emitting a large 638 // (> 4 GB of debug info aka "64-bit") unit, which we don't implement. 639 case DW_FORM_ref_addr: // reference to a DIE in the .info section 640 fallthrough 641 case DW_FORM_sec_offset: // offset into a DWARF section other than .info 642 if data == nil { 643 return fmt.Errorf("dwarf: null reference in %d", abbrev) 644 } 645 ctxt.AddSectionOffset(s, 4, data, value) 646 647 case DW_FORM_ref1, // reference within the compilation unit 648 DW_FORM_ref2, // reference 649 DW_FORM_ref4, // reference 650 DW_FORM_ref8, // reference 651 DW_FORM_ref_udata, // reference 652 653 DW_FORM_strp, // string 654 DW_FORM_indirect: // (see Section 7.5.3) 655 fallthrough 656 default: 657 return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls) 658 } 659 return nil 660 } 661 662 // PutAttrs writes the attributes for a DIE to symbol 's'. 663 // 664 // Note that we can (and do) add arbitrary attributes to a DIE, but 665 // only the ones actually listed in the Abbrev will be written out. 666 func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) { 667 Outer: 668 for _, f := range abbrevs[abbrev].attr { 669 for ap := attr; ap != nil; ap = ap.Link { 670 if ap.Atr == f.attr { 671 putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data) 672 continue Outer 673 } 674 } 675 676 putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil) 677 } 678 } 679 680 // HasChildren returns true if 'die' uses an abbrev that supports children. 681 func HasChildren(die *DWDie) bool { 682 return abbrevs[die.Abbrev].children != 0 683 } 684 685 // PutFunc writes a DIE for a function to s. 686 // It also writes child DIEs for each variable in vars. 687 func PutFunc(ctxt Context, s, ranges Sym, name string, external bool, startPC Sym, size int64, scopes []Scope) error { 688 Uleb128put(ctxt, s, DW_ABRV_FUNCTION) 689 putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name) 690 putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC) 691 putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size, startPC) 692 putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa}) 693 var ev int64 694 if external { 695 ev = 1 696 } 697 putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0) 698 if len(scopes) > 0 { 699 var encbuf [20]byte 700 if putscope(ctxt, s, ranges, startPC, 0, scopes, encbuf[:0]) < int32(len(scopes)) { 701 return errors.New("multiple toplevel scopes") 702 } 703 } 704 705 Uleb128put(ctxt, s, 0) 706 return nil 707 } 708 709 func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes []Scope, encbuf []byte) int32 { 710 for _, v := range scopes[curscope].Vars { 711 putvar(ctxt, s, v, encbuf) 712 } 713 this := curscope 714 curscope++ 715 for curscope < int32(len(scopes)) { 716 scope := scopes[curscope] 717 if scope.Parent != this { 718 return curscope 719 } 720 721 if len(scope.Ranges) == 1 { 722 Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE) 723 putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, startPC) 724 putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, startPC) 725 } else { 726 Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES) 727 putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, ranges.Len(), ranges) 728 729 ctxt.AddAddress(ranges, nil, -1) 730 ctxt.AddAddress(ranges, startPC, 0) 731 for _, r := range scope.Ranges { 732 ctxt.AddAddress(ranges, nil, r.Start) 733 ctxt.AddAddress(ranges, nil, r.End) 734 } 735 ctxt.AddAddress(ranges, nil, 0) 736 ctxt.AddAddress(ranges, nil, 0) 737 } 738 739 curscope = putscope(ctxt, s, ranges, startPC, curscope, scopes, encbuf) 740 741 Uleb128put(ctxt, s, 0) 742 } 743 return curscope 744 } 745 746 func putvar(ctxt Context, s Sym, v *Var, encbuf []byte) { 747 n := v.Name 748 749 Uleb128put(ctxt, s, int64(v.Abbrev)) 750 putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n) 751 loc := append(encbuf[:0], DW_OP_call_frame_cfa) 752 if v.Offset != 0 { 753 loc = append(loc, DW_OP_consts) 754 loc = AppendSleb128(loc, int64(v.Offset)) 755 loc = append(loc, DW_OP_plus) 756 } 757 putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc) 758 putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type) 759 } 760 761 // VarsByOffset attaches the methods of sort.Interface to []*Var, 762 // sorting in increasing Offset. 763 type VarsByOffset []*Var 764 765 func (s VarsByOffset) Len() int { return len(s) } 766 func (s VarsByOffset) Less(i, j int) bool { return s[i].Offset < s[j].Offset } 767 func (s VarsByOffset) Swap(i, j int) { s[i], s[j] = s[j], s[i] }