github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/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 "strings" 21 ) 22 23 /* 24 * Offsets and sizes of the debug_* sections in the cout file. 25 */ 26 var abbrevo int64 27 28 var abbrevsize int64 29 30 var abbrevsym *LSym 31 32 var abbrevsympos int64 33 34 var lineo int64 35 36 var linesize int64 37 38 var linesym *LSym 39 40 var linesympos int64 41 42 var infoo int64 // also the base for DWDie->offs and reference attributes. 43 44 var infosize int64 45 46 var infosym *LSym 47 48 var infosympos int64 49 50 var frameo int64 51 52 var framesize int64 53 54 var framesym *LSym 55 56 var framesympos int64 57 58 var pubnameso int64 59 60 var pubnamessize int64 61 62 var pubtypeso int64 63 64 var pubtypessize int64 65 66 var arangeso int64 67 68 var arangessize int64 69 70 var gdbscripto int64 71 72 var gdbscriptsize int64 73 74 var infosec *LSym 75 76 var inforeloco int64 77 78 var inforelocsize int64 79 80 var arangessec *LSym 81 82 var arangesreloco int64 83 84 var arangesrelocsize int64 85 86 var linesec *LSym 87 88 var linereloco int64 89 90 var linerelocsize int64 91 92 var framesec *LSym 93 94 var framereloco int64 95 96 var framerelocsize int64 97 98 var gdbscript string 99 100 /* 101 * Basic I/O 102 */ 103 func addrput(addr int64) { 104 switch Thearch.Ptrsize { 105 case 4: 106 Thearch.Lput(uint32(addr)) 107 108 case 8: 109 Thearch.Vput(uint64(addr)) 110 } 111 } 112 113 func uleb128enc(v uint64, dst []byte) int { 114 var c uint8 115 116 length := uint8(0) 117 for { 118 c = uint8(v & 0x7f) 119 v >>= 7 120 if v != 0 { 121 c |= 0x80 122 } 123 if dst != nil { 124 dst[0] = byte(c) 125 dst = dst[1:] 126 } 127 length++ 128 if c&0x80 == 0 { 129 break 130 } 131 } 132 133 return int(length) 134 } 135 136 func sleb128enc(v int64, dst []byte) int { 137 var c uint8 138 var s uint8 139 140 length := uint8(0) 141 for { 142 c = uint8(v & 0x7f) 143 s = uint8(v & 0x40) 144 v >>= 7 145 if (v != -1 || s == 0) && (v != 0 || s != 0) { 146 c |= 0x80 147 } 148 if dst != nil { 149 dst[0] = byte(c) 150 dst = dst[1:] 151 } 152 length++ 153 if c&0x80 == 0 { 154 break 155 } 156 } 157 158 return int(length) 159 } 160 161 func uleb128put(v int64) { 162 var buf [10]byte 163 n := uleb128enc(uint64(v), buf[:]) 164 Cwrite(buf[:n]) 165 } 166 167 func sleb128put(v int64) { 168 var buf [10]byte 169 n := sleb128enc(v, buf[:]) 170 Cwrite(buf[:n]) 171 } 172 173 /* 174 * Defining Abbrevs. This is hardcoded, and there will be 175 * only a handful of them. The DWARF spec places no restriction on 176 * the ordering of attributes in the Abbrevs and DIEs, and we will 177 * always write them out in the order of declaration in the abbrev. 178 */ 179 type DWAttrForm struct { 180 attr uint16 181 form uint8 182 } 183 184 // Go-specific type attributes. 185 const ( 186 DW_AT_go_kind = 0x2900 187 DW_AT_go_key = 0x2901 188 DW_AT_go_elem = 0x2902 189 190 DW_AT_internal_location = 253 // params and locals; not emitted 191 ) 192 193 // Index into the abbrevs table below. 194 // Keep in sync with ispubname() and ispubtype() below. 195 // ispubtype considers >= NULLTYPE public 196 const ( 197 DW_ABRV_NULL = iota 198 DW_ABRV_COMPUNIT 199 DW_ABRV_FUNCTION 200 DW_ABRV_VARIABLE 201 DW_ABRV_AUTO 202 DW_ABRV_PARAM 203 DW_ABRV_STRUCTFIELD 204 DW_ABRV_FUNCTYPEPARAM 205 DW_ABRV_DOTDOTDOT 206 DW_ABRV_ARRAYRANGE 207 DW_ABRV_NULLTYPE 208 DW_ABRV_BASETYPE 209 DW_ABRV_ARRAYTYPE 210 DW_ABRV_CHANTYPE 211 DW_ABRV_FUNCTYPE 212 DW_ABRV_IFACETYPE 213 DW_ABRV_MAPTYPE 214 DW_ABRV_PTRTYPE 215 DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. 216 DW_ABRV_SLICETYPE 217 DW_ABRV_STRINGTYPE 218 DW_ABRV_STRUCTTYPE 219 DW_ABRV_TYPEDECL 220 DW_NABRV 221 ) 222 223 type DWAbbrev struct { 224 tag uint8 225 children uint8 226 attr []DWAttrForm 227 } 228 229 var abbrevs = [DW_NABRV]DWAbbrev{ 230 /* The mandatory DW_ABRV_NULL entry. */ 231 {0, 0, []DWAttrForm{}}, 232 233 /* COMPUNIT */ 234 { 235 DW_TAG_compile_unit, 236 DW_CHILDREN_yes, 237 []DWAttrForm{ 238 {DW_AT_name, DW_FORM_string}, 239 {DW_AT_language, DW_FORM_data1}, 240 {DW_AT_low_pc, DW_FORM_addr}, 241 {DW_AT_high_pc, DW_FORM_addr}, 242 {DW_AT_stmt_list, DW_FORM_data4}, 243 }, 244 }, 245 246 /* FUNCTION */ 247 { 248 DW_TAG_subprogram, 249 DW_CHILDREN_yes, 250 []DWAttrForm{ 251 {DW_AT_name, DW_FORM_string}, 252 {DW_AT_low_pc, DW_FORM_addr}, 253 {DW_AT_high_pc, DW_FORM_addr}, 254 {DW_AT_external, DW_FORM_flag}, 255 }, 256 }, 257 258 /* VARIABLE */ 259 { 260 DW_TAG_variable, 261 DW_CHILDREN_no, 262 []DWAttrForm{ 263 {DW_AT_name, DW_FORM_string}, 264 {DW_AT_location, DW_FORM_block1}, 265 {DW_AT_type, DW_FORM_ref_addr}, 266 {DW_AT_external, DW_FORM_flag}, 267 }, 268 }, 269 270 /* AUTO */ 271 { 272 DW_TAG_variable, 273 DW_CHILDREN_no, 274 []DWAttrForm{ 275 {DW_AT_name, DW_FORM_string}, 276 {DW_AT_location, DW_FORM_block1}, 277 {DW_AT_type, DW_FORM_ref_addr}, 278 }, 279 }, 280 281 /* PARAM */ 282 { 283 DW_TAG_formal_parameter, 284 DW_CHILDREN_no, 285 []DWAttrForm{ 286 {DW_AT_name, DW_FORM_string}, 287 {DW_AT_location, DW_FORM_block1}, 288 {DW_AT_type, DW_FORM_ref_addr}, 289 }, 290 }, 291 292 /* STRUCTFIELD */ 293 { 294 DW_TAG_member, 295 DW_CHILDREN_no, 296 []DWAttrForm{ 297 {DW_AT_name, DW_FORM_string}, 298 {DW_AT_data_member_location, DW_FORM_block1}, 299 {DW_AT_type, DW_FORM_ref_addr}, 300 }, 301 }, 302 303 /* FUNCTYPEPARAM */ 304 { 305 DW_TAG_formal_parameter, 306 DW_CHILDREN_no, 307 308 // No name! 309 []DWAttrForm{ 310 {DW_AT_type, DW_FORM_ref_addr}, 311 }, 312 }, 313 314 /* DOTDOTDOT */ 315 { 316 DW_TAG_unspecified_parameters, 317 DW_CHILDREN_no, 318 []DWAttrForm{}, 319 }, 320 321 /* ARRAYRANGE */ 322 { 323 DW_TAG_subrange_type, 324 DW_CHILDREN_no, 325 326 // No name! 327 []DWAttrForm{ 328 {DW_AT_type, DW_FORM_ref_addr}, 329 {DW_AT_count, DW_FORM_udata}, 330 }, 331 }, 332 333 // Below here are the types considered public by ispubtype 334 /* NULLTYPE */ 335 { 336 DW_TAG_unspecified_type, 337 DW_CHILDREN_no, 338 []DWAttrForm{ 339 {DW_AT_name, DW_FORM_string}, 340 }, 341 }, 342 343 /* BASETYPE */ 344 { 345 DW_TAG_base_type, 346 DW_CHILDREN_no, 347 []DWAttrForm{ 348 {DW_AT_name, DW_FORM_string}, 349 {DW_AT_encoding, DW_FORM_data1}, 350 {DW_AT_byte_size, DW_FORM_data1}, 351 {DW_AT_go_kind, DW_FORM_data1}, 352 }, 353 }, 354 355 /* ARRAYTYPE */ 356 // child is subrange with upper bound 357 { 358 DW_TAG_array_type, 359 DW_CHILDREN_yes, 360 []DWAttrForm{ 361 {DW_AT_name, DW_FORM_string}, 362 {DW_AT_type, DW_FORM_ref_addr}, 363 {DW_AT_byte_size, DW_FORM_udata}, 364 {DW_AT_go_kind, DW_FORM_data1}, 365 }, 366 }, 367 368 /* CHANTYPE */ 369 { 370 DW_TAG_typedef, 371 DW_CHILDREN_no, 372 []DWAttrForm{ 373 {DW_AT_name, DW_FORM_string}, 374 {DW_AT_type, DW_FORM_ref_addr}, 375 {DW_AT_go_kind, DW_FORM_data1}, 376 {DW_AT_go_elem, DW_FORM_ref_addr}, 377 }, 378 }, 379 380 /* FUNCTYPE */ 381 { 382 DW_TAG_subroutine_type, 383 DW_CHILDREN_yes, 384 []DWAttrForm{ 385 {DW_AT_name, DW_FORM_string}, 386 // {DW_AT_type, DW_FORM_ref_addr}, 387 {DW_AT_go_kind, DW_FORM_data1}, 388 }, 389 }, 390 391 /* IFACETYPE */ 392 { 393 DW_TAG_typedef, 394 DW_CHILDREN_yes, 395 []DWAttrForm{ 396 {DW_AT_name, DW_FORM_string}, 397 {DW_AT_type, DW_FORM_ref_addr}, 398 {DW_AT_go_kind, DW_FORM_data1}, 399 }, 400 }, 401 402 /* MAPTYPE */ 403 { 404 DW_TAG_typedef, 405 DW_CHILDREN_no, 406 []DWAttrForm{ 407 {DW_AT_name, DW_FORM_string}, 408 {DW_AT_type, DW_FORM_ref_addr}, 409 {DW_AT_go_kind, DW_FORM_data1}, 410 {DW_AT_go_key, DW_FORM_ref_addr}, 411 {DW_AT_go_elem, DW_FORM_ref_addr}, 412 }, 413 }, 414 415 /* PTRTYPE */ 416 { 417 DW_TAG_pointer_type, 418 DW_CHILDREN_no, 419 []DWAttrForm{ 420 {DW_AT_name, DW_FORM_string}, 421 {DW_AT_type, DW_FORM_ref_addr}, 422 {DW_AT_go_kind, DW_FORM_data1}, 423 }, 424 }, 425 426 /* BARE_PTRTYPE */ 427 { 428 DW_TAG_pointer_type, 429 DW_CHILDREN_no, 430 []DWAttrForm{ 431 {DW_AT_name, DW_FORM_string}, 432 }, 433 }, 434 435 /* SLICETYPE */ 436 { 437 DW_TAG_structure_type, 438 DW_CHILDREN_yes, 439 []DWAttrForm{ 440 {DW_AT_name, DW_FORM_string}, 441 {DW_AT_byte_size, DW_FORM_udata}, 442 {DW_AT_go_kind, DW_FORM_data1}, 443 {DW_AT_go_elem, DW_FORM_ref_addr}, 444 }, 445 }, 446 447 /* STRINGTYPE */ 448 { 449 DW_TAG_structure_type, 450 DW_CHILDREN_yes, 451 []DWAttrForm{ 452 {DW_AT_name, DW_FORM_string}, 453 {DW_AT_byte_size, DW_FORM_udata}, 454 {DW_AT_go_kind, DW_FORM_data1}, 455 }, 456 }, 457 458 /* STRUCTTYPE */ 459 { 460 DW_TAG_structure_type, 461 DW_CHILDREN_yes, 462 []DWAttrForm{ 463 {DW_AT_name, DW_FORM_string}, 464 {DW_AT_byte_size, DW_FORM_udata}, 465 {DW_AT_go_kind, DW_FORM_data1}, 466 }, 467 }, 468 469 /* TYPEDECL */ 470 { 471 DW_TAG_typedef, 472 DW_CHILDREN_no, 473 []DWAttrForm{ 474 {DW_AT_name, DW_FORM_string}, 475 {DW_AT_type, DW_FORM_ref_addr}, 476 }, 477 }, 478 } 479 480 func writeabbrev() { 481 abbrevo = Cpos() 482 for i := 1; i < DW_NABRV; i++ { 483 // See section 7.5.3 484 uleb128put(int64(i)) 485 486 uleb128put(int64(abbrevs[i].tag)) 487 Cput(abbrevs[i].children) 488 for _, f := range abbrevs[i].attr { 489 uleb128put(int64(f.attr)) 490 uleb128put(int64(f.form)) 491 } 492 uleb128put(0) 493 uleb128put(0) 494 } 495 496 Cput(0) 497 abbrevsize = Cpos() - abbrevo 498 } 499 500 /* 501 * Debugging Information Entries and their attributes. 502 */ 503 const ( 504 HASHSIZE = 107 505 ) 506 507 func dwarfhashstr(s string) uint32 { 508 h := uint32(0) 509 for s != "" { 510 h = h + h + h + uint32(s[0]) 511 s = s[1:] 512 } 513 return h % HASHSIZE 514 } 515 516 // For DW_CLS_string and _block, value should contain the length, and 517 // data the data, for _reference, value is 0 and data is a DWDie* to 518 // the referenced instance, for all others, value is the whole thing 519 // and data is null. 520 521 type DWAttr struct { 522 link *DWAttr 523 atr uint16 // DW_AT_ 524 cls uint8 // DW_CLS_ 525 value int64 526 data interface{} 527 } 528 529 type DWDie struct { 530 abbrev int 531 link *DWDie 532 child *DWDie 533 attr *DWAttr 534 // offset into .debug_info section, i.e relative to 535 // infoo. only valid after call to putdie() 536 offs int64 537 hash []*DWDie // optional index of children by name, enabled by mkindex() 538 hlink *DWDie // bucket chain in parent's index 539 } 540 541 /* 542 * Root DIEs for compilation units, types and global variables. 543 */ 544 var dwroot DWDie 545 546 var dwtypes DWDie 547 548 var dwglobals DWDie 549 550 func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr { 551 a := new(DWAttr) 552 a.link = die.attr 553 die.attr = a 554 a.atr = attr 555 a.cls = uint8(cls) 556 a.value = value 557 a.data = data 558 return a 559 } 560 561 // Each DIE (except the root ones) has at least 1 attribute: its 562 // name. getattr moves the desired one to the front so 563 // frequently searched ones are found faster. 564 func getattr(die *DWDie, attr uint16) *DWAttr { 565 if die.attr.atr == attr { 566 return die.attr 567 } 568 569 a := die.attr 570 b := a.link 571 for b != nil { 572 if b.atr == attr { 573 a.link = b.link 574 b.link = die.attr 575 die.attr = b 576 return b 577 } 578 579 a = b 580 b = b.link 581 } 582 583 return nil 584 } 585 586 // Every DIE has at least a DW_AT_name attribute (but it will only be 587 // written out if it is listed in the abbrev). If its parent is 588 // keeping an index, the new DIE will be inserted there. 589 func newdie(parent *DWDie, abbrev int, name string) *DWDie { 590 die := new(DWDie) 591 die.abbrev = abbrev 592 die.link = parent.child 593 parent.child = die 594 595 newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name) 596 597 if parent.hash != nil { 598 h := int(dwarfhashstr(name)) 599 die.hlink = parent.hash[h] 600 parent.hash[h] = die 601 } 602 603 return die 604 } 605 606 func mkindex(die *DWDie) { 607 die.hash = make([]*DWDie, HASHSIZE) 608 } 609 610 func walktypedef(die *DWDie) *DWDie { 611 // Resolve typedef if present. 612 if die.abbrev == DW_ABRV_TYPEDECL { 613 for attr := die.attr; attr != nil; attr = attr.link { 614 if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil { 615 return attr.data.(*DWDie) 616 } 617 } 618 } 619 620 return die 621 } 622 623 // Find child by AT_name using hashtable if available or linear scan 624 // if not. 625 func find(die *DWDie, name string) *DWDie { 626 var a *DWDie 627 var b *DWDie 628 var die2 *DWDie 629 var h int 630 631 top: 632 if die.hash == nil { 633 for a = die.child; a != nil; a = a.link { 634 if name == getattr(a, DW_AT_name).data { 635 return a 636 } 637 } 638 goto notfound 639 } 640 641 h = int(dwarfhashstr(name)) 642 a = die.hash[h] 643 644 if a == nil { 645 goto notfound 646 } 647 648 if name == getattr(a, DW_AT_name).data { 649 return a 650 } 651 652 // Move found ones to head of the list. 653 b = a.hlink 654 655 for b != nil { 656 if name == getattr(b, DW_AT_name).data { 657 a.hlink = b.hlink 658 b.hlink = die.hash[h] 659 die.hash[h] = b 660 return b 661 } 662 663 a = b 664 b = b.hlink 665 } 666 667 notfound: 668 die2 = walktypedef(die) 669 if die2 != die { 670 die = die2 671 goto top 672 } 673 674 return nil 675 } 676 677 func find_or_diag(die *DWDie, name string) *DWDie { 678 r := find(die, name) 679 if r == nil { 680 Diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name) 681 Errorexit() 682 } 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 = R_ADDR 694 r.Add = addend 695 r.Xadd = addend 696 if Iself && Thearch.Thechar == '6' { 697 addend = 0 698 } 699 switch siz { 700 case 4: 701 Thearch.Lput(uint32(addend)) 702 703 case 8: 704 Thearch.Vput(uint64(addend)) 705 706 default: 707 Diag("bad size in adddwarfrel") 708 } 709 } 710 711 func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr { 712 if ref == nil { 713 return nil 714 } 715 return newattr(die, attr, DW_CLS_REFERENCE, 0, ref) 716 } 717 718 var fwdcount int 719 720 func putattr(abbrev int, form int, cls int, value int64, data interface{}) { 721 switch form { 722 case DW_FORM_addr: // address 723 if Linkmode == LinkExternal { 724 value -= (data.(*LSym)).Value 725 adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value) 726 break 727 } 728 729 addrput(value) 730 731 case DW_FORM_block1: // block 732 if cls == DW_CLS_ADDRESS { 733 Cput(uint8(1 + Thearch.Ptrsize)) 734 Cput(DW_OP_addr) 735 if Linkmode == LinkExternal { 736 value -= (data.(*LSym)).Value 737 adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value) 738 break 739 } 740 741 addrput(value) 742 break 743 } 744 745 value &= 0xff 746 Cput(uint8(value)) 747 p := data.([]byte) 748 for i := 0; int64(i) < value; i++ { 749 Cput(uint8(p[i])) 750 } 751 752 case DW_FORM_block2: // block 753 value &= 0xffff 754 755 Thearch.Wput(uint16(value)) 756 p := data.([]byte) 757 for i := 0; int64(i) < value; i++ { 758 Cput(uint8(p[i])) 759 } 760 761 case DW_FORM_block4: // block 762 value &= 0xffffffff 763 764 Thearch.Lput(uint32(value)) 765 p := data.([]byte) 766 for i := 0; int64(i) < value; i++ { 767 Cput(uint8(p[i])) 768 } 769 770 case DW_FORM_block: // block 771 uleb128put(value) 772 773 p := data.([]byte) 774 for i := 0; int64(i) < value; i++ { 775 Cput(uint8(p[i])) 776 } 777 778 case DW_FORM_data1: // constant 779 Cput(uint8(value)) 780 781 case DW_FORM_data2: // constant 782 Thearch.Wput(uint16(value)) 783 784 case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr 785 if Linkmode == LinkExternal && cls == DW_CLS_PTR { 786 adddwarfrel(infosec, linesym, infoo, 4, value) 787 break 788 } 789 790 Thearch.Lput(uint32(value)) 791 792 case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr 793 Thearch.Vput(uint64(value)) 794 795 case DW_FORM_sdata: // constant 796 sleb128put(value) 797 798 case DW_FORM_udata: // constant 799 uleb128put(value) 800 801 case DW_FORM_string: // string 802 strnput(data.(string), int(value+1)) 803 804 case DW_FORM_flag: // flag 805 if value != 0 { 806 Cput(1) 807 } else { 808 Cput(0) 809 } 810 811 // In DWARF 2 (which is what we claim to generate), 812 // the ref_addr is the same size as a normal address. 813 // In DWARF 3 it is always 32 bits, unless emitting a large 814 // (> 4 GB of debug info aka "64-bit") unit, which we don't implement. 815 case DW_FORM_ref_addr: // reference to a DIE in the .info section 816 if data == nil { 817 Diag("dwarf: null reference in %d", abbrev) 818 if Thearch.Ptrsize == 8 { 819 Thearch.Vput(0) // invalid dwarf, gdb will complain. 820 } else { 821 Thearch.Lput(0) // invalid dwarf, gdb will complain. 822 } 823 } else { 824 off := (data.(*DWDie)).offs 825 if off == 0 { 826 fwdcount++ 827 } 828 if Linkmode == LinkExternal { 829 adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off) 830 break 831 } 832 833 addrput(off) 834 } 835 836 case DW_FORM_ref1, // reference within the compilation unit 837 DW_FORM_ref2, // reference 838 DW_FORM_ref4, // reference 839 DW_FORM_ref8, // reference 840 DW_FORM_ref_udata, // reference 841 842 DW_FORM_strp, // string 843 DW_FORM_indirect: // (see Section 7.5.3) 844 fallthrough 845 default: 846 Diag("dwarf: unsupported attribute form %d / class %d", form, cls) 847 848 Errorexit() 849 } 850 } 851 852 // Note that we can (and do) add arbitrary attributes to a DIE, but 853 // only the ones actually listed in the Abbrev will be written out. 854 func putattrs(abbrev int, attr *DWAttr) { 855 Outer: 856 for _, f := range abbrevs[abbrev].attr { 857 for ap := attr; ap != nil; ap = ap.link { 858 if ap.atr == f.attr { 859 putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data) 860 continue Outer 861 } 862 } 863 864 putattr(abbrev, int(f.form), 0, 0, nil) 865 } 866 } 867 868 func putdies(die *DWDie) { 869 for ; die != nil; die = die.link { 870 putdie(die) 871 } 872 } 873 874 func putdie(die *DWDie) { 875 die.offs = Cpos() - infoo 876 uleb128put(int64(die.abbrev)) 877 putattrs(die.abbrev, die.attr) 878 if abbrevs[die.abbrev].children != 0 { 879 putdies(die.child) 880 Cput(0) 881 } 882 } 883 884 func reverselist(list **DWDie) { 885 curr := *list 886 var prev *DWDie 887 for curr != nil { 888 var next *DWDie = curr.link 889 curr.link = prev 890 prev = curr 891 curr = next 892 } 893 894 *list = prev 895 } 896 897 func reversetree(list **DWDie) { 898 reverselist(list) 899 for die := *list; die != nil; die = die.link { 900 if abbrevs[die.abbrev].children != 0 { 901 reversetree(&die.child) 902 } 903 } 904 } 905 906 func newmemberoffsetattr(die *DWDie, offs int32) { 907 var block [20]byte 908 909 i := 0 910 block[i] = DW_OP_plus_uconst 911 i++ 912 i += uleb128enc(uint64(offs), block[i:]) 913 newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i]) 914 } 915 916 // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a 917 // location expression that evals to a const. 918 func newabslocexprattr(die *DWDie, addr int64, sym *LSym) { 919 newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym) 920 // below 921 } 922 923 // Lookup predefined types 924 func lookup_or_diag(n string) *LSym { 925 s := Linkrlookup(Ctxt, n, 0) 926 if s == nil || s.Size == 0 { 927 Diag("dwarf: missing type: %s", n) 928 Errorexit() 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 find_or_diag(&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 find_or_diag(&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: %%Y\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, find_or_diag(&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, find_or_diag(&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, find_or_diag(&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 := find_or_diag(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._string"))) 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, find_or_diag(&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, find_or_diag(&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, find_or_diag(&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 1423 if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { 1424 defgotype(sym) 1425 return 1426 } 1427 1428 var dv *DWDie 1429 1430 var dt *DWDie 1431 switch t { 1432 default: 1433 return 1434 1435 case 'd', 'b', 'D', 'B': 1436 dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s) 1437 newabslocexprattr(dv, v, sym) 1438 if ver == 0 { 1439 newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0) 1440 } 1441 fallthrough 1442 1443 // fallthrough 1444 case 'a', 'p': 1445 dt = defgotype(gotype) 1446 } 1447 1448 if dv != nil { 1449 newrefattr(dv, DW_AT_type, dt) 1450 } 1451 } 1452 1453 func movetomodule(parent *DWDie) { 1454 die := dwroot.child.child 1455 for die.link != nil { 1456 die = die.link 1457 } 1458 die.link = parent.child 1459 } 1460 1461 // If the pcln table contains runtime/runtime.go, use that to set gdbscript path. 1462 func finddebugruntimepath(s *LSym) { 1463 if gdbscript != "" { 1464 return 1465 } 1466 1467 var f *LSym 1468 var p string 1469 for i := 0; i < s.Pcln.Nfile; i++ { 1470 f = s.Pcln.File[i] 1471 _ = p 1472 if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 { 1473 gdbscript = f.Name[:i] + "runtime/runtime-gdb.py" 1474 break 1475 } 1476 } 1477 } 1478 1479 /* 1480 * Generate short opcodes when possible, long ones when necessary. 1481 * See section 6.2.5 1482 */ 1483 const ( 1484 LINE_BASE = -1 1485 LINE_RANGE = 4 1486 OPCODE_BASE = 10 1487 ) 1488 1489 func putpclcdelta(delta_pc int64, delta_lc int64) { 1490 if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE { 1491 var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc) 1492 if OPCODE_BASE <= opcode && opcode < 256 { 1493 Cput(uint8(opcode)) 1494 return 1495 } 1496 } 1497 1498 if delta_pc != 0 { 1499 Cput(DW_LNS_advance_pc) 1500 sleb128put(delta_pc) 1501 } 1502 1503 Cput(DW_LNS_advance_line) 1504 sleb128put(delta_lc) 1505 Cput(DW_LNS_copy) 1506 } 1507 1508 func newcfaoffsetattr(die *DWDie, offs int32) { 1509 var block [20]byte 1510 1511 i := 0 1512 1513 block[i] = DW_OP_call_frame_cfa 1514 i++ 1515 if offs != 0 { 1516 block[i] = DW_OP_consts 1517 i++ 1518 i += sleb128enc(int64(offs), block[i:]) 1519 block[i] = DW_OP_plus 1520 i++ 1521 } 1522 1523 newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i]) 1524 } 1525 1526 func mkvarname(name string, da int) string { 1527 buf := fmt.Sprintf("%s#%d", name, da) 1528 n := buf 1529 return n 1530 } 1531 1532 /* 1533 * Walk prog table, emit line program and build DIE tree. 1534 */ 1535 1536 // flush previous compilation unit. 1537 func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) { 1538 if dwinfo != nil && pc != 0 { 1539 newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym) 1540 } 1541 1542 if unitstart >= 0 { 1543 Cput(0) // start extended opcode 1544 uleb128put(1) 1545 Cput(DW_LNE_end_sequence) 1546 1547 here := Cpos() 1548 Cseek(unitstart) 1549 Thearch.Lput(uint32(here - unitstart - 4)) // unit_length 1550 Thearch.Wput(2) // dwarf version 1551 Thearch.Lput(uint32(header_length)) // header length starting here 1552 Cseek(here) 1553 } 1554 } 1555 1556 func writelines() { 1557 if linesec == nil { 1558 linesec = Linklookup(Ctxt, ".dwarfline", 0) 1559 } 1560 linesec.R = linesec.R[:0] 1561 1562 unitstart := int64(-1) 1563 headerend := int64(-1) 1564 epc := int64(0) 1565 var epcs *LSym 1566 lineo = Cpos() 1567 var dwinfo *DWDie 1568 1569 flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10)) 1570 unitstart = Cpos() 1571 1572 lang := DW_LANG_Go 1573 1574 s := Ctxt.Textp 1575 1576 dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go") 1577 newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0) 1578 newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0) 1579 newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1580 1581 // Write .debug_line Line Number Program Header (sec 6.2.4) 1582 // Fields marked with (*) must be changed for 64-bit dwarf 1583 Thearch.Lput(0) // unit_length (*), will be filled in by flushunit. 1584 Thearch.Wput(2) // dwarf version (appendix F) 1585 Thearch.Lput(0) // header_length (*), filled in by flushunit. 1586 1587 // cpos == unitstart + 4 + 2 + 4 1588 Cput(1) // minimum_instruction_length 1589 Cput(1) // default_is_stmt 1590 Cput(LINE_BASE & 0xFF) // line_base 1591 Cput(LINE_RANGE) // line_range 1592 Cput(OPCODE_BASE) // opcode_base 1593 Cput(0) // standard_opcode_lengths[1] 1594 Cput(1) // standard_opcode_lengths[2] 1595 Cput(1) // standard_opcode_lengths[3] 1596 Cput(1) // standard_opcode_lengths[4] 1597 Cput(1) // standard_opcode_lengths[5] 1598 Cput(0) // standard_opcode_lengths[6] 1599 Cput(0) // standard_opcode_lengths[7] 1600 Cput(0) // standard_opcode_lengths[8] 1601 Cput(1) // standard_opcode_lengths[9] 1602 Cput(0) // include_directories (empty) 1603 1604 files := make([]*LSym, Ctxt.Nhistfile) 1605 1606 for f := Ctxt.Filesyms; f != nil; f = f.Next { 1607 files[f.Value-1] = f 1608 } 1609 1610 for i := 0; int32(i) < Ctxt.Nhistfile; i++ { 1611 strnput(files[i].Name, len(files[i].Name)+4) 1612 } 1613 1614 // 4 zeros: the string termination + 3 fields. 1615 Cput(0) 1616 // terminate file_names. 1617 headerend = Cpos() 1618 1619 Cput(0) // start extended opcode 1620 uleb128put(1 + int64(Thearch.Ptrsize)) 1621 Cput(DW_LNE_set_address) 1622 1623 pc := s.Value 1624 line := 1 1625 file := 1 1626 if Linkmode == LinkExternal { 1627 adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0) 1628 } else { 1629 addrput(pc) 1630 } 1631 1632 var a *Auto 1633 var da int 1634 var dt int 1635 var dwfunc *DWDie 1636 var dws **DWDie 1637 var dwvar *DWDie 1638 var n string 1639 var nn string 1640 var offs int64 1641 var pcfile Pciter 1642 var pcline Pciter 1643 var varhash [HASHSIZE]*DWDie 1644 for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next { 1645 s = Ctxt.Cursym 1646 1647 dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s.Name) 1648 newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1649 epc = s.Value + s.Size 1650 epcs = s 1651 newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s) 1652 if s.Version == 0 { 1653 newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0) 1654 } 1655 1656 if s.Pcln == nil { 1657 continue 1658 } 1659 1660 finddebugruntimepath(s) 1661 1662 pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile) 1663 pciterinit(Ctxt, &pcline, &s.Pcln.Pcline) 1664 epc = pc 1665 for pcfile.done == 0 && pcline.done == 0 { 1666 if epc-s.Value >= int64(pcfile.nextpc) { 1667 pciternext(&pcfile) 1668 continue 1669 } 1670 1671 if epc-s.Value >= int64(pcline.nextpc) { 1672 pciternext(&pcline) 1673 continue 1674 } 1675 1676 if int32(file) != pcfile.value { 1677 Cput(DW_LNS_set_file) 1678 uleb128put(int64(pcfile.value)) 1679 file = int(pcfile.value) 1680 } 1681 1682 putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line)) 1683 1684 pc = s.Value + int64(pcline.pc) 1685 line = int(pcline.value) 1686 if pcfile.nextpc < pcline.nextpc { 1687 epc = int64(pcfile.nextpc) 1688 } else { 1689 epc = int64(pcline.nextpc) 1690 } 1691 epc += s.Value 1692 } 1693 1694 da = 0 1695 dwfunc.hash = varhash[:] // enable indexing of children by name 1696 varhash = [HASHSIZE]*DWDie{} 1697 for a = s.Autom; a != nil; a = a.Link { 1698 switch a.Name { 1699 case A_AUTO: 1700 dt = DW_ABRV_AUTO 1701 offs = int64(a.Aoffset) - int64(Thearch.Ptrsize) 1702 1703 case A_PARAM: 1704 dt = DW_ABRV_PARAM 1705 offs = int64(a.Aoffset) 1706 1707 default: 1708 continue 1709 } 1710 1711 if strings.Contains(a.Asym.Name, ".autotmp_") { 1712 continue 1713 } 1714 if find(dwfunc, a.Asym.Name) != nil { 1715 n = mkvarname(a.Asym.Name, da) 1716 } else { 1717 n = a.Asym.Name 1718 } 1719 1720 // Drop the package prefix from locals and arguments. 1721 _ = nn 1722 if i := strings.LastIndex(n, "."); i >= 0 { 1723 n = n[i+1:] 1724 } 1725 1726 dwvar = newdie(dwfunc, dt, n) 1727 newcfaoffsetattr(dwvar, int32(offs)) 1728 newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype)) 1729 1730 // push dwvar down dwfunc->child to preserve order 1731 newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil) 1732 1733 dwfunc.child = dwvar.link // take dwvar out from the top of the list 1734 for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link { 1735 if offs > getattr(*dws, DW_AT_internal_location).value { 1736 break 1737 } 1738 } 1739 dwvar.link = *dws 1740 *dws = dwvar 1741 1742 da++ 1743 } 1744 1745 dwfunc.hash = nil 1746 } 1747 1748 flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10)) 1749 linesize = Cpos() - lineo 1750 } 1751 1752 /* 1753 * Emit .debug_frame 1754 */ 1755 const ( 1756 CIERESERVE = 16 1757 DATAALIGNMENTFACTOR = -4 1758 FAKERETURNCOLUMN = 16 // TODO gdb6 doesn't like > 15? 1759 ) 1760 1761 func putpccfadelta(deltapc int64, cfa int64) { 1762 Cput(DW_CFA_def_cfa_offset_sf) 1763 sleb128put(cfa / DATAALIGNMENTFACTOR) 1764 1765 if deltapc < 0x40 { 1766 Cput(uint8(DW_CFA_advance_loc + deltapc)) 1767 } else if deltapc < 0x100 { 1768 Cput(DW_CFA_advance_loc1) 1769 Cput(uint8(deltapc)) 1770 } else if deltapc < 0x10000 { 1771 Cput(DW_CFA_advance_loc2) 1772 Thearch.Wput(uint16(deltapc)) 1773 } else { 1774 Cput(DW_CFA_advance_loc4) 1775 Thearch.Lput(uint32(deltapc)) 1776 } 1777 } 1778 1779 func writeframes() { 1780 if framesec == nil { 1781 framesec = Linklookup(Ctxt, ".dwarfframe", 0) 1782 } 1783 framesec.R = framesec.R[:0] 1784 frameo = Cpos() 1785 1786 // Emit the CIE, Section 6.4.1 1787 Thearch.Lput(CIERESERVE) // initial length, must be multiple of thearch.ptrsize 1788 Thearch.Lput(0xffffffff) // cid. 1789 Cput(3) // dwarf version (appendix F) 1790 Cput(0) // augmentation "" 1791 uleb128put(1) // code_alignment_factor 1792 sleb128put(DATAALIGNMENTFACTOR) // guess 1793 uleb128put(FAKERETURNCOLUMN) // return_address_register 1794 1795 Cput(DW_CFA_def_cfa) 1796 1797 uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h) 1798 uleb128put(int64(Thearch.Ptrsize)) // offset 1799 1800 Cput(DW_CFA_offset + FAKERETURNCOLUMN) // return address 1801 uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4 1802 1803 // 4 is to exclude the length field. 1804 pad := CIERESERVE + frameo + 4 - Cpos() 1805 1806 if pad < 0 { 1807 Diag("dwarf: CIERESERVE too small by %d bytes.", -pad) 1808 Errorexit() 1809 } 1810 1811 strnput("", int(pad)) 1812 1813 var fdeo int64 1814 var fdesize int64 1815 var nextpc uint32 1816 var pcsp Pciter 1817 var s *LSym 1818 for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next { 1819 s = Ctxt.Cursym 1820 if s.Pcln == nil { 1821 continue 1822 } 1823 1824 fdeo = Cpos() 1825 1826 // Emit a FDE, Section 6.4.1, starting wit a placeholder. 1827 Thearch.Lput(0) // length, must be multiple of thearch.ptrsize 1828 Thearch.Lput(0) // Pointer to the CIE above, at offset 0 1829 addrput(0) // initial location 1830 addrput(0) // address range 1831 1832 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1833 nextpc = pcsp.nextpc 1834 1835 // pciterinit goes up to the end of the function, 1836 // but DWARF expects us to stop just before the end. 1837 if int64(nextpc) == s.Size { 1838 nextpc-- 1839 if nextpc < pcsp.pc { 1840 continue 1841 } 1842 } 1843 1844 putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value)) 1845 } 1846 1847 fdesize = Cpos() - fdeo - 4 // exclude the length field. 1848 pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize 1849 strnput("", int(pad)) 1850 fdesize += pad 1851 1852 // Emit the FDE header for real, Section 6.4.1. 1853 Cseek(fdeo) 1854 1855 Thearch.Lput(uint32(fdesize)) 1856 if Linkmode == LinkExternal { 1857 adddwarfrel(framesec, framesym, frameo, 4, 0) 1858 adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0) 1859 } else { 1860 Thearch.Lput(0) 1861 addrput(s.Value) 1862 } 1863 1864 addrput(s.Size) 1865 Cseek(fdeo + 4 + fdesize) 1866 } 1867 1868 Cflush() 1869 framesize = Cpos() - frameo 1870 } 1871 1872 /* 1873 * Walk DWarfDebugInfoEntries, and emit .debug_info 1874 */ 1875 const ( 1876 COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 1877 ) 1878 1879 func writeinfo() { 1880 fwdcount = 0 1881 if infosec == nil { 1882 infosec = Linklookup(Ctxt, ".dwarfinfo", 0) 1883 } 1884 infosec.R = infosec.R[:0] 1885 1886 if arangessec == nil { 1887 arangessec = Linklookup(Ctxt, ".dwarfaranges", 0) 1888 } 1889 arangessec.R = arangessec.R[:0] 1890 1891 var here int64 1892 var unitstart int64 1893 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1894 unitstart = Cpos() 1895 1896 // Write .debug_info Compilation Unit Header (sec 7.5.1) 1897 // Fields marked with (*) must be changed for 64-bit dwarf 1898 // This must match COMPUNITHEADERSIZE above. 1899 Thearch.Lput(0) // unit_length (*), will be filled in later. 1900 Thearch.Wput(2) // dwarf version (appendix F) 1901 1902 // debug_abbrev_offset (*) 1903 if Linkmode == LinkExternal { 1904 adddwarfrel(infosec, abbrevsym, infoo, 4, 0) 1905 } else { 1906 Thearch.Lput(0) 1907 } 1908 1909 Cput(uint8(Thearch.Ptrsize)) // address_size 1910 1911 putdie(compunit) 1912 1913 here = Cpos() 1914 Cseek(unitstart) 1915 Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field. 1916 Cseek(here) 1917 } 1918 1919 Cflush() 1920 } 1921 1922 /* 1923 * Emit .debug_pubnames/_types. _info must have been written before, 1924 * because we need die->offs and infoo/infosize; 1925 */ 1926 func ispubname(die *DWDie) bool { 1927 switch die.abbrev { 1928 case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE: 1929 a := getattr(die, DW_AT_external) 1930 return a != nil && a.value != 0 1931 } 1932 1933 return false 1934 } 1935 1936 func ispubtype(die *DWDie) bool { 1937 return die.abbrev >= DW_ABRV_NULLTYPE 1938 } 1939 1940 func writepub(ispub func(*DWDie) bool) int64 { 1941 var die *DWDie 1942 var dwa *DWAttr 1943 var unitstart int64 1944 var unitend int64 1945 var here int64 1946 1947 sectionstart := Cpos() 1948 1949 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1950 unitstart = compunit.offs - COMPUNITHEADERSIZE 1951 if compunit.link != nil { 1952 unitend = compunit.link.offs - COMPUNITHEADERSIZE 1953 } else { 1954 unitend = infoo + infosize 1955 } 1956 1957 // Write .debug_pubnames/types Header (sec 6.1.1) 1958 Thearch.Lput(0) // unit_length (*), will be filled in later. 1959 Thearch.Wput(2) // dwarf version (appendix F) 1960 Thearch.Lput(uint32(unitstart)) // debug_info_offset (of the Comp unit Header) 1961 Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length 1962 1963 for die = compunit.child; die != nil; die = die.link { 1964 if !ispub(die) { 1965 continue 1966 } 1967 Thearch.Lput(uint32(die.offs - unitstart)) 1968 dwa = getattr(die, DW_AT_name) 1969 strnput(dwa.data.(string), int(dwa.value+1)) 1970 } 1971 1972 Thearch.Lput(0) 1973 1974 here = Cpos() 1975 Cseek(sectionstart) 1976 Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field. 1977 Cseek(here) 1978 } 1979 1980 return sectionstart 1981 } 1982 1983 /* 1984 * emit .debug_aranges. _info must have been written before, 1985 * because we need die->offs of dw_globals. 1986 */ 1987 func writearanges() int64 { 1988 var b *DWAttr 1989 var e *DWAttr 1990 var value int64 1991 1992 sectionstart := Cpos() 1993 headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself 1994 1995 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1996 b = getattr(compunit, DW_AT_low_pc) 1997 if b == nil { 1998 continue 1999 } 2000 e = getattr(compunit, DW_AT_high_pc) 2001 if e == nil { 2002 continue 2003 } 2004 2005 // Write .debug_aranges Header + entry (sec 6.1.2) 2006 Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*) 2007 Thearch.Wput(2) // dwarf version (appendix F) 2008 2009 value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset 2010 if Linkmode == LinkExternal { 2011 adddwarfrel(arangessec, infosym, sectionstart, 4, value) 2012 } else { 2013 Thearch.Lput(uint32(value)) 2014 } 2015 2016 Cput(uint8(Thearch.Ptrsize)) // address_size 2017 Cput(0) // segment_size 2018 strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize 2019 2020 if Linkmode == LinkExternal { 2021 adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value) 2022 } else { 2023 addrput(b.value) 2024 } 2025 2026 addrput(e.value - b.value) 2027 addrput(0) 2028 addrput(0) 2029 } 2030 2031 Cflush() 2032 return sectionstart 2033 } 2034 2035 func writegdbscript() int64 { 2036 sectionstart := Cpos() 2037 2038 if gdbscript != "" { 2039 Cput(1) // magic 1 byte? 2040 strnput(gdbscript, len(gdbscript)+1) 2041 Cflush() 2042 } 2043 2044 return sectionstart 2045 } 2046 2047 func align(size int64) { 2048 if HEADTYPE == Hwindows { // Only Windows PE need section align. 2049 strnput("", int(Rnd(size, PEFILEALIGN)-size)) 2050 } 2051 } 2052 2053 func writedwarfreloc(s *LSym) int64 { 2054 var i int 2055 var r *Reloc 2056 2057 start := Cpos() 2058 for ri := 0; ri < len(s.R); ri++ { 2059 r = &s.R[ri] 2060 if Iself { 2061 i = Thearch.Elfreloc1(r, int64(r.Off)) 2062 } else if HEADTYPE == Hdarwin { 2063 i = Thearch.Machoreloc1(r, int64(r.Off)) 2064 } else { 2065 i = -1 2066 } 2067 if i < 0 { 2068 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) 2069 } 2070 } 2071 2072 return start 2073 } 2074 2075 /* 2076 * This is the main entry point for generating dwarf. After emitting 2077 * the mandatory debug_abbrev section, it calls writelines() to set up 2078 * the per-compilation unit part of the DIE tree, while simultaneously 2079 * emitting the debug_line section. When the final tree contains 2080 * forward references, it will write the debug_info section in 2 2081 * passes. 2082 * 2083 */ 2084 func Dwarfemitdebugsections() { 2085 if Debug['w'] != 0 { // disable dwarf 2086 return 2087 } 2088 2089 if Linkmode == LinkExternal && !Iself { 2090 return 2091 } 2092 2093 // For diagnostic messages. 2094 newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 2095 2096 mkindex(&dwroot) 2097 mkindex(&dwtypes) 2098 mkindex(&dwglobals) 2099 2100 // Some types that must exist to define other ones. 2101 newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>") 2102 2103 newdie(&dwtypes, DW_ABRV_NULLTYPE, "void") 2104 newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer") 2105 2106 die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size 2107 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 2108 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0) 2109 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0) 2110 2111 // Needed by the prettyprinter code for interface inspection. 2112 defgotype(lookup_or_diag("type.runtime._type")) 2113 2114 defgotype(lookup_or_diag("type.runtime.interfacetype")) 2115 defgotype(lookup_or_diag("type.runtime.itab")) 2116 2117 genasmsym(defdwsymb) 2118 2119 writeabbrev() 2120 align(abbrevsize) 2121 writelines() 2122 align(linesize) 2123 writeframes() 2124 align(framesize) 2125 2126 synthesizestringtypes(dwtypes.child) 2127 synthesizeslicetypes(dwtypes.child) 2128 synthesizemaptypes(dwtypes.child) 2129 synthesizechantypes(dwtypes.child) 2130 2131 reversetree(&dwroot.child) 2132 reversetree(&dwtypes.child) 2133 reversetree(&dwglobals.child) 2134 2135 movetomodule(&dwtypes) 2136 movetomodule(&dwglobals) 2137 2138 infoo = Cpos() 2139 writeinfo() 2140 infoe := Cpos() 2141 pubnameso = infoe 2142 pubtypeso = infoe 2143 arangeso = infoe 2144 gdbscripto = infoe 2145 2146 if fwdcount > 0 { 2147 if Debug['v'] != 0 { 2148 fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime()) 2149 } 2150 Cseek(infoo) 2151 writeinfo() 2152 if fwdcount > 0 { 2153 Diag("dwarf: unresolved references after first dwarf info pass") 2154 Errorexit() 2155 } 2156 2157 if infoe != Cpos() { 2158 Diag("dwarf: inconsistent second dwarf info pass") 2159 Errorexit() 2160 } 2161 } 2162 2163 infosize = infoe - infoo 2164 align(infosize) 2165 2166 pubnameso = writepub(ispubname) 2167 pubnamessize = Cpos() - pubnameso 2168 align(pubnamessize) 2169 2170 pubtypeso = writepub(ispubtype) 2171 pubtypessize = Cpos() - pubtypeso 2172 align(pubtypessize) 2173 2174 arangeso = writearanges() 2175 arangessize = Cpos() - arangeso 2176 align(arangessize) 2177 2178 gdbscripto = writegdbscript() 2179 gdbscriptsize = Cpos() - gdbscripto 2180 align(gdbscriptsize) 2181 2182 for Cpos()&7 != 0 { 2183 Cput(0) 2184 } 2185 inforeloco = writedwarfreloc(infosec) 2186 inforelocsize = Cpos() - inforeloco 2187 align(inforelocsize) 2188 2189 arangesreloco = writedwarfreloc(arangessec) 2190 arangesrelocsize = Cpos() - arangesreloco 2191 align(arangesrelocsize) 2192 2193 linereloco = writedwarfreloc(linesec) 2194 linerelocsize = Cpos() - linereloco 2195 align(linerelocsize) 2196 2197 framereloco = writedwarfreloc(framesec) 2198 framerelocsize = Cpos() - framereloco 2199 align(framerelocsize) 2200 } 2201 2202 /* 2203 * Elf. 2204 */ 2205 const ( 2206 ElfStrDebugAbbrev = iota 2207 ElfStrDebugAranges 2208 ElfStrDebugFrame 2209 ElfStrDebugInfo 2210 ElfStrDebugLine 2211 ElfStrDebugLoc 2212 ElfStrDebugMacinfo 2213 ElfStrDebugPubNames 2214 ElfStrDebugPubTypes 2215 ElfStrDebugRanges 2216 ElfStrDebugStr 2217 ElfStrGDBScripts 2218 ElfStrRelDebugInfo 2219 ElfStrRelDebugAranges 2220 ElfStrRelDebugLine 2221 ElfStrRelDebugFrame 2222 NElfStrDbg 2223 ) 2224 2225 var elfstrdbg [NElfStrDbg]int64 2226 2227 func dwarfaddshstrings(shstrtab *LSym) { 2228 if Debug['w'] != 0 { // disable dwarf 2229 return 2230 } 2231 2232 elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev") 2233 elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges") 2234 elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame") 2235 elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info") 2236 elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line") 2237 elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc") 2238 elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo") 2239 elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames") 2240 elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes") 2241 elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges") 2242 elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str") 2243 elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts") 2244 if Linkmode == LinkExternal { 2245 switch Thearch.Thechar { 2246 case '6', '7', '9': 2247 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info") 2248 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges") 2249 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line") 2250 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame") 2251 default: 2252 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info") 2253 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges") 2254 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line") 2255 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame") 2256 } 2257 2258 infosym = Linklookup(Ctxt, ".debug_info", 0) 2259 infosym.Hide = 1 2260 2261 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2262 abbrevsym.Hide = 1 2263 2264 linesym = Linklookup(Ctxt, ".debug_line", 0) 2265 linesym.Hide = 1 2266 2267 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2268 framesym.Hide = 1 2269 } 2270 } 2271 2272 // Add section symbols for DWARF debug info. This is called before 2273 // dwarfaddelfheaders. 2274 func dwarfaddelfsectionsyms() { 2275 if infosym != nil { 2276 infosympos = Cpos() 2277 putelfsectionsym(infosym, 0) 2278 } 2279 2280 if abbrevsym != nil { 2281 abbrevsympos = Cpos() 2282 putelfsectionsym(abbrevsym, 0) 2283 } 2284 2285 if linesym != nil { 2286 linesympos = Cpos() 2287 putelfsectionsym(linesym, 0) 2288 } 2289 2290 if framesym != nil { 2291 framesympos = Cpos() 2292 putelfsectionsym(framesym, 0) 2293 } 2294 } 2295 2296 func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) { 2297 sh := newElfShdr(elfstrdbg[elfstr]) 2298 switch Thearch.Thechar { 2299 case '6', '7', '9': 2300 sh.type_ = SHT_RELA 2301 default: 2302 sh.type_ = SHT_REL 2303 } 2304 2305 sh.entsize = uint64(Thearch.Ptrsize) * 2 2306 if sh.type_ == SHT_RELA { 2307 sh.entsize += uint64(Thearch.Ptrsize) 2308 } 2309 sh.link = uint32(elfshname(".symtab").shnum) 2310 sh.info = uint32(shdata.shnum) 2311 sh.off = uint64(off) 2312 sh.size = uint64(size) 2313 sh.addralign = uint64(Thearch.Ptrsize) 2314 } 2315 2316 func dwarfaddelfheaders() { 2317 if Debug['w'] != 0 { // disable dwarf 2318 return 2319 } 2320 2321 sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev]) 2322 sh.type_ = SHT_PROGBITS 2323 sh.off = uint64(abbrevo) 2324 sh.size = uint64(abbrevsize) 2325 sh.addralign = 1 2326 if abbrevsympos > 0 { 2327 putelfsymshndx(abbrevsympos, sh.shnum) 2328 } 2329 2330 sh = newElfShdr(elfstrdbg[ElfStrDebugLine]) 2331 sh.type_ = SHT_PROGBITS 2332 sh.off = uint64(lineo) 2333 sh.size = uint64(linesize) 2334 sh.addralign = 1 2335 if linesympos > 0 { 2336 putelfsymshndx(linesympos, sh.shnum) 2337 } 2338 shline := sh 2339 2340 sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]) 2341 sh.type_ = SHT_PROGBITS 2342 sh.off = uint64(frameo) 2343 sh.size = uint64(framesize) 2344 sh.addralign = 1 2345 if framesympos > 0 { 2346 putelfsymshndx(framesympos, sh.shnum) 2347 } 2348 shframe := sh 2349 2350 sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]) 2351 sh.type_ = SHT_PROGBITS 2352 sh.off = uint64(infoo) 2353 sh.size = uint64(infosize) 2354 sh.addralign = 1 2355 if infosympos > 0 { 2356 putelfsymshndx(infosympos, sh.shnum) 2357 } 2358 shinfo := sh 2359 2360 if pubnamessize > 0 { 2361 sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames]) 2362 sh.type_ = SHT_PROGBITS 2363 sh.off = uint64(pubnameso) 2364 sh.size = uint64(pubnamessize) 2365 sh.addralign = 1 2366 } 2367 2368 if pubtypessize > 0 { 2369 sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes]) 2370 sh.type_ = SHT_PROGBITS 2371 sh.off = uint64(pubtypeso) 2372 sh.size = uint64(pubtypessize) 2373 sh.addralign = 1 2374 } 2375 2376 var sharanges *ElfShdr 2377 if arangessize != 0 { 2378 sh := newElfShdr(elfstrdbg[ElfStrDebugAranges]) 2379 sh.type_ = SHT_PROGBITS 2380 sh.off = uint64(arangeso) 2381 sh.size = uint64(arangessize) 2382 sh.addralign = 1 2383 sharanges = sh 2384 } 2385 2386 if gdbscriptsize != 0 { 2387 sh := newElfShdr(elfstrdbg[ElfStrGDBScripts]) 2388 sh.type_ = SHT_PROGBITS 2389 sh.off = uint64(gdbscripto) 2390 sh.size = uint64(gdbscriptsize) 2391 sh.addralign = 1 2392 } 2393 2394 if inforelocsize != 0 { 2395 dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize) 2396 } 2397 2398 if arangesrelocsize != 0 { 2399 dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize) 2400 } 2401 2402 if linerelocsize != 0 { 2403 dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize) 2404 } 2405 2406 if framerelocsize != 0 { 2407 dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize) 2408 } 2409 } 2410 2411 /* 2412 * Macho 2413 */ 2414 func dwarfaddmachoheaders() { 2415 if Debug['w'] != 0 { // disable dwarf 2416 return 2417 } 2418 2419 // Zero vsize segments won't be loaded in memory, even so they 2420 // have to be page aligned in the file. 2421 fakestart := abbrevo &^ 0xfff 2422 2423 nsect := 4 2424 if pubnamessize > 0 { 2425 nsect++ 2426 } 2427 if pubtypessize > 0 { 2428 nsect++ 2429 } 2430 if arangessize > 0 { 2431 nsect++ 2432 } 2433 if gdbscriptsize > 0 { 2434 nsect++ 2435 } 2436 2437 ms := newMachoSeg("__DWARF", nsect) 2438 ms.fileoffset = uint64(fakestart) 2439 ms.filesize = uint64(abbrevo) - uint64(fakestart) 2440 ms.vaddr = ms.fileoffset + Segdata.Vaddr - Segdata.Fileoff 2441 2442 msect := newMachoSect(ms, "__debug_abbrev", "__DWARF") 2443 msect.off = uint32(abbrevo) 2444 msect.size = uint64(abbrevsize) 2445 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2446 ms.filesize += msect.size 2447 2448 msect = newMachoSect(ms, "__debug_line", "__DWARF") 2449 msect.off = uint32(lineo) 2450 msect.size = uint64(linesize) 2451 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2452 ms.filesize += msect.size 2453 2454 msect = newMachoSect(ms, "__debug_frame", "__DWARF") 2455 msect.off = uint32(frameo) 2456 msect.size = uint64(framesize) 2457 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2458 ms.filesize += msect.size 2459 2460 msect = newMachoSect(ms, "__debug_info", "__DWARF") 2461 msect.off = uint32(infoo) 2462 msect.size = uint64(infosize) 2463 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2464 ms.filesize += msect.size 2465 2466 if pubnamessize > 0 { 2467 msect := newMachoSect(ms, "__debug_pubnames", "__DWARF") 2468 msect.off = uint32(pubnameso) 2469 msect.size = uint64(pubnamessize) 2470 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2471 ms.filesize += msect.size 2472 } 2473 2474 if pubtypessize > 0 { 2475 msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF") 2476 msect.off = uint32(pubtypeso) 2477 msect.size = uint64(pubtypessize) 2478 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2479 ms.filesize += msect.size 2480 } 2481 2482 if arangessize > 0 { 2483 msect := newMachoSect(ms, "__debug_aranges", "__DWARF") 2484 msect.off = uint32(arangeso) 2485 msect.size = uint64(arangessize) 2486 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2487 ms.filesize += msect.size 2488 } 2489 2490 // TODO(lvd) fix gdb/python to load MachO (16 char section name limit) 2491 if gdbscriptsize > 0 { 2492 msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF") 2493 msect.off = uint32(gdbscripto) 2494 msect.size = uint64(gdbscriptsize) 2495 msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff 2496 ms.filesize += msect.size 2497 } 2498 } 2499 2500 /* 2501 * Windows PE 2502 */ 2503 func dwarfaddpeheaders() { 2504 if Debug['w'] != 0 { // disable dwarf 2505 return 2506 } 2507 2508 newPEDWARFSection(".debug_abbrev", abbrevsize) 2509 newPEDWARFSection(".debug_line", linesize) 2510 newPEDWARFSection(".debug_frame", framesize) 2511 newPEDWARFSection(".debug_info", infosize) 2512 newPEDWARFSection(".debug_pubnames", pubnamessize) 2513 newPEDWARFSection(".debug_pubtypes", pubtypessize) 2514 newPEDWARFSection(".debug_aranges", arangessize) 2515 newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize) 2516 }