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