github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/cmd/link/internal/ld/dwarf.go (about) 1 // Copyright 2010 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 // TODO/NICETOHAVE: 6 // - eliminate DW_CLS_ if not used 7 // - package info in compilation units 8 // - assign global variables and types to their packages 9 // - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg 10 // ptype struct '[]uint8' and qualifiers need to be quoted away 11 // - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean. 12 // - file:line info for variables 13 // - make strings a typedef so prettyprinters can see the underlying string type 14 15 package ld 16 17 import ( 18 "cmd/internal/obj" 19 "fmt" 20 "os" 21 "strings" 22 ) 23 24 /* 25 * Offsets and sizes of the debug_* sections in the cout file. 26 */ 27 var abbrevo int64 28 29 var abbrevsize int64 30 31 var abbrevsym *LSym 32 33 var abbrevsympos int64 34 35 var lineo int64 36 37 var linesize int64 38 39 var linesym *LSym 40 41 var linesympos int64 42 43 var infoo int64 // also the base for DWDie->offs and reference attributes. 44 45 var infosize int64 46 47 var infosym *LSym 48 49 var infosympos int64 50 51 var frameo int64 52 53 var framesize int64 54 55 var framesym *LSym 56 57 var framesympos int64 58 59 var pubnameso int64 60 61 var pubnamessize int64 62 63 var pubtypeso int64 64 65 var pubtypessize int64 66 67 var arangeso int64 68 69 var arangessize int64 70 71 var gdbscripto int64 72 73 var gdbscriptsize int64 74 75 var infosec *LSym 76 77 var inforeloco int64 78 79 var inforelocsize int64 80 81 var arangessec *LSym 82 83 var arangesreloco int64 84 85 var arangesrelocsize int64 86 87 var linesec *LSym 88 89 var linereloco int64 90 91 var linerelocsize int64 92 93 var framesec *LSym 94 95 var framereloco int64 96 97 var framerelocsize int64 98 99 var gdbscript string 100 101 /* 102 * Basic I/O 103 */ 104 func addrput(addr int64) { 105 switch Thearch.Ptrsize { 106 case 4: 107 Thearch.Lput(uint32(addr)) 108 109 case 8: 110 Thearch.Vput(uint64(addr)) 111 } 112 } 113 114 func uleb128enc(v uint64, dst []byte) int { 115 var c uint8 116 117 length := uint8(0) 118 for { 119 c = uint8(v & 0x7f) 120 v >>= 7 121 if v != 0 { 122 c |= 0x80 123 } 124 if dst != nil { 125 dst[0] = byte(c) 126 dst = dst[1:] 127 } 128 length++ 129 if c&0x80 == 0 { 130 break 131 } 132 } 133 134 return int(length) 135 } 136 137 func sleb128enc(v int64, dst []byte) int { 138 var c uint8 139 var s uint8 140 141 length := uint8(0) 142 for { 143 c = uint8(v & 0x7f) 144 s = uint8(v & 0x40) 145 v >>= 7 146 if (v != -1 || s == 0) && (v != 0 || s != 0) { 147 c |= 0x80 148 } 149 if dst != nil { 150 dst[0] = byte(c) 151 dst = dst[1:] 152 } 153 length++ 154 if c&0x80 == 0 { 155 break 156 } 157 } 158 159 return int(length) 160 } 161 162 var encbuf [10]byte 163 164 func uleb128put(v int64) { 165 n := uleb128enc(uint64(v), encbuf[:]) 166 Cwrite(encbuf[:n]) 167 } 168 169 func sleb128put(v int64) { 170 n := sleb128enc(v, encbuf[:]) 171 Cwrite(encbuf[:n]) 172 } 173 174 /* 175 * Defining Abbrevs. This is hardcoded, and there will be 176 * only a handful of them. The DWARF spec places no restriction on 177 * the ordering of attributes in the Abbrevs and DIEs, and we will 178 * always write them out in the order of declaration in the abbrev. 179 */ 180 type DWAttrForm struct { 181 attr uint16 182 form uint8 183 } 184 185 // Go-specific type attributes. 186 const ( 187 DW_AT_go_kind = 0x2900 188 DW_AT_go_key = 0x2901 189 DW_AT_go_elem = 0x2902 190 191 DW_AT_internal_location = 253 // params and locals; not emitted 192 ) 193 194 // Index into the abbrevs table below. 195 // Keep in sync with ispubname() and ispubtype() below. 196 // ispubtype considers >= NULLTYPE public 197 const ( 198 DW_ABRV_NULL = iota 199 DW_ABRV_COMPUNIT 200 DW_ABRV_FUNCTION 201 DW_ABRV_VARIABLE 202 DW_ABRV_AUTO 203 DW_ABRV_PARAM 204 DW_ABRV_STRUCTFIELD 205 DW_ABRV_FUNCTYPEPARAM 206 DW_ABRV_DOTDOTDOT 207 DW_ABRV_ARRAYRANGE 208 DW_ABRV_NULLTYPE 209 DW_ABRV_BASETYPE 210 DW_ABRV_ARRAYTYPE 211 DW_ABRV_CHANTYPE 212 DW_ABRV_FUNCTYPE 213 DW_ABRV_IFACETYPE 214 DW_ABRV_MAPTYPE 215 DW_ABRV_PTRTYPE 216 DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. 217 DW_ABRV_SLICETYPE 218 DW_ABRV_STRINGTYPE 219 DW_ABRV_STRUCTTYPE 220 DW_ABRV_TYPEDECL 221 DW_NABRV 222 ) 223 224 type DWAbbrev struct { 225 tag uint8 226 children uint8 227 attr []DWAttrForm 228 } 229 230 var abbrevs = [DW_NABRV]DWAbbrev{ 231 /* The mandatory DW_ABRV_NULL entry. */ 232 {0, 0, []DWAttrForm{}}, 233 234 /* COMPUNIT */ 235 { 236 DW_TAG_compile_unit, 237 DW_CHILDREN_yes, 238 []DWAttrForm{ 239 {DW_AT_name, DW_FORM_string}, 240 {DW_AT_language, DW_FORM_data1}, 241 {DW_AT_low_pc, DW_FORM_addr}, 242 {DW_AT_high_pc, DW_FORM_addr}, 243 {DW_AT_stmt_list, DW_FORM_data4}, 244 {DW_AT_comp_dir, DW_FORM_string}, 245 }, 246 }, 247 248 /* FUNCTION */ 249 { 250 DW_TAG_subprogram, 251 DW_CHILDREN_yes, 252 []DWAttrForm{ 253 {DW_AT_name, DW_FORM_string}, 254 {DW_AT_low_pc, DW_FORM_addr}, 255 {DW_AT_high_pc, DW_FORM_addr}, 256 {DW_AT_external, DW_FORM_flag}, 257 }, 258 }, 259 260 /* VARIABLE */ 261 { 262 DW_TAG_variable, 263 DW_CHILDREN_no, 264 []DWAttrForm{ 265 {DW_AT_name, DW_FORM_string}, 266 {DW_AT_location, DW_FORM_block1}, 267 {DW_AT_type, DW_FORM_ref_addr}, 268 {DW_AT_external, DW_FORM_flag}, 269 }, 270 }, 271 272 /* AUTO */ 273 { 274 DW_TAG_variable, 275 DW_CHILDREN_no, 276 []DWAttrForm{ 277 {DW_AT_name, DW_FORM_string}, 278 {DW_AT_location, DW_FORM_block1}, 279 {DW_AT_type, DW_FORM_ref_addr}, 280 }, 281 }, 282 283 /* PARAM */ 284 { 285 DW_TAG_formal_parameter, 286 DW_CHILDREN_no, 287 []DWAttrForm{ 288 {DW_AT_name, DW_FORM_string}, 289 {DW_AT_location, DW_FORM_block1}, 290 {DW_AT_type, DW_FORM_ref_addr}, 291 }, 292 }, 293 294 /* STRUCTFIELD */ 295 { 296 DW_TAG_member, 297 DW_CHILDREN_no, 298 []DWAttrForm{ 299 {DW_AT_name, DW_FORM_string}, 300 {DW_AT_data_member_location, DW_FORM_block1}, 301 {DW_AT_type, DW_FORM_ref_addr}, 302 }, 303 }, 304 305 /* FUNCTYPEPARAM */ 306 { 307 DW_TAG_formal_parameter, 308 DW_CHILDREN_no, 309 310 // No name! 311 []DWAttrForm{ 312 {DW_AT_type, DW_FORM_ref_addr}, 313 }, 314 }, 315 316 /* DOTDOTDOT */ 317 { 318 DW_TAG_unspecified_parameters, 319 DW_CHILDREN_no, 320 []DWAttrForm{}, 321 }, 322 323 /* ARRAYRANGE */ 324 { 325 DW_TAG_subrange_type, 326 DW_CHILDREN_no, 327 328 // No name! 329 []DWAttrForm{ 330 {DW_AT_type, DW_FORM_ref_addr}, 331 {DW_AT_count, DW_FORM_udata}, 332 }, 333 }, 334 335 // Below here are the types considered public by ispubtype 336 /* NULLTYPE */ 337 { 338 DW_TAG_unspecified_type, 339 DW_CHILDREN_no, 340 []DWAttrForm{ 341 {DW_AT_name, DW_FORM_string}, 342 }, 343 }, 344 345 /* BASETYPE */ 346 { 347 DW_TAG_base_type, 348 DW_CHILDREN_no, 349 []DWAttrForm{ 350 {DW_AT_name, DW_FORM_string}, 351 {DW_AT_encoding, DW_FORM_data1}, 352 {DW_AT_byte_size, DW_FORM_data1}, 353 {DW_AT_go_kind, DW_FORM_data1}, 354 }, 355 }, 356 357 /* ARRAYTYPE */ 358 // child is subrange with upper bound 359 { 360 DW_TAG_array_type, 361 DW_CHILDREN_yes, 362 []DWAttrForm{ 363 {DW_AT_name, DW_FORM_string}, 364 {DW_AT_type, DW_FORM_ref_addr}, 365 {DW_AT_byte_size, DW_FORM_udata}, 366 {DW_AT_go_kind, DW_FORM_data1}, 367 }, 368 }, 369 370 /* CHANTYPE */ 371 { 372 DW_TAG_typedef, 373 DW_CHILDREN_no, 374 []DWAttrForm{ 375 {DW_AT_name, DW_FORM_string}, 376 {DW_AT_type, DW_FORM_ref_addr}, 377 {DW_AT_go_kind, DW_FORM_data1}, 378 {DW_AT_go_elem, DW_FORM_ref_addr}, 379 }, 380 }, 381 382 /* FUNCTYPE */ 383 { 384 DW_TAG_subroutine_type, 385 DW_CHILDREN_yes, 386 []DWAttrForm{ 387 {DW_AT_name, DW_FORM_string}, 388 // {DW_AT_type, DW_FORM_ref_addr}, 389 {DW_AT_go_kind, DW_FORM_data1}, 390 }, 391 }, 392 393 /* IFACETYPE */ 394 { 395 DW_TAG_typedef, 396 DW_CHILDREN_yes, 397 []DWAttrForm{ 398 {DW_AT_name, DW_FORM_string}, 399 {DW_AT_type, DW_FORM_ref_addr}, 400 {DW_AT_go_kind, DW_FORM_data1}, 401 }, 402 }, 403 404 /* MAPTYPE */ 405 { 406 DW_TAG_typedef, 407 DW_CHILDREN_no, 408 []DWAttrForm{ 409 {DW_AT_name, DW_FORM_string}, 410 {DW_AT_type, DW_FORM_ref_addr}, 411 {DW_AT_go_kind, DW_FORM_data1}, 412 {DW_AT_go_key, DW_FORM_ref_addr}, 413 {DW_AT_go_elem, DW_FORM_ref_addr}, 414 }, 415 }, 416 417 /* PTRTYPE */ 418 { 419 DW_TAG_pointer_type, 420 DW_CHILDREN_no, 421 []DWAttrForm{ 422 {DW_AT_name, DW_FORM_string}, 423 {DW_AT_type, DW_FORM_ref_addr}, 424 {DW_AT_go_kind, DW_FORM_data1}, 425 }, 426 }, 427 428 /* BARE_PTRTYPE */ 429 { 430 DW_TAG_pointer_type, 431 DW_CHILDREN_no, 432 []DWAttrForm{ 433 {DW_AT_name, DW_FORM_string}, 434 }, 435 }, 436 437 /* SLICETYPE */ 438 { 439 DW_TAG_structure_type, 440 DW_CHILDREN_yes, 441 []DWAttrForm{ 442 {DW_AT_name, DW_FORM_string}, 443 {DW_AT_byte_size, DW_FORM_udata}, 444 {DW_AT_go_kind, DW_FORM_data1}, 445 {DW_AT_go_elem, DW_FORM_ref_addr}, 446 }, 447 }, 448 449 /* STRINGTYPE */ 450 { 451 DW_TAG_structure_type, 452 DW_CHILDREN_yes, 453 []DWAttrForm{ 454 {DW_AT_name, DW_FORM_string}, 455 {DW_AT_byte_size, DW_FORM_udata}, 456 {DW_AT_go_kind, DW_FORM_data1}, 457 }, 458 }, 459 460 /* STRUCTTYPE */ 461 { 462 DW_TAG_structure_type, 463 DW_CHILDREN_yes, 464 []DWAttrForm{ 465 {DW_AT_name, DW_FORM_string}, 466 {DW_AT_byte_size, DW_FORM_udata}, 467 {DW_AT_go_kind, DW_FORM_data1}, 468 }, 469 }, 470 471 /* TYPEDECL */ 472 { 473 DW_TAG_typedef, 474 DW_CHILDREN_no, 475 []DWAttrForm{ 476 {DW_AT_name, DW_FORM_string}, 477 {DW_AT_type, DW_FORM_ref_addr}, 478 }, 479 }, 480 } 481 482 func writeabbrev() { 483 abbrevo = Cpos() 484 for i := 1; i < DW_NABRV; i++ { 485 // See section 7.5.3 486 uleb128put(int64(i)) 487 488 uleb128put(int64(abbrevs[i].tag)) 489 Cput(abbrevs[i].children) 490 for _, f := range abbrevs[i].attr { 491 uleb128put(int64(f.attr)) 492 uleb128put(int64(f.form)) 493 } 494 uleb128put(0) 495 uleb128put(0) 496 } 497 498 Cput(0) 499 abbrevsize = Cpos() - abbrevo 500 } 501 502 /* 503 * Debugging Information Entries and their attributes. 504 */ 505 const ( 506 HASHSIZE = 107 507 ) 508 509 func dwarfhashstr(s string) uint32 { 510 h := uint32(0) 511 for s != "" { 512 h = h + h + h + uint32(s[0]) 513 s = s[1:] 514 } 515 return h % HASHSIZE 516 } 517 518 // For DW_CLS_string and _block, value should contain the length, and 519 // data the data, for _reference, value is 0 and data is a DWDie* to 520 // the referenced instance, for all others, value is the whole thing 521 // and data is null. 522 523 type DWAttr struct { 524 link *DWAttr 525 atr uint16 // DW_AT_ 526 cls uint8 // DW_CLS_ 527 value int64 528 data interface{} 529 } 530 531 type DWDie struct { 532 abbrev int 533 link *DWDie 534 child *DWDie 535 attr *DWAttr 536 // offset into .debug_info section, i.e relative to 537 // infoo. only valid after call to putdie() 538 offs int64 539 hash []*DWDie // optional index of children by name, enabled by mkindex() 540 hlink *DWDie // bucket chain in parent's index 541 } 542 543 /* 544 * Root DIEs for compilation units, types and global variables. 545 */ 546 var dwroot DWDie 547 548 var dwtypes DWDie 549 550 var dwglobals DWDie 551 552 func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr { 553 a := new(DWAttr) 554 a.link = die.attr 555 die.attr = a 556 a.atr = attr 557 a.cls = uint8(cls) 558 a.value = value 559 a.data = data 560 return a 561 } 562 563 // Each DIE (except the root ones) has at least 1 attribute: its 564 // name. getattr moves the desired one to the front so 565 // frequently searched ones are found faster. 566 func getattr(die *DWDie, attr uint16) *DWAttr { 567 if die.attr.atr == attr { 568 return die.attr 569 } 570 571 a := die.attr 572 b := a.link 573 for b != nil { 574 if b.atr == attr { 575 a.link = b.link 576 b.link = die.attr 577 die.attr = b 578 return b 579 } 580 581 a = b 582 b = b.link 583 } 584 585 return nil 586 } 587 588 // Every DIE has at least a DW_AT_name attribute (but it will only be 589 // written out if it is listed in the abbrev). If its parent is 590 // keeping an index, the new DIE will be inserted there. 591 func newdie(parent *DWDie, abbrev int, name string) *DWDie { 592 die := new(DWDie) 593 die.abbrev = abbrev 594 die.link = parent.child 595 parent.child = die 596 597 newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name) 598 599 if parent.hash != nil { 600 h := int(dwarfhashstr(name)) 601 die.hlink = parent.hash[h] 602 parent.hash[h] = die 603 } 604 605 return die 606 } 607 608 func mkindex(die *DWDie) { 609 die.hash = make([]*DWDie, HASHSIZE) 610 } 611 612 func walktypedef(die *DWDie) *DWDie { 613 // Resolve typedef if present. 614 if die.abbrev == DW_ABRV_TYPEDECL { 615 for attr := die.attr; attr != nil; attr = attr.link { 616 if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil { 617 return attr.data.(*DWDie) 618 } 619 } 620 } 621 622 return die 623 } 624 625 // Find child by AT_name using hashtable if available or linear scan 626 // if not. 627 func find(die *DWDie, name string) *DWDie { 628 var a *DWDie 629 var b *DWDie 630 var die2 *DWDie 631 var h int 632 633 top: 634 if die.hash == nil { 635 for a = die.child; a != nil; a = a.link { 636 if name == getattr(a, DW_AT_name).data { 637 return a 638 } 639 } 640 goto notfound 641 } 642 643 h = int(dwarfhashstr(name)) 644 a = die.hash[h] 645 646 if a == nil { 647 goto notfound 648 } 649 650 if name == getattr(a, DW_AT_name).data { 651 return a 652 } 653 654 // Move found ones to head of the list. 655 b = a.hlink 656 657 for b != nil { 658 if name == getattr(b, DW_AT_name).data { 659 a.hlink = b.hlink 660 b.hlink = die.hash[h] 661 die.hash[h] = b 662 return b 663 } 664 665 a = b 666 b = b.hlink 667 } 668 669 notfound: 670 die2 = walktypedef(die) 671 if die2 != die { 672 die = die2 673 goto top 674 } 675 676 return nil 677 } 678 679 func mustFind(die *DWDie, name string) *DWDie { 680 r := find(die, name) 681 if r == nil { 682 Exitf("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name) 683 } 684 return r 685 } 686 687 func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64) { 688 r := Addrel(sec) 689 r.Sym = sym 690 r.Xsym = sym 691 r.Off = int32(Cpos() - offsetbase) 692 r.Siz = uint8(siz) 693 r.Type = obj.R_ADDR 694 r.Add = addend 695 r.Xadd = addend 696 if Iself && Thearch.Thechar == '6' { 697 addend = 0 698 } 699 if HEADTYPE == obj.Hdarwin { 700 addend += sym.Value 701 } 702 switch siz { 703 case 4: 704 Thearch.Lput(uint32(addend)) 705 706 case 8: 707 Thearch.Vput(uint64(addend)) 708 709 default: 710 Diag("bad size in adddwarfrel") 711 } 712 } 713 714 func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr { 715 if ref == nil { 716 return nil 717 } 718 return newattr(die, attr, DW_CLS_REFERENCE, 0, ref) 719 } 720 721 var fwdcount int 722 723 func putattr(abbrev int, form int, cls int, value int64, data interface{}) { 724 switch form { 725 case DW_FORM_addr: // address 726 if Linkmode == LinkExternal { 727 value -= (data.(*LSym)).Value 728 adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value) 729 break 730 } 731 732 addrput(value) 733 734 case DW_FORM_block1: // block 735 if cls == DW_CLS_ADDRESS { 736 Cput(uint8(1 + Thearch.Ptrsize)) 737 Cput(DW_OP_addr) 738 if Linkmode == LinkExternal { 739 value -= (data.(*LSym)).Value 740 adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value) 741 break 742 } 743 744 addrput(value) 745 break 746 } 747 748 value &= 0xff 749 Cput(uint8(value)) 750 p := data.([]byte) 751 for i := 0; int64(i) < value; i++ { 752 Cput(uint8(p[i])) 753 } 754 755 case DW_FORM_block2: // block 756 value &= 0xffff 757 758 Thearch.Wput(uint16(value)) 759 p := data.([]byte) 760 for i := 0; int64(i) < value; i++ { 761 Cput(uint8(p[i])) 762 } 763 764 case DW_FORM_block4: // block 765 value &= 0xffffffff 766 767 Thearch.Lput(uint32(value)) 768 p := data.([]byte) 769 for i := 0; int64(i) < value; i++ { 770 Cput(uint8(p[i])) 771 } 772 773 case DW_FORM_block: // block 774 uleb128put(value) 775 776 p := data.([]byte) 777 for i := 0; int64(i) < value; i++ { 778 Cput(uint8(p[i])) 779 } 780 781 case DW_FORM_data1: // constant 782 Cput(uint8(value)) 783 784 case DW_FORM_data2: // constant 785 Thearch.Wput(uint16(value)) 786 787 case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr 788 if Linkmode == LinkExternal && cls == DW_CLS_PTR { 789 adddwarfrel(infosec, linesym, infoo, 4, value) 790 break 791 } 792 793 Thearch.Lput(uint32(value)) 794 795 case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr 796 Thearch.Vput(uint64(value)) 797 798 case DW_FORM_sdata: // constant 799 sleb128put(value) 800 801 case DW_FORM_udata: // constant 802 uleb128put(value) 803 804 case DW_FORM_string: // string 805 strnput(data.(string), int(value+1)) 806 807 case DW_FORM_flag: // flag 808 if value != 0 { 809 Cput(1) 810 } else { 811 Cput(0) 812 } 813 814 // In DWARF 2 (which is what we claim to generate), 815 // the ref_addr is the same size as a normal address. 816 // In DWARF 3 it is always 32 bits, unless emitting a large 817 // (> 4 GB of debug info aka "64-bit") unit, which we don't implement. 818 case DW_FORM_ref_addr: // reference to a DIE in the .info section 819 if data == nil { 820 Diag("dwarf: null reference in %d", abbrev) 821 if Thearch.Ptrsize == 8 { 822 Thearch.Vput(0) // invalid dwarf, gdb will complain. 823 } else { 824 Thearch.Lput(0) // invalid dwarf, gdb will complain. 825 } 826 } else { 827 off := (data.(*DWDie)).offs 828 if off == 0 { 829 fwdcount++ 830 } 831 if Linkmode == LinkExternal { 832 adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off) 833 break 834 } 835 836 addrput(off) 837 } 838 839 case DW_FORM_ref1, // reference within the compilation unit 840 DW_FORM_ref2, // reference 841 DW_FORM_ref4, // reference 842 DW_FORM_ref8, // reference 843 DW_FORM_ref_udata, // reference 844 845 DW_FORM_strp, // string 846 DW_FORM_indirect: // (see Section 7.5.3) 847 fallthrough 848 default: 849 Exitf("dwarf: unsupported attribute form %d / class %d", form, cls) 850 } 851 } 852 853 // Note that we can (and do) add arbitrary attributes to a DIE, but 854 // only the ones actually listed in the Abbrev will be written out. 855 func putattrs(abbrev int, attr *DWAttr) { 856 Outer: 857 for _, f := range abbrevs[abbrev].attr { 858 for ap := attr; ap != nil; ap = ap.link { 859 if ap.atr == f.attr { 860 putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data) 861 continue Outer 862 } 863 } 864 865 putattr(abbrev, int(f.form), 0, 0, nil) 866 } 867 } 868 869 func putdies(die *DWDie) { 870 for ; die != nil; die = die.link { 871 putdie(die) 872 } 873 } 874 875 func putdie(die *DWDie) { 876 die.offs = Cpos() - infoo 877 uleb128put(int64(die.abbrev)) 878 putattrs(die.abbrev, die.attr) 879 if abbrevs[die.abbrev].children != 0 { 880 putdies(die.child) 881 Cput(0) 882 } 883 } 884 885 func reverselist(list **DWDie) { 886 curr := *list 887 var prev *DWDie 888 for curr != nil { 889 var next *DWDie = curr.link 890 curr.link = prev 891 prev = curr 892 curr = next 893 } 894 895 *list = prev 896 } 897 898 func reversetree(list **DWDie) { 899 reverselist(list) 900 for die := *list; die != nil; die = die.link { 901 if abbrevs[die.abbrev].children != 0 { 902 reversetree(&die.child) 903 } 904 } 905 } 906 907 func newmemberoffsetattr(die *DWDie, offs int32) { 908 var block [20]byte 909 910 i := 0 911 block[i] = DW_OP_plus_uconst 912 i++ 913 i += uleb128enc(uint64(offs), block[i:]) 914 newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i]) 915 } 916 917 // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a 918 // location expression that evals to a const. 919 func newabslocexprattr(die *DWDie, addr int64, sym *LSym) { 920 newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym) 921 // below 922 } 923 924 // Lookup predefined types 925 func lookup_or_diag(n string) *LSym { 926 s := Linkrlookup(Ctxt, n, 0) 927 if s == nil || s.Size == 0 { 928 Exitf("dwarf: missing type: %s", n) 929 } 930 931 return s 932 } 933 934 func dotypedef(parent *DWDie, name string, def *DWDie) { 935 // Only emit typedefs for real names. 936 if strings.HasPrefix(name, "map[") { 937 return 938 } 939 if strings.HasPrefix(name, "struct {") { 940 return 941 } 942 if strings.HasPrefix(name, "chan ") { 943 return 944 } 945 if name[0] == '[' || name[0] == '*' { 946 return 947 } 948 if def == nil { 949 Diag("dwarf: bad def in dotypedef") 950 } 951 952 // The typedef entry must be created after the def, 953 // so that future lookups will find the typedef instead 954 // of the real definition. This hooks the typedef into any 955 // circular definition loops, so that gdb can understand them. 956 die := newdie(parent, DW_ABRV_TYPEDECL, name) 957 958 newrefattr(die, DW_AT_type, def) 959 } 960 961 // Define gotype, for composite ones recurse into constituents. 962 func defgotype(gotype *LSym) *DWDie { 963 if gotype == nil { 964 return mustFind(&dwtypes, "<unspecified>") 965 } 966 967 if !strings.HasPrefix(gotype.Name, "type.") { 968 Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name) 969 return mustFind(&dwtypes, "<unspecified>") 970 } 971 972 name := gotype.Name[5:] // could also decode from Type.string 973 974 die := find(&dwtypes, name) 975 976 if die != nil { 977 return die 978 } 979 980 if false && Debug['v'] > 2 { 981 fmt.Printf("new type: %v\n", gotype) 982 } 983 984 kind := decodetype_kind(gotype) 985 bytesize := decodetype_size(gotype) 986 987 switch kind { 988 case obj.KindBool: 989 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name) 990 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_boolean, 0) 991 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 992 993 case obj.KindInt, 994 obj.KindInt8, 995 obj.KindInt16, 996 obj.KindInt32, 997 obj.KindInt64: 998 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name) 999 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_signed, 0) 1000 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1001 1002 case obj.KindUint, 1003 obj.KindUint8, 1004 obj.KindUint16, 1005 obj.KindUint32, 1006 obj.KindUint64, 1007 obj.KindUintptr: 1008 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name) 1009 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 1010 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1011 1012 case obj.KindFloat32, 1013 obj.KindFloat64: 1014 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name) 1015 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_float, 0) 1016 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1017 1018 case obj.KindComplex64, 1019 obj.KindComplex128: 1020 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name) 1021 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_complex_float, 0) 1022 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1023 1024 case obj.KindArray: 1025 die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name) 1026 dotypedef(&dwtypes, name, die) 1027 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1028 s := decodetype_arrayelem(gotype) 1029 newrefattr(die, DW_AT_type, defgotype(s)) 1030 fld := newdie(die, DW_ABRV_ARRAYRANGE, "range") 1031 1032 // use actual length not upper bound; correct for 0-length arrays. 1033 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0) 1034 1035 newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr")) 1036 1037 case obj.KindChan: 1038 die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name) 1039 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1040 s := decodetype_chanelem(gotype) 1041 newrefattr(die, DW_AT_go_elem, defgotype(s)) 1042 1043 case obj.KindFunc: 1044 die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name) 1045 dotypedef(&dwtypes, name, die) 1046 newrefattr(die, DW_AT_type, mustFind(&dwtypes, "void")) 1047 nfields := decodetype_funcincount(gotype) 1048 var fld *DWDie 1049 var s *LSym 1050 for i := 0; i < nfields; i++ { 1051 s = decodetype_funcintype(gotype, i) 1052 fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:]) 1053 newrefattr(fld, DW_AT_type, defgotype(s)) 1054 } 1055 1056 if decodetype_funcdotdotdot(gotype) != 0 { 1057 newdie(die, DW_ABRV_DOTDOTDOT, "...") 1058 } 1059 nfields = decodetype_funcoutcount(gotype) 1060 for i := 0; i < nfields; i++ { 1061 s = decodetype_funcouttype(gotype, i) 1062 fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:]) 1063 newrefattr(fld, DW_AT_type, defptrto(defgotype(s))) 1064 } 1065 1066 case obj.KindInterface: 1067 die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name) 1068 dotypedef(&dwtypes, name, die) 1069 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1070 nfields := int(decodetype_ifacemethodcount(gotype)) 1071 var s *LSym 1072 if nfields == 0 { 1073 s = lookup_or_diag("type.runtime.eface") 1074 } else { 1075 s = lookup_or_diag("type.runtime.iface") 1076 } 1077 newrefattr(die, DW_AT_type, defgotype(s)) 1078 1079 case obj.KindMap: 1080 die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name) 1081 s := decodetype_mapkey(gotype) 1082 newrefattr(die, DW_AT_go_key, defgotype(s)) 1083 s = decodetype_mapvalue(gotype) 1084 newrefattr(die, DW_AT_go_elem, defgotype(s)) 1085 1086 case obj.KindPtr: 1087 die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name) 1088 dotypedef(&dwtypes, name, die) 1089 s := decodetype_ptrelem(gotype) 1090 newrefattr(die, DW_AT_type, defgotype(s)) 1091 1092 case obj.KindSlice: 1093 die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name) 1094 dotypedef(&dwtypes, name, die) 1095 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1096 s := decodetype_arrayelem(gotype) 1097 newrefattr(die, DW_AT_go_elem, defgotype(s)) 1098 1099 case obj.KindString: 1100 die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name) 1101 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1102 1103 case obj.KindStruct: 1104 die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name) 1105 dotypedef(&dwtypes, name, die) 1106 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 1107 nfields := decodetype_structfieldcount(gotype) 1108 var f string 1109 var fld *DWDie 1110 var s *LSym 1111 for i := 0; i < nfields; i++ { 1112 f = decodetype_structfieldname(gotype, i) 1113 s = decodetype_structfieldtype(gotype, i) 1114 if f == "" { 1115 f = s.Name[5:] // skip "type." 1116 } 1117 fld = newdie(die, DW_ABRV_STRUCTFIELD, f) 1118 newrefattr(fld, DW_AT_type, defgotype(s)) 1119 newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i))) 1120 } 1121 1122 case obj.KindUnsafePointer: 1123 die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name) 1124 1125 default: 1126 Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name) 1127 die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name) 1128 newrefattr(die, DW_AT_type, mustFind(&dwtypes, "<unspecified>")) 1129 } 1130 1131 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0) 1132 1133 return die 1134 } 1135 1136 // Find or construct *T given T. 1137 func defptrto(dwtype *DWDie) *DWDie { 1138 ptrname := fmt.Sprintf("*%s", getattr(dwtype, DW_AT_name).data) 1139 die := find(&dwtypes, ptrname) 1140 if die == nil { 1141 die = newdie(&dwtypes, DW_ABRV_PTRTYPE, ptrname) 1142 newrefattr(die, DW_AT_type, dwtype) 1143 } 1144 1145 return die 1146 } 1147 1148 // Copies src's children into dst. Copies attributes by value. 1149 // DWAttr.data is copied as pointer only. If except is one of 1150 // the top-level children, it will not be copied. 1151 func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) { 1152 var c *DWDie 1153 var a *DWAttr 1154 1155 for src = src.child; src != nil; src = src.link { 1156 if src == except { 1157 continue 1158 } 1159 c = newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string)) 1160 for a = src.attr; a != nil; a = a.link { 1161 newattr(c, a.atr, int(a.cls), a.value, a.data) 1162 } 1163 copychildrenexcept(c, src, nil) 1164 } 1165 1166 reverselist(&dst.child) 1167 } 1168 1169 func copychildren(dst *DWDie, src *DWDie) { 1170 copychildrenexcept(dst, src, nil) 1171 } 1172 1173 // Search children (assumed to have DW_TAG_member) for the one named 1174 // field and set its DW_AT_type to dwtype 1175 func substitutetype(structdie *DWDie, field string, dwtype *DWDie) { 1176 child := mustFind(structdie, field) 1177 if child == nil { 1178 return 1179 } 1180 1181 a := getattr(child, DW_AT_type) 1182 if a != nil { 1183 a.data = dwtype 1184 } else { 1185 newrefattr(child, DW_AT_type, dwtype) 1186 } 1187 } 1188 1189 func synthesizestringtypes(die *DWDie) { 1190 prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.stringStructDWARF"))) 1191 if prototype == nil { 1192 return 1193 } 1194 1195 for ; die != nil; die = die.link { 1196 if die.abbrev != DW_ABRV_STRINGTYPE { 1197 continue 1198 } 1199 copychildren(die, prototype) 1200 } 1201 } 1202 1203 func synthesizeslicetypes(die *DWDie) { 1204 prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.slice"))) 1205 if prototype == nil { 1206 return 1207 } 1208 1209 var elem *DWDie 1210 for ; die != nil; die = die.link { 1211 if die.abbrev != DW_ABRV_SLICETYPE { 1212 continue 1213 } 1214 copychildren(die, prototype) 1215 elem = getattr(die, DW_AT_go_elem).data.(*DWDie) 1216 substitutetype(die, "array", defptrto(elem)) 1217 } 1218 } 1219 1220 func mkinternaltypename(base string, arg1 string, arg2 string) string { 1221 var buf string 1222 1223 if arg2 == "" { 1224 buf = fmt.Sprintf("%s<%s>", base, arg1) 1225 } else { 1226 buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2) 1227 } 1228 n := buf 1229 return n 1230 } 1231 1232 // synthesizemaptypes is way too closely married to runtime/hashmap.c 1233 const ( 1234 MaxKeySize = 128 1235 MaxValSize = 128 1236 BucketSize = 8 1237 ) 1238 1239 func synthesizemaptypes(die *DWDie) { 1240 hash := walktypedef(defgotype(lookup_or_diag("type.runtime.hmap"))) 1241 bucket := walktypedef(defgotype(lookup_or_diag("type.runtime.bmap"))) 1242 1243 if hash == nil { 1244 return 1245 } 1246 1247 var a *DWAttr 1248 var dwh *DWDie 1249 var dwhb *DWDie 1250 var dwhk *DWDie 1251 var dwhv *DWDie 1252 var fld *DWDie 1253 var indirect_key int 1254 var indirect_val int 1255 var keysize int 1256 var keytype *DWDie 1257 var t *DWDie 1258 var valsize int 1259 var valtype *DWDie 1260 for ; die != nil; die = die.link { 1261 if die.abbrev != DW_ABRV_MAPTYPE { 1262 continue 1263 } 1264 1265 keytype = walktypedef(getattr(die, DW_AT_go_key).data.(*DWDie)) 1266 valtype = walktypedef(getattr(die, DW_AT_go_elem).data.(*DWDie)) 1267 1268 // compute size info like hashmap.c does. 1269 a = getattr(keytype, DW_AT_byte_size) 1270 1271 if a != nil { 1272 keysize = int(a.value) 1273 } else { 1274 keysize = Thearch.Ptrsize 1275 } 1276 a = getattr(valtype, DW_AT_byte_size) 1277 if a != nil { 1278 valsize = int(a.value) 1279 } else { 1280 valsize = Thearch.Ptrsize 1281 } 1282 indirect_key = 0 1283 indirect_val = 0 1284 if keysize > MaxKeySize { 1285 keysize = Thearch.Ptrsize 1286 indirect_key = 1 1287 } 1288 1289 if valsize > MaxValSize { 1290 valsize = Thearch.Ptrsize 1291 indirect_val = 1 1292 } 1293 1294 // Construct type to represent an array of BucketSize keys 1295 dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]key", getattr(keytype, DW_AT_name).data.(string), "")) 1296 1297 newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(keysize), 0) 1298 t = keytype 1299 if indirect_key != 0 { 1300 t = defptrto(keytype) 1301 } 1302 newrefattr(dwhk, DW_AT_type, t) 1303 fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size") 1304 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) 1305 newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr")) 1306 1307 // Construct type to represent an array of BucketSize values 1308 dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), "")) 1309 1310 newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(valsize), 0) 1311 t = valtype 1312 if indirect_val != 0 { 1313 t = defptrto(valtype) 1314 } 1315 newrefattr(dwhv, DW_AT_type, t) 1316 fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size") 1317 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) 1318 newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr")) 1319 1320 // Construct bucket<K,V> 1321 dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string))) 1322 1323 // Copy over all fields except the field "data" from the generic bucket. 1324 // "data" will be replaced with keys/values below. 1325 copychildrenexcept(dwhb, bucket, find(bucket, "data")) 1326 1327 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys") 1328 newrefattr(fld, DW_AT_type, dwhk) 1329 newmemberoffsetattr(fld, BucketSize) 1330 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values") 1331 newrefattr(fld, DW_AT_type, dwhv) 1332 newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize)) 1333 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow") 1334 newrefattr(fld, DW_AT_type, defptrto(dwhb)) 1335 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))) 1336 if Thearch.Regsize > Thearch.Ptrsize { 1337 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad") 1338 newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr")) 1339 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize)) 1340 } 1341 1342 newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0) 1343 1344 // Construct hash<K,V> 1345 dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hash", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string))) 1346 1347 copychildren(dwh, hash) 1348 substitutetype(dwh, "buckets", defptrto(dwhb)) 1349 substitutetype(dwh, "oldbuckets", defptrto(dwhb)) 1350 newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil) 1351 1352 // make map type a pointer to hash<K,V> 1353 newrefattr(die, DW_AT_type, defptrto(dwh)) 1354 } 1355 } 1356 1357 func synthesizechantypes(die *DWDie) { 1358 sudog := walktypedef(defgotype(lookup_or_diag("type.runtime.sudog"))) 1359 waitq := walktypedef(defgotype(lookup_or_diag("type.runtime.waitq"))) 1360 hchan := walktypedef(defgotype(lookup_or_diag("type.runtime.hchan"))) 1361 if sudog == nil || waitq == nil || hchan == nil { 1362 return 1363 } 1364 1365 sudogsize := int(getattr(sudog, DW_AT_byte_size).value) 1366 1367 var a *DWAttr 1368 var dwh *DWDie 1369 var dws *DWDie 1370 var dww *DWDie 1371 var elemsize int 1372 var elemtype *DWDie 1373 for ; die != nil; die = die.link { 1374 if die.abbrev != DW_ABRV_CHANTYPE { 1375 continue 1376 } 1377 elemtype = getattr(die, DW_AT_go_elem).data.(*DWDie) 1378 a = getattr(elemtype, DW_AT_byte_size) 1379 if a != nil { 1380 elemsize = int(a.value) 1381 } else { 1382 elemsize = Thearch.Ptrsize 1383 } 1384 1385 // sudog<T> 1386 dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("sudog", getattr(elemtype, DW_AT_name).data.(string), "")) 1387 1388 copychildren(dws, sudog) 1389 substitutetype(dws, "elem", elemtype) 1390 if elemsize > 8 { 1391 elemsize -= 8 1392 } else { 1393 elemsize = 0 1394 } 1395 newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+int64(elemsize), nil) 1396 1397 // waitq<T> 1398 dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("waitq", getattr(elemtype, DW_AT_name).data.(string), "")) 1399 1400 copychildren(dww, waitq) 1401 substitutetype(dww, "first", defptrto(dws)) 1402 substitutetype(dww, "last", defptrto(dws)) 1403 newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil) 1404 1405 // hchan<T> 1406 dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hchan", getattr(elemtype, DW_AT_name).data.(string), "")) 1407 1408 copychildren(dwh, hchan) 1409 substitutetype(dwh, "recvq", dww) 1410 substitutetype(dwh, "sendq", dww) 1411 newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil) 1412 1413 newrefattr(die, DW_AT_type, defptrto(dwh)) 1414 } 1415 } 1416 1417 // For use with pass.c::genasmsym 1418 func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) { 1419 if strings.HasPrefix(s, "go.string.") { 1420 return 1421 } 1422 if strings.HasPrefix(s, "runtime.gcbits.") { 1423 return 1424 } 1425 1426 if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { 1427 defgotype(sym) 1428 return 1429 } 1430 1431 var dv *DWDie 1432 1433 var dt *DWDie 1434 switch t { 1435 default: 1436 return 1437 1438 case 'd', 'b', 'D', 'B': 1439 dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s) 1440 newabslocexprattr(dv, v, sym) 1441 if ver == 0 { 1442 newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0) 1443 } 1444 fallthrough 1445 1446 case 'a', 'p': 1447 dt = defgotype(gotype) 1448 } 1449 1450 if dv != nil { 1451 newrefattr(dv, DW_AT_type, dt) 1452 } 1453 } 1454 1455 func movetomodule(parent *DWDie) { 1456 die := dwroot.child.child 1457 for die.link != nil { 1458 die = die.link 1459 } 1460 die.link = parent.child 1461 } 1462 1463 // If the pcln table contains runtime/runtime.go, use that to set gdbscript path. 1464 func finddebugruntimepath(s *LSym) { 1465 if gdbscript != "" { 1466 return 1467 } 1468 1469 var f *LSym 1470 var p string 1471 for i := 0; i < s.Pcln.Nfile; i++ { 1472 f = s.Pcln.File[i] 1473 _ = p 1474 if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 { 1475 gdbscript = f.Name[:i] + "runtime/runtime-gdb.py" 1476 break 1477 } 1478 } 1479 } 1480 1481 /* 1482 * Generate short opcodes when possible, long ones when necessary. 1483 * See section 6.2.5 1484 */ 1485 const ( 1486 LINE_BASE = -1 1487 LINE_RANGE = 4 1488 OPCODE_BASE = 10 1489 ) 1490 1491 func putpclcdelta(delta_pc int64, delta_lc int64) { 1492 if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE { 1493 var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc) 1494 if OPCODE_BASE <= opcode && opcode < 256 { 1495 Cput(uint8(opcode)) 1496 return 1497 } 1498 } 1499 1500 if delta_pc != 0 { 1501 Cput(DW_LNS_advance_pc) 1502 sleb128put(delta_pc) 1503 } 1504 1505 Cput(DW_LNS_advance_line) 1506 sleb128put(delta_lc) 1507 Cput(DW_LNS_copy) 1508 } 1509 1510 func newcfaoffsetattr(die *DWDie, offs int32) { 1511 var block [20]byte 1512 1513 i := 0 1514 1515 block[i] = DW_OP_call_frame_cfa 1516 i++ 1517 if offs != 0 { 1518 block[i] = DW_OP_consts 1519 i++ 1520 i += sleb128enc(int64(offs), block[i:]) 1521 block[i] = DW_OP_plus 1522 i++ 1523 } 1524 1525 newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i]) 1526 } 1527 1528 func mkvarname(name string, da int) string { 1529 buf := fmt.Sprintf("%s#%d", name, da) 1530 n := buf 1531 return n 1532 } 1533 1534 /* 1535 * Walk prog table, emit line program and build DIE tree. 1536 */ 1537 1538 // flush previous compilation unit. 1539 func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) { 1540 if dwinfo != nil && pc != 0 { 1541 newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym) 1542 } 1543 1544 if unitstart >= 0 { 1545 Cput(0) // start extended opcode 1546 uleb128put(1) 1547 Cput(DW_LNE_end_sequence) 1548 1549 here := Cpos() 1550 Cseek(unitstart) 1551 Thearch.Lput(uint32(here - unitstart - 4)) // unit_length 1552 Thearch.Wput(2) // dwarf version 1553 Thearch.Lput(uint32(header_length)) // header length starting here 1554 Cseek(here) 1555 } 1556 } 1557 1558 func getCompilationDir() string { 1559 if dir, err := os.Getwd(); err == nil { 1560 return dir 1561 } 1562 return "/" 1563 } 1564 1565 func writelines() { 1566 if linesec == nil { 1567 linesec = Linklookup(Ctxt, ".dwarfline", 0) 1568 } 1569 linesec.R = linesec.R[:0] 1570 1571 unitstart := int64(-1) 1572 headerend := int64(-1) 1573 epc := int64(0) 1574 var epcs *LSym 1575 lineo = Cpos() 1576 var dwinfo *DWDie 1577 1578 flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10)) 1579 unitstart = Cpos() 1580 1581 lang := DW_LANG_Go 1582 1583 s := Ctxt.Textp 1584 1585 dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go") 1586 newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0) 1587 newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0) 1588 newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1589 // OS X linker requires compilation dir or absolute path in comp unit name to output debug info. 1590 compDir := getCompilationDir() 1591 newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir) 1592 1593 // Write .debug_line Line Number Program Header (sec 6.2.4) 1594 // Fields marked with (*) must be changed for 64-bit dwarf 1595 Thearch.Lput(0) // unit_length (*), will be filled in by flushunit. 1596 Thearch.Wput(2) // dwarf version (appendix F) 1597 Thearch.Lput(0) // header_length (*), filled in by flushunit. 1598 1599 // cpos == unitstart + 4 + 2 + 4 1600 Cput(1) // minimum_instruction_length 1601 Cput(1) // default_is_stmt 1602 Cput(LINE_BASE & 0xFF) // line_base 1603 Cput(LINE_RANGE) // line_range 1604 Cput(OPCODE_BASE) // opcode_base 1605 Cput(0) // standard_opcode_lengths[1] 1606 Cput(1) // standard_opcode_lengths[2] 1607 Cput(1) // standard_opcode_lengths[3] 1608 Cput(1) // standard_opcode_lengths[4] 1609 Cput(1) // standard_opcode_lengths[5] 1610 Cput(0) // standard_opcode_lengths[6] 1611 Cput(0) // standard_opcode_lengths[7] 1612 Cput(0) // standard_opcode_lengths[8] 1613 Cput(1) // standard_opcode_lengths[9] 1614 Cput(0) // include_directories (empty) 1615 1616 files := make([]*LSym, Ctxt.Nhistfile) 1617 1618 for f := Ctxt.Filesyms; f != nil; f = f.Next { 1619 files[f.Value-1] = f 1620 } 1621 1622 for i := 0; int32(i) < Ctxt.Nhistfile; i++ { 1623 strnput(files[i].Name, len(files[i].Name)+4) 1624 } 1625 1626 // 4 zeros: the string termination + 3 fields. 1627 Cput(0) 1628 // terminate file_names. 1629 headerend = Cpos() 1630 1631 Cput(0) // start extended opcode 1632 uleb128put(1 + int64(Thearch.Ptrsize)) 1633 Cput(DW_LNE_set_address) 1634 1635 pc := s.Value 1636 line := 1 1637 file := 1 1638 if Linkmode == LinkExternal { 1639 adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0) 1640 } else { 1641 addrput(pc) 1642 } 1643 1644 var a *Auto 1645 var da int 1646 var dt int 1647 var dwfunc *DWDie 1648 var dws **DWDie 1649 var dwvar *DWDie 1650 var n string 1651 var nn string 1652 var offs int64 1653 var pcfile Pciter 1654 var pcline Pciter 1655 var varhash [HASHSIZE]*DWDie 1656 for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next { 1657 s = Ctxt.Cursym 1658 1659 dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s.Name) 1660 newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1661 epc = s.Value + s.Size 1662 epcs = s 1663 newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s) 1664 if s.Version == 0 { 1665 newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0) 1666 } 1667 1668 if s.Pcln == nil { 1669 continue 1670 } 1671 1672 finddebugruntimepath(s) 1673 1674 pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile) 1675 pciterinit(Ctxt, &pcline, &s.Pcln.Pcline) 1676 epc = pc 1677 for pcfile.done == 0 && pcline.done == 0 { 1678 if epc-s.Value >= int64(pcfile.nextpc) { 1679 pciternext(&pcfile) 1680 continue 1681 } 1682 1683 if epc-s.Value >= int64(pcline.nextpc) { 1684 pciternext(&pcline) 1685 continue 1686 } 1687 1688 if int32(file) != pcfile.value { 1689 Cput(DW_LNS_set_file) 1690 uleb128put(int64(pcfile.value)) 1691 file = int(pcfile.value) 1692 } 1693 1694 putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line)) 1695 1696 pc = s.Value + int64(pcline.pc) 1697 line = int(pcline.value) 1698 if pcfile.nextpc < pcline.nextpc { 1699 epc = int64(pcfile.nextpc) 1700 } else { 1701 epc = int64(pcline.nextpc) 1702 } 1703 epc += s.Value 1704 } 1705 1706 da = 0 1707 dwfunc.hash = varhash[:] // enable indexing of children by name 1708 varhash = [HASHSIZE]*DWDie{} 1709 for a = s.Autom; a != nil; a = a.Link { 1710 switch a.Name { 1711 case obj.A_AUTO: 1712 dt = DW_ABRV_AUTO 1713 offs = int64(a.Aoffset) 1714 if !haslinkregister() { 1715 offs -= int64(Thearch.Ptrsize) 1716 } 1717 1718 case obj.A_PARAM: 1719 dt = DW_ABRV_PARAM 1720 offs = int64(a.Aoffset) + Ctxt.FixedFrameSize() 1721 1722 default: 1723 continue 1724 } 1725 1726 if strings.Contains(a.Asym.Name, ".autotmp_") { 1727 continue 1728 } 1729 if find(dwfunc, a.Asym.Name) != nil { 1730 n = mkvarname(a.Asym.Name, da) 1731 } else { 1732 n = a.Asym.Name 1733 } 1734 1735 // Drop the package prefix from locals and arguments. 1736 _ = nn 1737 if i := strings.LastIndex(n, "."); i >= 0 { 1738 n = n[i+1:] 1739 } 1740 1741 dwvar = newdie(dwfunc, dt, n) 1742 newcfaoffsetattr(dwvar, int32(offs)) 1743 newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype)) 1744 1745 // push dwvar down dwfunc->child to preserve order 1746 newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil) 1747 1748 dwfunc.child = dwvar.link // take dwvar out from the top of the list 1749 for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link { 1750 if offs > getattr(*dws, DW_AT_internal_location).value { 1751 break 1752 } 1753 } 1754 dwvar.link = *dws 1755 *dws = dwvar 1756 1757 da++ 1758 } 1759 1760 dwfunc.hash = nil 1761 } 1762 1763 flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10)) 1764 linesize = Cpos() - lineo 1765 } 1766 1767 /* 1768 * Emit .debug_frame 1769 */ 1770 const ( 1771 CIERESERVE = 16 1772 DATAALIGNMENTFACTOR = -4 1773 ) 1774 1775 func putpccfadelta(deltapc int64, cfa int64) { 1776 Cput(DW_CFA_def_cfa_offset_sf) 1777 sleb128put(cfa / DATAALIGNMENTFACTOR) 1778 1779 if deltapc < 0x40 { 1780 Cput(uint8(DW_CFA_advance_loc + deltapc)) 1781 } else if deltapc < 0x100 { 1782 Cput(DW_CFA_advance_loc1) 1783 Cput(uint8(deltapc)) 1784 } else if deltapc < 0x10000 { 1785 Cput(DW_CFA_advance_loc2) 1786 Thearch.Wput(uint16(deltapc)) 1787 } else { 1788 Cput(DW_CFA_advance_loc4) 1789 Thearch.Lput(uint32(deltapc)) 1790 } 1791 } 1792 1793 func writeframes() { 1794 if framesec == nil { 1795 framesec = Linklookup(Ctxt, ".dwarfframe", 0) 1796 } 1797 framesec.R = framesec.R[:0] 1798 frameo = Cpos() 1799 1800 // Emit the CIE, Section 6.4.1 1801 Thearch.Lput(CIERESERVE) // initial length, must be multiple of thearch.ptrsize 1802 Thearch.Lput(0xffffffff) // cid. 1803 Cput(3) // dwarf version (appendix F) 1804 Cput(0) // augmentation "" 1805 uleb128put(1) // code_alignment_factor 1806 sleb128put(DATAALIGNMENTFACTOR) // guess 1807 uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register 1808 1809 Cput(DW_CFA_def_cfa) 1810 1811 uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h) 1812 if haslinkregister() { 1813 uleb128put(int64(0)) // offset 1814 } else { 1815 uleb128put(int64(Thearch.Ptrsize)) // offset 1816 } 1817 1818 Cput(DW_CFA_offset_extended) 1819 uleb128put(int64(Thearch.Dwarfreglr)) // return address 1820 if haslinkregister() { 1821 uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0 1822 } else { 1823 uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4 1824 } 1825 1826 // 4 is to exclude the length field. 1827 pad := CIERESERVE + frameo + 4 - Cpos() 1828 1829 if pad < 0 { 1830 Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad) 1831 } 1832 1833 strnput("", int(pad)) 1834 1835 var fdeo int64 1836 var fdesize int64 1837 var nextpc uint32 1838 var pcsp Pciter 1839 var s *LSym 1840 for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next { 1841 s = Ctxt.Cursym 1842 if s.Pcln == nil { 1843 continue 1844 } 1845 1846 fdeo = Cpos() 1847 1848 // Emit a FDE, Section 6.4.1, starting wit a placeholder. 1849 Thearch.Lput(0) // length, must be multiple of thearch.ptrsize 1850 Thearch.Lput(0) // Pointer to the CIE above, at offset 0 1851 addrput(0) // initial location 1852 addrput(0) // address range 1853 1854 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1855 nextpc = pcsp.nextpc 1856 1857 // pciterinit goes up to the end of the function, 1858 // but DWARF expects us to stop just before the end. 1859 if int64(nextpc) == s.Size { 1860 nextpc-- 1861 if nextpc < pcsp.pc { 1862 continue 1863 } 1864 } 1865 1866 if haslinkregister() { 1867 putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value)) 1868 } else { 1869 putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value)) 1870 } 1871 } 1872 1873 fdesize = Cpos() - fdeo - 4 // exclude the length field. 1874 pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize 1875 strnput("", int(pad)) 1876 fdesize += pad 1877 1878 // Emit the FDE header for real, Section 6.4.1. 1879 Cseek(fdeo) 1880 1881 Thearch.Lput(uint32(fdesize)) 1882 if Linkmode == LinkExternal { 1883 adddwarfrel(framesec, framesym, frameo, 4, 0) 1884 adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0) 1885 } else { 1886 Thearch.Lput(0) 1887 addrput(s.Value) 1888 } 1889 1890 addrput(s.Size) 1891 Cseek(fdeo + 4 + fdesize) 1892 } 1893 1894 Cflush() 1895 framesize = Cpos() - frameo 1896 } 1897 1898 /* 1899 * Walk DWarfDebugInfoEntries, and emit .debug_info 1900 */ 1901 const ( 1902 COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 1903 ) 1904 1905 func writeinfo() { 1906 fwdcount = 0 1907 if infosec == nil { 1908 infosec = Linklookup(Ctxt, ".dwarfinfo", 0) 1909 } 1910 infosec.R = infosec.R[:0] 1911 1912 if arangessec == nil { 1913 arangessec = Linklookup(Ctxt, ".dwarfaranges", 0) 1914 } 1915 arangessec.R = arangessec.R[:0] 1916 1917 var here int64 1918 var unitstart int64 1919 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1920 unitstart = Cpos() 1921 1922 // Write .debug_info Compilation Unit Header (sec 7.5.1) 1923 // Fields marked with (*) must be changed for 64-bit dwarf 1924 // This must match COMPUNITHEADERSIZE above. 1925 Thearch.Lput(0) // unit_length (*), will be filled in later. 1926 Thearch.Wput(2) // dwarf version (appendix F) 1927 1928 // debug_abbrev_offset (*) 1929 if Linkmode == LinkExternal { 1930 adddwarfrel(infosec, abbrevsym, infoo, 4, 0) 1931 } else { 1932 Thearch.Lput(0) 1933 } 1934 1935 Cput(uint8(Thearch.Ptrsize)) // address_size 1936 1937 putdie(compunit) 1938 1939 here = Cpos() 1940 Cseek(unitstart) 1941 Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field. 1942 Cseek(here) 1943 } 1944 1945 Cflush() 1946 } 1947 1948 /* 1949 * Emit .debug_pubnames/_types. _info must have been written before, 1950 * because we need die->offs and infoo/infosize; 1951 */ 1952 func ispubname(die *DWDie) bool { 1953 switch die.abbrev { 1954 case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE: 1955 a := getattr(die, DW_AT_external) 1956 return a != nil && a.value != 0 1957 } 1958 1959 return false 1960 } 1961 1962 func ispubtype(die *DWDie) bool { 1963 return die.abbrev >= DW_ABRV_NULLTYPE 1964 } 1965 1966 func writepub(ispub func(*DWDie) bool) int64 { 1967 var die *DWDie 1968 var dwa *DWAttr 1969 var unitstart int64 1970 var unitend int64 1971 var here int64 1972 1973 sectionstart := Cpos() 1974 1975 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1976 unitstart = compunit.offs - COMPUNITHEADERSIZE 1977 if compunit.link != nil { 1978 unitend = compunit.link.offs - COMPUNITHEADERSIZE 1979 } else { 1980 unitend = infoo + infosize 1981 } 1982 1983 // Write .debug_pubnames/types Header (sec 6.1.1) 1984 Thearch.Lput(0) // unit_length (*), will be filled in later. 1985 Thearch.Wput(2) // dwarf version (appendix F) 1986 Thearch.Lput(uint32(unitstart)) // debug_info_offset (of the Comp unit Header) 1987 Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length 1988 1989 for die = compunit.child; die != nil; die = die.link { 1990 if !ispub(die) { 1991 continue 1992 } 1993 Thearch.Lput(uint32(die.offs - unitstart)) 1994 dwa = getattr(die, DW_AT_name) 1995 strnput(dwa.data.(string), int(dwa.value+1)) 1996 } 1997 1998 Thearch.Lput(0) 1999 2000 here = Cpos() 2001 Cseek(sectionstart) 2002 Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field. 2003 Cseek(here) 2004 } 2005 2006 return sectionstart 2007 } 2008 2009 /* 2010 * emit .debug_aranges. _info must have been written before, 2011 * because we need die->offs of dw_globals. 2012 */ 2013 func writearanges() int64 { 2014 var b *DWAttr 2015 var e *DWAttr 2016 var value int64 2017 2018 sectionstart := Cpos() 2019 headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself 2020 2021 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 2022 b = getattr(compunit, DW_AT_low_pc) 2023 if b == nil { 2024 continue 2025 } 2026 e = getattr(compunit, DW_AT_high_pc) 2027 if e == nil { 2028 continue 2029 } 2030 2031 // Write .debug_aranges Header + entry (sec 6.1.2) 2032 Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*) 2033 Thearch.Wput(2) // dwarf version (appendix F) 2034 2035 value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset 2036 if Linkmode == LinkExternal { 2037 adddwarfrel(arangessec, infosym, sectionstart, 4, value) 2038 } else { 2039 Thearch.Lput(uint32(value)) 2040 } 2041 2042 Cput(uint8(Thearch.Ptrsize)) // address_size 2043 Cput(0) // segment_size 2044 strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize 2045 2046 if Linkmode == LinkExternal { 2047 adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value) 2048 } else { 2049 addrput(b.value) 2050 } 2051 2052 addrput(e.value - b.value) 2053 addrput(0) 2054 addrput(0) 2055 } 2056 2057 Cflush() 2058 return sectionstart 2059 } 2060 2061 func writegdbscript() int64 { 2062 sectionstart := Cpos() 2063 2064 if gdbscript != "" { 2065 Cput(1) // magic 1 byte? 2066 strnput(gdbscript, len(gdbscript)+1) 2067 Cflush() 2068 } 2069 2070 return sectionstart 2071 } 2072 2073 func align(size int64) { 2074 if HEADTYPE == obj.Hwindows { // Only Windows PE need section align. 2075 strnput("", int(Rnd(size, PEFILEALIGN)-size)) 2076 } 2077 } 2078 2079 func writedwarfreloc(s *LSym) int64 { 2080 var i int 2081 var r *Reloc 2082 2083 start := Cpos() 2084 for ri := 0; ri < len(s.R); ri++ { 2085 r = &s.R[ri] 2086 if Iself { 2087 i = Thearch.Elfreloc1(r, int64(r.Off)) 2088 } else if HEADTYPE == obj.Hdarwin { 2089 i = Thearch.Machoreloc1(r, int64(r.Off)) 2090 } else { 2091 i = -1 2092 } 2093 if i < 0 { 2094 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) 2095 } 2096 } 2097 2098 return start 2099 } 2100 2101 func addmachodwarfsect(prev *Section, name string) *Section { 2102 sect := addsection(&Segdwarf, name, 04) 2103 sect.Extnum = prev.Extnum + 1 2104 sym := Linklookup(Ctxt, name, 0) 2105 sym.Sect = sect 2106 return sect 2107 } 2108 2109 /* 2110 * This is the main entry point for generating dwarf. After emitting 2111 * the mandatory debug_abbrev section, it calls writelines() to set up 2112 * the per-compilation unit part of the DIE tree, while simultaneously 2113 * emitting the debug_line section. When the final tree contains 2114 * forward references, it will write the debug_info section in 2 2115 * passes. 2116 * 2117 */ 2118 func Dwarfemitdebugsections() { 2119 if Debug['w'] != 0 { // disable dwarf 2120 return 2121 } 2122 2123 if Linkmode == LinkExternal { 2124 if !Iself && HEADTYPE != obj.Hdarwin { 2125 return 2126 } 2127 if HEADTYPE == obj.Hdarwin { 2128 sect := Segdata.Sect 2129 // find the last section. 2130 for sect.Next != nil { 2131 sect = sect.Next 2132 } 2133 sect = addmachodwarfsect(sect, ".debug_abbrev") 2134 sect = addmachodwarfsect(sect, ".debug_line") 2135 sect = addmachodwarfsect(sect, ".debug_frame") 2136 sect = addmachodwarfsect(sect, ".debug_info") 2137 2138 infosym = Linklookup(Ctxt, ".debug_info", 0) 2139 infosym.Hide = 1 2140 2141 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2142 abbrevsym.Hide = 1 2143 2144 linesym = Linklookup(Ctxt, ".debug_line", 0) 2145 linesym.Hide = 1 2146 2147 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2148 framesym.Hide = 1 2149 } 2150 } 2151 2152 // For diagnostic messages. 2153 newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 2154 2155 mkindex(&dwroot) 2156 mkindex(&dwtypes) 2157 mkindex(&dwglobals) 2158 2159 // Some types that must exist to define other ones. 2160 newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>") 2161 2162 newdie(&dwtypes, DW_ABRV_NULLTYPE, "void") 2163 newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer") 2164 2165 die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size 2166 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 2167 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0) 2168 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0) 2169 2170 // Needed by the prettyprinter code for interface inspection. 2171 defgotype(lookup_or_diag("type.runtime._type")) 2172 2173 defgotype(lookup_or_diag("type.runtime.interfacetype")) 2174 defgotype(lookup_or_diag("type.runtime.itab")) 2175 2176 genasmsym(defdwsymb) 2177 2178 writeabbrev() 2179 align(abbrevsize) 2180 writelines() 2181 align(linesize) 2182 writeframes() 2183 align(framesize) 2184 2185 synthesizestringtypes(dwtypes.child) 2186 synthesizeslicetypes(dwtypes.child) 2187 synthesizemaptypes(dwtypes.child) 2188 synthesizechantypes(dwtypes.child) 2189 2190 reversetree(&dwroot.child) 2191 reversetree(&dwtypes.child) 2192 reversetree(&dwglobals.child) 2193 2194 movetomodule(&dwtypes) 2195 movetomodule(&dwglobals) 2196 2197 infoo = Cpos() 2198 writeinfo() 2199 infoe := Cpos() 2200 pubnameso = infoe 2201 pubtypeso = infoe 2202 arangeso = infoe 2203 gdbscripto = infoe 2204 2205 if fwdcount > 0 { 2206 if Debug['v'] != 0 { 2207 fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime()) 2208 } 2209 Cseek(infoo) 2210 writeinfo() 2211 if fwdcount > 0 { 2212 Exitf("dwarf: unresolved references after first dwarf info pass") 2213 } 2214 2215 if infoe != Cpos() { 2216 Exitf("dwarf: inconsistent second dwarf info pass") 2217 } 2218 } 2219 2220 infosize = infoe - infoo 2221 align(infosize) 2222 2223 pubnameso = writepub(ispubname) 2224 pubnamessize = Cpos() - pubnameso 2225 align(pubnamessize) 2226 2227 pubtypeso = writepub(ispubtype) 2228 pubtypessize = Cpos() - pubtypeso 2229 align(pubtypessize) 2230 2231 arangeso = writearanges() 2232 arangessize = Cpos() - arangeso 2233 align(arangessize) 2234 2235 gdbscripto = writegdbscript() 2236 gdbscriptsize = Cpos() - gdbscripto 2237 align(gdbscriptsize) 2238 2239 for Cpos()&7 != 0 { 2240 Cput(0) 2241 } 2242 if HEADTYPE != obj.Hdarwin { 2243 dwarfemitreloc() 2244 } 2245 } 2246 2247 func dwarfemitreloc() { 2248 if Debug['w'] != 0 { // disable dwarf 2249 return 2250 } 2251 inforeloco = writedwarfreloc(infosec) 2252 inforelocsize = Cpos() - inforeloco 2253 align(inforelocsize) 2254 2255 arangesreloco = writedwarfreloc(arangessec) 2256 arangesrelocsize = Cpos() - arangesreloco 2257 align(arangesrelocsize) 2258 2259 linereloco = writedwarfreloc(linesec) 2260 linerelocsize = Cpos() - linereloco 2261 align(linerelocsize) 2262 2263 framereloco = writedwarfreloc(framesec) 2264 framerelocsize = Cpos() - framereloco 2265 align(framerelocsize) 2266 } 2267 2268 /* 2269 * Elf. 2270 */ 2271 const ( 2272 ElfStrDebugAbbrev = iota 2273 ElfStrDebugAranges 2274 ElfStrDebugFrame 2275 ElfStrDebugInfo 2276 ElfStrDebugLine 2277 ElfStrDebugLoc 2278 ElfStrDebugMacinfo 2279 ElfStrDebugPubNames 2280 ElfStrDebugPubTypes 2281 ElfStrDebugRanges 2282 ElfStrDebugStr 2283 ElfStrGDBScripts 2284 ElfStrRelDebugInfo 2285 ElfStrRelDebugAranges 2286 ElfStrRelDebugLine 2287 ElfStrRelDebugFrame 2288 NElfStrDbg 2289 ) 2290 2291 var elfstrdbg [NElfStrDbg]int64 2292 2293 func dwarfaddshstrings(shstrtab *LSym) { 2294 if Debug['w'] != 0 { // disable dwarf 2295 return 2296 } 2297 2298 elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev") 2299 elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges") 2300 elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame") 2301 elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info") 2302 elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line") 2303 elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc") 2304 elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo") 2305 elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames") 2306 elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes") 2307 elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges") 2308 elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str") 2309 elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts") 2310 if Linkmode == LinkExternal { 2311 switch Thearch.Thechar { 2312 case '0', '6', '7', '9': 2313 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info") 2314 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges") 2315 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line") 2316 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame") 2317 default: 2318 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info") 2319 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges") 2320 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line") 2321 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame") 2322 } 2323 2324 infosym = Linklookup(Ctxt, ".debug_info", 0) 2325 infosym.Hide = 1 2326 2327 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2328 abbrevsym.Hide = 1 2329 2330 linesym = Linklookup(Ctxt, ".debug_line", 0) 2331 linesym.Hide = 1 2332 2333 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2334 framesym.Hide = 1 2335 } 2336 } 2337 2338 // Add section symbols for DWARF debug info. This is called before 2339 // dwarfaddelfheaders. 2340 func dwarfaddelfsectionsyms() { 2341 if infosym != nil { 2342 infosympos = Cpos() 2343 putelfsectionsym(infosym, 0) 2344 } 2345 2346 if abbrevsym != nil { 2347 abbrevsympos = Cpos() 2348 putelfsectionsym(abbrevsym, 0) 2349 } 2350 2351 if linesym != nil { 2352 linesympos = Cpos() 2353 putelfsectionsym(linesym, 0) 2354 } 2355 2356 if framesym != nil { 2357 framesympos = Cpos() 2358 putelfsectionsym(framesym, 0) 2359 } 2360 } 2361 2362 func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) { 2363 sh := newElfShdr(elfstrdbg[elfstr]) 2364 switch Thearch.Thechar { 2365 case '0', '6', '7', '9': 2366 sh.type_ = SHT_RELA 2367 default: 2368 sh.type_ = SHT_REL 2369 } 2370 2371 sh.entsize = uint64(Thearch.Ptrsize) * 2 2372 if sh.type_ == SHT_RELA { 2373 sh.entsize += uint64(Thearch.Ptrsize) 2374 } 2375 sh.link = uint32(elfshname(".symtab").shnum) 2376 sh.info = uint32(shdata.shnum) 2377 sh.off = uint64(off) 2378 sh.size = uint64(size) 2379 sh.addralign = uint64(Thearch.Ptrsize) 2380 } 2381 2382 func dwarfaddelfheaders() { 2383 if Debug['w'] != 0 { // disable dwarf 2384 return 2385 } 2386 2387 sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev]) 2388 sh.type_ = SHT_PROGBITS 2389 sh.off = uint64(abbrevo) 2390 sh.size = uint64(abbrevsize) 2391 sh.addralign = 1 2392 if abbrevsympos > 0 { 2393 putelfsymshndx(abbrevsympos, sh.shnum) 2394 } 2395 2396 sh = newElfShdr(elfstrdbg[ElfStrDebugLine]) 2397 sh.type_ = SHT_PROGBITS 2398 sh.off = uint64(lineo) 2399 sh.size = uint64(linesize) 2400 sh.addralign = 1 2401 if linesympos > 0 { 2402 putelfsymshndx(linesympos, sh.shnum) 2403 } 2404 shline := sh 2405 2406 sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]) 2407 sh.type_ = SHT_PROGBITS 2408 sh.off = uint64(frameo) 2409 sh.size = uint64(framesize) 2410 sh.addralign = 1 2411 if framesympos > 0 { 2412 putelfsymshndx(framesympos, sh.shnum) 2413 } 2414 shframe := sh 2415 2416 sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]) 2417 sh.type_ = SHT_PROGBITS 2418 sh.off = uint64(infoo) 2419 sh.size = uint64(infosize) 2420 sh.addralign = 1 2421 if infosympos > 0 { 2422 putelfsymshndx(infosympos, sh.shnum) 2423 } 2424 shinfo := sh 2425 2426 if pubnamessize > 0 { 2427 sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames]) 2428 sh.type_ = SHT_PROGBITS 2429 sh.off = uint64(pubnameso) 2430 sh.size = uint64(pubnamessize) 2431 sh.addralign = 1 2432 } 2433 2434 if pubtypessize > 0 { 2435 sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes]) 2436 sh.type_ = SHT_PROGBITS 2437 sh.off = uint64(pubtypeso) 2438 sh.size = uint64(pubtypessize) 2439 sh.addralign = 1 2440 } 2441 2442 var sharanges *ElfShdr 2443 if arangessize != 0 { 2444 sh := newElfShdr(elfstrdbg[ElfStrDebugAranges]) 2445 sh.type_ = SHT_PROGBITS 2446 sh.off = uint64(arangeso) 2447 sh.size = uint64(arangessize) 2448 sh.addralign = 1 2449 sharanges = sh 2450 } 2451 2452 if gdbscriptsize != 0 { 2453 sh := newElfShdr(elfstrdbg[ElfStrGDBScripts]) 2454 sh.type_ = SHT_PROGBITS 2455 sh.off = uint64(gdbscripto) 2456 sh.size = uint64(gdbscriptsize) 2457 sh.addralign = 1 2458 } 2459 2460 if inforelocsize != 0 { 2461 dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize) 2462 } 2463 2464 if arangesrelocsize != 0 { 2465 dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize) 2466 } 2467 2468 if linerelocsize != 0 { 2469 dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize) 2470 } 2471 2472 if framerelocsize != 0 { 2473 dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize) 2474 } 2475 } 2476 2477 /* 2478 * Macho 2479 */ 2480 func dwarfaddmachoheaders(ms *MachoSeg) { 2481 if Debug['w'] != 0 { // disable dwarf 2482 return 2483 } 2484 2485 // Zero vsize segments won't be loaded in memory, even so they 2486 // have to be page aligned in the file. 2487 fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000) 2488 addr := Segdata.Vaddr + Segdata.Length 2489 2490 nsect := 4 2491 if pubnamessize > 0 { 2492 nsect++ 2493 } 2494 if pubtypessize > 0 { 2495 nsect++ 2496 } 2497 if arangessize > 0 { 2498 nsect++ 2499 } 2500 if gdbscriptsize > 0 { 2501 nsect++ 2502 } 2503 2504 if Linkmode != LinkExternal { 2505 ms = newMachoSeg("__DWARF", nsect) 2506 ms.fileoffset = uint64(fakestart) 2507 ms.filesize = Segdwarf.Filelen 2508 ms.vaddr = addr 2509 } 2510 2511 msect := newMachoSect(ms, "__debug_abbrev", "__DWARF") 2512 msect.off = uint32(abbrevo) 2513 msect.size = uint64(abbrevsize) 2514 msect.addr = addr 2515 addr += msect.size 2516 msect.flag = 0x02000000 2517 if abbrevsym != nil { 2518 abbrevsym.Value = int64(msect.addr) 2519 } 2520 2521 msect = newMachoSect(ms, "__debug_line", "__DWARF") 2522 msect.off = uint32(lineo) 2523 msect.size = uint64(linesize) 2524 msect.addr = addr 2525 addr += msect.size 2526 msect.flag = 0x02000000 2527 if linesym != nil { 2528 linesym.Value = int64(msect.addr) 2529 } 2530 if linerelocsize > 0 { 2531 msect.nreloc = uint32(len(linesec.R)) 2532 msect.reloc = uint32(linereloco) 2533 } 2534 2535 msect = newMachoSect(ms, "__debug_frame", "__DWARF") 2536 msect.off = uint32(frameo) 2537 msect.size = uint64(framesize) 2538 msect.addr = addr 2539 addr += msect.size 2540 msect.flag = 0x02000000 2541 if framesym != nil { 2542 framesym.Value = int64(msect.addr) 2543 } 2544 if framerelocsize > 0 { 2545 msect.nreloc = uint32(len(framesec.R)) 2546 msect.reloc = uint32(framereloco) 2547 } 2548 2549 msect = newMachoSect(ms, "__debug_info", "__DWARF") 2550 msect.off = uint32(infoo) 2551 msect.size = uint64(infosize) 2552 msect.addr = addr 2553 addr += msect.size 2554 msect.flag = 0x02000000 2555 if infosym != nil { 2556 infosym.Value = int64(msect.addr) 2557 } 2558 if inforelocsize > 0 { 2559 msect.nreloc = uint32(len(infosec.R)) 2560 msect.reloc = uint32(inforeloco) 2561 } 2562 2563 if pubnamessize > 0 { 2564 msect := newMachoSect(ms, "__debug_pubnames", "__DWARF") 2565 msect.off = uint32(pubnameso) 2566 msect.size = uint64(pubnamessize) 2567 msect.addr = addr 2568 addr += msect.size 2569 msect.flag = 0x02000000 2570 } 2571 2572 if pubtypessize > 0 { 2573 msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF") 2574 msect.off = uint32(pubtypeso) 2575 msect.size = uint64(pubtypessize) 2576 msect.addr = addr 2577 addr += msect.size 2578 msect.flag = 0x02000000 2579 } 2580 2581 if arangessize > 0 { 2582 msect := newMachoSect(ms, "__debug_aranges", "__DWARF") 2583 msect.off = uint32(arangeso) 2584 msect.size = uint64(arangessize) 2585 msect.addr = addr 2586 addr += msect.size 2587 msect.flag = 0x02000000 2588 if arangesrelocsize > 0 { 2589 msect.nreloc = uint32(len(arangessec.R)) 2590 msect.reloc = uint32(arangesreloco) 2591 } 2592 } 2593 2594 // TODO(lvd) fix gdb/python to load MachO (16 char section name limit) 2595 if gdbscriptsize > 0 { 2596 msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF") 2597 msect.off = uint32(gdbscripto) 2598 msect.size = uint64(gdbscriptsize) 2599 msect.addr = addr 2600 addr += msect.size 2601 msect.flag = 0x02000000 2602 } 2603 } 2604 2605 /* 2606 * Windows PE 2607 */ 2608 func dwarfaddpeheaders() { 2609 if Debug['w'] != 0 { // disable dwarf 2610 return 2611 } 2612 2613 newPEDWARFSection(".debug_abbrev", abbrevsize) 2614 newPEDWARFSection(".debug_line", linesize) 2615 newPEDWARFSection(".debug_frame", framesize) 2616 newPEDWARFSection(".debug_info", infosize) 2617 newPEDWARFSection(".debug_pubnames", pubnamessize) 2618 newPEDWARFSection(".debug_pubtypes", pubtypessize) 2619 newPEDWARFSection(".debug_aranges", arangessize) 2620 newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize) 2621 }