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._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, 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) 1721 if haslinkregister() { 1722 offs += int64(Thearch.Ptrsize) 1723 } 1724 1725 default: 1726 continue 1727 } 1728 1729 if strings.Contains(a.Asym.Name, ".autotmp_") { 1730 continue 1731 } 1732 if find(dwfunc, a.Asym.Name) != nil { 1733 n = mkvarname(a.Asym.Name, da) 1734 } else { 1735 n = a.Asym.Name 1736 } 1737 1738 // Drop the package prefix from locals and arguments. 1739 _ = nn 1740 if i := strings.LastIndex(n, "."); i >= 0 { 1741 n = n[i+1:] 1742 } 1743 1744 dwvar = newdie(dwfunc, dt, n) 1745 newcfaoffsetattr(dwvar, int32(offs)) 1746 newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype)) 1747 1748 // push dwvar down dwfunc->child to preserve order 1749 newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil) 1750 1751 dwfunc.child = dwvar.link // take dwvar out from the top of the list 1752 for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link { 1753 if offs > getattr(*dws, DW_AT_internal_location).value { 1754 break 1755 } 1756 } 1757 dwvar.link = *dws 1758 *dws = dwvar 1759 1760 da++ 1761 } 1762 1763 dwfunc.hash = nil 1764 } 1765 1766 flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10)) 1767 linesize = Cpos() - lineo 1768 } 1769 1770 /* 1771 * Emit .debug_frame 1772 */ 1773 const ( 1774 CIERESERVE = 16 1775 DATAALIGNMENTFACTOR = -4 1776 ) 1777 1778 func putpccfadelta(deltapc int64, cfa int64) { 1779 Cput(DW_CFA_def_cfa_offset_sf) 1780 sleb128put(cfa / DATAALIGNMENTFACTOR) 1781 1782 if deltapc < 0x40 { 1783 Cput(uint8(DW_CFA_advance_loc + deltapc)) 1784 } else if deltapc < 0x100 { 1785 Cput(DW_CFA_advance_loc1) 1786 Cput(uint8(deltapc)) 1787 } else if deltapc < 0x10000 { 1788 Cput(DW_CFA_advance_loc2) 1789 Thearch.Wput(uint16(deltapc)) 1790 } else { 1791 Cput(DW_CFA_advance_loc4) 1792 Thearch.Lput(uint32(deltapc)) 1793 } 1794 } 1795 1796 func writeframes() { 1797 if framesec == nil { 1798 framesec = Linklookup(Ctxt, ".dwarfframe", 0) 1799 } 1800 framesec.R = framesec.R[:0] 1801 frameo = Cpos() 1802 1803 // Emit the CIE, Section 6.4.1 1804 Thearch.Lput(CIERESERVE) // initial length, must be multiple of thearch.ptrsize 1805 Thearch.Lput(0xffffffff) // cid. 1806 Cput(3) // dwarf version (appendix F) 1807 Cput(0) // augmentation "" 1808 uleb128put(1) // code_alignment_factor 1809 sleb128put(DATAALIGNMENTFACTOR) // guess 1810 uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register 1811 1812 Cput(DW_CFA_def_cfa) 1813 1814 uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h) 1815 if haslinkregister() { 1816 uleb128put(int64(0)) // offset 1817 } else { 1818 uleb128put(int64(Thearch.Ptrsize)) // offset 1819 } 1820 1821 Cput(DW_CFA_offset_extended) 1822 uleb128put(int64(Thearch.Dwarfreglr)) // return address 1823 if haslinkregister() { 1824 uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0 1825 } else { 1826 uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4 1827 } 1828 1829 // 4 is to exclude the length field. 1830 pad := CIERESERVE + frameo + 4 - Cpos() 1831 1832 if pad < 0 { 1833 Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad) 1834 } 1835 1836 strnput("", int(pad)) 1837 1838 var fdeo int64 1839 var fdesize int64 1840 var nextpc uint32 1841 var pcsp Pciter 1842 var s *LSym 1843 for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next { 1844 s = Ctxt.Cursym 1845 if s.Pcln == nil { 1846 continue 1847 } 1848 1849 fdeo = Cpos() 1850 1851 // Emit a FDE, Section 6.4.1, starting wit a placeholder. 1852 Thearch.Lput(0) // length, must be multiple of thearch.ptrsize 1853 Thearch.Lput(0) // Pointer to the CIE above, at offset 0 1854 addrput(0) // initial location 1855 addrput(0) // address range 1856 1857 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1858 nextpc = pcsp.nextpc 1859 1860 // pciterinit goes up to the end of the function, 1861 // but DWARF expects us to stop just before the end. 1862 if int64(nextpc) == s.Size { 1863 nextpc-- 1864 if nextpc < pcsp.pc { 1865 continue 1866 } 1867 } 1868 1869 if haslinkregister() { 1870 putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value)) 1871 } else { 1872 putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value)) 1873 } 1874 } 1875 1876 fdesize = Cpos() - fdeo - 4 // exclude the length field. 1877 pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize 1878 strnput("", int(pad)) 1879 fdesize += pad 1880 1881 // Emit the FDE header for real, Section 6.4.1. 1882 Cseek(fdeo) 1883 1884 Thearch.Lput(uint32(fdesize)) 1885 if Linkmode == LinkExternal { 1886 adddwarfrel(framesec, framesym, frameo, 4, 0) 1887 adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0) 1888 } else { 1889 Thearch.Lput(0) 1890 addrput(s.Value) 1891 } 1892 1893 addrput(s.Size) 1894 Cseek(fdeo + 4 + fdesize) 1895 } 1896 1897 Cflush() 1898 framesize = Cpos() - frameo 1899 } 1900 1901 /* 1902 * Walk DWarfDebugInfoEntries, and emit .debug_info 1903 */ 1904 const ( 1905 COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 1906 ) 1907 1908 func writeinfo() { 1909 fwdcount = 0 1910 if infosec == nil { 1911 infosec = Linklookup(Ctxt, ".dwarfinfo", 0) 1912 } 1913 infosec.R = infosec.R[:0] 1914 1915 if arangessec == nil { 1916 arangessec = Linklookup(Ctxt, ".dwarfaranges", 0) 1917 } 1918 arangessec.R = arangessec.R[:0] 1919 1920 var here int64 1921 var unitstart int64 1922 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1923 unitstart = Cpos() 1924 1925 // Write .debug_info Compilation Unit Header (sec 7.5.1) 1926 // Fields marked with (*) must be changed for 64-bit dwarf 1927 // This must match COMPUNITHEADERSIZE above. 1928 Thearch.Lput(0) // unit_length (*), will be filled in later. 1929 Thearch.Wput(2) // dwarf version (appendix F) 1930 1931 // debug_abbrev_offset (*) 1932 if Linkmode == LinkExternal { 1933 adddwarfrel(infosec, abbrevsym, infoo, 4, 0) 1934 } else { 1935 Thearch.Lput(0) 1936 } 1937 1938 Cput(uint8(Thearch.Ptrsize)) // address_size 1939 1940 putdie(compunit) 1941 1942 here = Cpos() 1943 Cseek(unitstart) 1944 Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field. 1945 Cseek(here) 1946 } 1947 1948 Cflush() 1949 } 1950 1951 /* 1952 * Emit .debug_pubnames/_types. _info must have been written before, 1953 * because we need die->offs and infoo/infosize; 1954 */ 1955 func ispubname(die *DWDie) bool { 1956 switch die.abbrev { 1957 case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE: 1958 a := getattr(die, DW_AT_external) 1959 return a != nil && a.value != 0 1960 } 1961 1962 return false 1963 } 1964 1965 func ispubtype(die *DWDie) bool { 1966 return die.abbrev >= DW_ABRV_NULLTYPE 1967 } 1968 1969 func writepub(ispub func(*DWDie) bool) int64 { 1970 var die *DWDie 1971 var dwa *DWAttr 1972 var unitstart int64 1973 var unitend int64 1974 var here int64 1975 1976 sectionstart := Cpos() 1977 1978 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1979 unitstart = compunit.offs - COMPUNITHEADERSIZE 1980 if compunit.link != nil { 1981 unitend = compunit.link.offs - COMPUNITHEADERSIZE 1982 } else { 1983 unitend = infoo + infosize 1984 } 1985 1986 // Write .debug_pubnames/types Header (sec 6.1.1) 1987 Thearch.Lput(0) // unit_length (*), will be filled in later. 1988 Thearch.Wput(2) // dwarf version (appendix F) 1989 Thearch.Lput(uint32(unitstart)) // debug_info_offset (of the Comp unit Header) 1990 Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length 1991 1992 for die = compunit.child; die != nil; die = die.link { 1993 if !ispub(die) { 1994 continue 1995 } 1996 Thearch.Lput(uint32(die.offs - unitstart)) 1997 dwa = getattr(die, DW_AT_name) 1998 strnput(dwa.data.(string), int(dwa.value+1)) 1999 } 2000 2001 Thearch.Lput(0) 2002 2003 here = Cpos() 2004 Cseek(sectionstart) 2005 Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field. 2006 Cseek(here) 2007 } 2008 2009 return sectionstart 2010 } 2011 2012 /* 2013 * emit .debug_aranges. _info must have been written before, 2014 * because we need die->offs of dw_globals. 2015 */ 2016 func writearanges() int64 { 2017 var b *DWAttr 2018 var e *DWAttr 2019 var value int64 2020 2021 sectionstart := Cpos() 2022 headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself 2023 2024 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 2025 b = getattr(compunit, DW_AT_low_pc) 2026 if b == nil { 2027 continue 2028 } 2029 e = getattr(compunit, DW_AT_high_pc) 2030 if e == nil { 2031 continue 2032 } 2033 2034 // Write .debug_aranges Header + entry (sec 6.1.2) 2035 Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*) 2036 Thearch.Wput(2) // dwarf version (appendix F) 2037 2038 value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset 2039 if Linkmode == LinkExternal { 2040 adddwarfrel(arangessec, infosym, sectionstart, 4, value) 2041 } else { 2042 Thearch.Lput(uint32(value)) 2043 } 2044 2045 Cput(uint8(Thearch.Ptrsize)) // address_size 2046 Cput(0) // segment_size 2047 strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize 2048 2049 if Linkmode == LinkExternal { 2050 adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value) 2051 } else { 2052 addrput(b.value) 2053 } 2054 2055 addrput(e.value - b.value) 2056 addrput(0) 2057 addrput(0) 2058 } 2059 2060 Cflush() 2061 return sectionstart 2062 } 2063 2064 func writegdbscript() int64 { 2065 sectionstart := Cpos() 2066 2067 if gdbscript != "" { 2068 Cput(1) // magic 1 byte? 2069 strnput(gdbscript, len(gdbscript)+1) 2070 Cflush() 2071 } 2072 2073 return sectionstart 2074 } 2075 2076 func align(size int64) { 2077 if HEADTYPE == obj.Hwindows { // Only Windows PE need section align. 2078 strnput("", int(Rnd(size, PEFILEALIGN)-size)) 2079 } 2080 } 2081 2082 func writedwarfreloc(s *LSym) int64 { 2083 var i int 2084 var r *Reloc 2085 2086 start := Cpos() 2087 for ri := 0; ri < len(s.R); ri++ { 2088 r = &s.R[ri] 2089 if Iself { 2090 i = Thearch.Elfreloc1(r, int64(r.Off)) 2091 } else if HEADTYPE == obj.Hdarwin { 2092 i = Thearch.Machoreloc1(r, int64(r.Off)) 2093 } else { 2094 i = -1 2095 } 2096 if i < 0 { 2097 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) 2098 } 2099 } 2100 2101 return start 2102 } 2103 2104 func addmachodwarfsect(prev *Section, name string) *Section { 2105 sect := addsection(&Segdwarf, name, 04) 2106 sect.Extnum = prev.Extnum + 1 2107 sym := Linklookup(Ctxt, name, 0) 2108 sym.Sect = sect 2109 return sect 2110 } 2111 2112 /* 2113 * This is the main entry point for generating dwarf. After emitting 2114 * the mandatory debug_abbrev section, it calls writelines() to set up 2115 * the per-compilation unit part of the DIE tree, while simultaneously 2116 * emitting the debug_line section. When the final tree contains 2117 * forward references, it will write the debug_info section in 2 2118 * passes. 2119 * 2120 */ 2121 func Dwarfemitdebugsections() { 2122 if Debug['w'] != 0 { // disable dwarf 2123 return 2124 } 2125 2126 if Linkmode == LinkExternal { 2127 if !Iself && HEADTYPE != obj.Hdarwin { 2128 return 2129 } 2130 if HEADTYPE == obj.Hdarwin { 2131 sect := Segdata.Sect 2132 // find the last section. 2133 for sect.Next != nil { 2134 sect = sect.Next 2135 } 2136 sect = addmachodwarfsect(sect, ".debug_abbrev") 2137 sect = addmachodwarfsect(sect, ".debug_line") 2138 sect = addmachodwarfsect(sect, ".debug_frame") 2139 sect = addmachodwarfsect(sect, ".debug_info") 2140 2141 infosym = Linklookup(Ctxt, ".debug_info", 0) 2142 infosym.Hide = 1 2143 2144 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2145 abbrevsym.Hide = 1 2146 2147 linesym = Linklookup(Ctxt, ".debug_line", 0) 2148 linesym.Hide = 1 2149 2150 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2151 framesym.Hide = 1 2152 } 2153 } 2154 2155 // For diagnostic messages. 2156 newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 2157 2158 mkindex(&dwroot) 2159 mkindex(&dwtypes) 2160 mkindex(&dwglobals) 2161 2162 // Some types that must exist to define other ones. 2163 newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>") 2164 2165 newdie(&dwtypes, DW_ABRV_NULLTYPE, "void") 2166 newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer") 2167 2168 die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size 2169 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 2170 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0) 2171 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0) 2172 2173 // Needed by the prettyprinter code for interface inspection. 2174 defgotype(lookup_or_diag("type.runtime._type")) 2175 2176 defgotype(lookup_or_diag("type.runtime.interfacetype")) 2177 defgotype(lookup_or_diag("type.runtime.itab")) 2178 2179 genasmsym(defdwsymb) 2180 2181 writeabbrev() 2182 align(abbrevsize) 2183 writelines() 2184 align(linesize) 2185 writeframes() 2186 align(framesize) 2187 2188 synthesizestringtypes(dwtypes.child) 2189 synthesizeslicetypes(dwtypes.child) 2190 synthesizemaptypes(dwtypes.child) 2191 synthesizechantypes(dwtypes.child) 2192 2193 reversetree(&dwroot.child) 2194 reversetree(&dwtypes.child) 2195 reversetree(&dwglobals.child) 2196 2197 movetomodule(&dwtypes) 2198 movetomodule(&dwglobals) 2199 2200 infoo = Cpos() 2201 writeinfo() 2202 infoe := Cpos() 2203 pubnameso = infoe 2204 pubtypeso = infoe 2205 arangeso = infoe 2206 gdbscripto = infoe 2207 2208 if fwdcount > 0 { 2209 if Debug['v'] != 0 { 2210 fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime()) 2211 } 2212 Cseek(infoo) 2213 writeinfo() 2214 if fwdcount > 0 { 2215 Exitf("dwarf: unresolved references after first dwarf info pass") 2216 } 2217 2218 if infoe != Cpos() { 2219 Exitf("dwarf: inconsistent second dwarf info pass") 2220 } 2221 } 2222 2223 infosize = infoe - infoo 2224 align(infosize) 2225 2226 pubnameso = writepub(ispubname) 2227 pubnamessize = Cpos() - pubnameso 2228 align(pubnamessize) 2229 2230 pubtypeso = writepub(ispubtype) 2231 pubtypessize = Cpos() - pubtypeso 2232 align(pubtypessize) 2233 2234 arangeso = writearanges() 2235 arangessize = Cpos() - arangeso 2236 align(arangessize) 2237 2238 gdbscripto = writegdbscript() 2239 gdbscriptsize = Cpos() - gdbscripto 2240 align(gdbscriptsize) 2241 2242 for Cpos()&7 != 0 { 2243 Cput(0) 2244 } 2245 if HEADTYPE != obj.Hdarwin { 2246 dwarfemitreloc() 2247 } 2248 } 2249 2250 func dwarfemitreloc() { 2251 if Debug['w'] != 0 { // disable dwarf 2252 return 2253 } 2254 inforeloco = writedwarfreloc(infosec) 2255 inforelocsize = Cpos() - inforeloco 2256 align(inforelocsize) 2257 2258 arangesreloco = writedwarfreloc(arangessec) 2259 arangesrelocsize = Cpos() - arangesreloco 2260 align(arangesrelocsize) 2261 2262 linereloco = writedwarfreloc(linesec) 2263 linerelocsize = Cpos() - linereloco 2264 align(linerelocsize) 2265 2266 framereloco = writedwarfreloc(framesec) 2267 framerelocsize = Cpos() - framereloco 2268 align(framerelocsize) 2269 } 2270 2271 /* 2272 * Elf. 2273 */ 2274 const ( 2275 ElfStrDebugAbbrev = iota 2276 ElfStrDebugAranges 2277 ElfStrDebugFrame 2278 ElfStrDebugInfo 2279 ElfStrDebugLine 2280 ElfStrDebugLoc 2281 ElfStrDebugMacinfo 2282 ElfStrDebugPubNames 2283 ElfStrDebugPubTypes 2284 ElfStrDebugRanges 2285 ElfStrDebugStr 2286 ElfStrGDBScripts 2287 ElfStrRelDebugInfo 2288 ElfStrRelDebugAranges 2289 ElfStrRelDebugLine 2290 ElfStrRelDebugFrame 2291 NElfStrDbg 2292 ) 2293 2294 var elfstrdbg [NElfStrDbg]int64 2295 2296 func dwarfaddshstrings(shstrtab *LSym) { 2297 if Debug['w'] != 0 { // disable dwarf 2298 return 2299 } 2300 2301 elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev") 2302 elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges") 2303 elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame") 2304 elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info") 2305 elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line") 2306 elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc") 2307 elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo") 2308 elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames") 2309 elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes") 2310 elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges") 2311 elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str") 2312 elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts") 2313 if Linkmode == LinkExternal { 2314 switch Thearch.Thechar { 2315 case '6', '7', '9': 2316 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info") 2317 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges") 2318 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line") 2319 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame") 2320 default: 2321 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info") 2322 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges") 2323 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line") 2324 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame") 2325 } 2326 2327 infosym = Linklookup(Ctxt, ".debug_info", 0) 2328 infosym.Hide = 1 2329 2330 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2331 abbrevsym.Hide = 1 2332 2333 linesym = Linklookup(Ctxt, ".debug_line", 0) 2334 linesym.Hide = 1 2335 2336 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2337 framesym.Hide = 1 2338 } 2339 } 2340 2341 // Add section symbols for DWARF debug info. This is called before 2342 // dwarfaddelfheaders. 2343 func dwarfaddelfsectionsyms() { 2344 if infosym != nil { 2345 infosympos = Cpos() 2346 putelfsectionsym(infosym, 0) 2347 } 2348 2349 if abbrevsym != nil { 2350 abbrevsympos = Cpos() 2351 putelfsectionsym(abbrevsym, 0) 2352 } 2353 2354 if linesym != nil { 2355 linesympos = Cpos() 2356 putelfsectionsym(linesym, 0) 2357 } 2358 2359 if framesym != nil { 2360 framesympos = Cpos() 2361 putelfsectionsym(framesym, 0) 2362 } 2363 } 2364 2365 func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) { 2366 sh := newElfShdr(elfstrdbg[elfstr]) 2367 switch Thearch.Thechar { 2368 case '6', '7', '9': 2369 sh.type_ = SHT_RELA 2370 default: 2371 sh.type_ = SHT_REL 2372 } 2373 2374 sh.entsize = uint64(Thearch.Ptrsize) * 2 2375 if sh.type_ == SHT_RELA { 2376 sh.entsize += uint64(Thearch.Ptrsize) 2377 } 2378 sh.link = uint32(elfshname(".symtab").shnum) 2379 sh.info = uint32(shdata.shnum) 2380 sh.off = uint64(off) 2381 sh.size = uint64(size) 2382 sh.addralign = uint64(Thearch.Ptrsize) 2383 } 2384 2385 func dwarfaddelfheaders() { 2386 if Debug['w'] != 0 { // disable dwarf 2387 return 2388 } 2389 2390 sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev]) 2391 sh.type_ = SHT_PROGBITS 2392 sh.off = uint64(abbrevo) 2393 sh.size = uint64(abbrevsize) 2394 sh.addralign = 1 2395 if abbrevsympos > 0 { 2396 putelfsymshndx(abbrevsympos, sh.shnum) 2397 } 2398 2399 sh = newElfShdr(elfstrdbg[ElfStrDebugLine]) 2400 sh.type_ = SHT_PROGBITS 2401 sh.off = uint64(lineo) 2402 sh.size = uint64(linesize) 2403 sh.addralign = 1 2404 if linesympos > 0 { 2405 putelfsymshndx(linesympos, sh.shnum) 2406 } 2407 shline := sh 2408 2409 sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]) 2410 sh.type_ = SHT_PROGBITS 2411 sh.off = uint64(frameo) 2412 sh.size = uint64(framesize) 2413 sh.addralign = 1 2414 if framesympos > 0 { 2415 putelfsymshndx(framesympos, sh.shnum) 2416 } 2417 shframe := sh 2418 2419 sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]) 2420 sh.type_ = SHT_PROGBITS 2421 sh.off = uint64(infoo) 2422 sh.size = uint64(infosize) 2423 sh.addralign = 1 2424 if infosympos > 0 { 2425 putelfsymshndx(infosympos, sh.shnum) 2426 } 2427 shinfo := sh 2428 2429 if pubnamessize > 0 { 2430 sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames]) 2431 sh.type_ = SHT_PROGBITS 2432 sh.off = uint64(pubnameso) 2433 sh.size = uint64(pubnamessize) 2434 sh.addralign = 1 2435 } 2436 2437 if pubtypessize > 0 { 2438 sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes]) 2439 sh.type_ = SHT_PROGBITS 2440 sh.off = uint64(pubtypeso) 2441 sh.size = uint64(pubtypessize) 2442 sh.addralign = 1 2443 } 2444 2445 var sharanges *ElfShdr 2446 if arangessize != 0 { 2447 sh := newElfShdr(elfstrdbg[ElfStrDebugAranges]) 2448 sh.type_ = SHT_PROGBITS 2449 sh.off = uint64(arangeso) 2450 sh.size = uint64(arangessize) 2451 sh.addralign = 1 2452 sharanges = sh 2453 } 2454 2455 if gdbscriptsize != 0 { 2456 sh := newElfShdr(elfstrdbg[ElfStrGDBScripts]) 2457 sh.type_ = SHT_PROGBITS 2458 sh.off = uint64(gdbscripto) 2459 sh.size = uint64(gdbscriptsize) 2460 sh.addralign = 1 2461 } 2462 2463 if inforelocsize != 0 { 2464 dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize) 2465 } 2466 2467 if arangesrelocsize != 0 { 2468 dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize) 2469 } 2470 2471 if linerelocsize != 0 { 2472 dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize) 2473 } 2474 2475 if framerelocsize != 0 { 2476 dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize) 2477 } 2478 } 2479 2480 /* 2481 * Macho 2482 */ 2483 func dwarfaddmachoheaders(ms *MachoSeg) { 2484 if Debug['w'] != 0 { // disable dwarf 2485 return 2486 } 2487 2488 // Zero vsize segments won't be loaded in memory, even so they 2489 // have to be page aligned in the file. 2490 fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000) 2491 addr := Segdata.Vaddr + Segdata.Length 2492 2493 nsect := 4 2494 if pubnamessize > 0 { 2495 nsect++ 2496 } 2497 if pubtypessize > 0 { 2498 nsect++ 2499 } 2500 if arangessize > 0 { 2501 nsect++ 2502 } 2503 if gdbscriptsize > 0 { 2504 nsect++ 2505 } 2506 2507 if Linkmode != LinkExternal { 2508 ms = newMachoSeg("__DWARF", nsect) 2509 ms.fileoffset = uint64(fakestart) 2510 ms.filesize = Segdwarf.Filelen 2511 ms.vaddr = addr 2512 } 2513 2514 msect := newMachoSect(ms, "__debug_abbrev", "__DWARF") 2515 msect.off = uint32(abbrevo) 2516 msect.size = uint64(abbrevsize) 2517 msect.addr = addr 2518 addr += msect.size 2519 msect.flag = 0x02000000 2520 if abbrevsym != nil { 2521 abbrevsym.Value = int64(msect.addr) 2522 } 2523 2524 msect = newMachoSect(ms, "__debug_line", "__DWARF") 2525 msect.off = uint32(lineo) 2526 msect.size = uint64(linesize) 2527 msect.addr = addr 2528 addr += msect.size 2529 msect.flag = 0x02000000 2530 if linesym != nil { 2531 linesym.Value = int64(msect.addr) 2532 } 2533 if linerelocsize > 0 { 2534 msect.nreloc = uint32(len(linesec.R)) 2535 msect.reloc = uint32(linereloco) 2536 } 2537 2538 msect = newMachoSect(ms, "__debug_frame", "__DWARF") 2539 msect.off = uint32(frameo) 2540 msect.size = uint64(framesize) 2541 msect.addr = addr 2542 addr += msect.size 2543 msect.flag = 0x02000000 2544 if framesym != nil { 2545 framesym.Value = int64(msect.addr) 2546 } 2547 if framerelocsize > 0 { 2548 msect.nreloc = uint32(len(framesec.R)) 2549 msect.reloc = uint32(framereloco) 2550 } 2551 2552 msect = newMachoSect(ms, "__debug_info", "__DWARF") 2553 msect.off = uint32(infoo) 2554 msect.size = uint64(infosize) 2555 msect.addr = addr 2556 addr += msect.size 2557 msect.flag = 0x02000000 2558 if infosym != nil { 2559 infosym.Value = int64(msect.addr) 2560 } 2561 if inforelocsize > 0 { 2562 msect.nreloc = uint32(len(infosec.R)) 2563 msect.reloc = uint32(inforeloco) 2564 } 2565 2566 if pubnamessize > 0 { 2567 msect := newMachoSect(ms, "__debug_pubnames", "__DWARF") 2568 msect.off = uint32(pubnameso) 2569 msect.size = uint64(pubnamessize) 2570 msect.addr = addr 2571 addr += msect.size 2572 msect.flag = 0x02000000 2573 } 2574 2575 if pubtypessize > 0 { 2576 msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF") 2577 msect.off = uint32(pubtypeso) 2578 msect.size = uint64(pubtypessize) 2579 msect.addr = addr 2580 addr += msect.size 2581 msect.flag = 0x02000000 2582 } 2583 2584 if arangessize > 0 { 2585 msect := newMachoSect(ms, "__debug_aranges", "__DWARF") 2586 msect.off = uint32(arangeso) 2587 msect.size = uint64(arangessize) 2588 msect.addr = addr 2589 addr += msect.size 2590 msect.flag = 0x02000000 2591 if arangesrelocsize > 0 { 2592 msect.nreloc = uint32(len(arangessec.R)) 2593 msect.reloc = uint32(arangesreloco) 2594 } 2595 } 2596 2597 // TODO(lvd) fix gdb/python to load MachO (16 char section name limit) 2598 if gdbscriptsize > 0 { 2599 msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF") 2600 msect.off = uint32(gdbscripto) 2601 msect.size = uint64(gdbscriptsize) 2602 msect.addr = addr 2603 addr += msect.size 2604 msect.flag = 0x02000000 2605 } 2606 } 2607 2608 /* 2609 * Windows PE 2610 */ 2611 func dwarfaddpeheaders() { 2612 if Debug['w'] != 0 { // disable dwarf 2613 return 2614 } 2615 2616 newPEDWARFSection(".debug_abbrev", abbrevsize) 2617 newPEDWARFSection(".debug_line", linesize) 2618 newPEDWARFSection(".debug_frame", framesize) 2619 newPEDWARFSection(".debug_info", infosize) 2620 newPEDWARFSection(".debug_pubnames", pubnamessize) 2621 newPEDWARFSection(".debug_pubtypes", pubtypessize) 2622 newPEDWARFSection(".debug_aranges", arangessize) 2623 newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize) 2624 } 2625