github.com/aloncn/graphics-go@v0.0.1/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 // The first tuple is aligned to a multiple of the size of a single tuple 1950 // (twice the size of an address) 1951 headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize*2))) // don't count unit_length field itself 1952 1953 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1954 b := getattr(compunit, DW_AT_low_pc) 1955 if b == nil { 1956 continue 1957 } 1958 e := getattr(compunit, DW_AT_high_pc) 1959 if e == nil { 1960 continue 1961 } 1962 1963 // Write .debug_aranges Header + entry (sec 6.1.2) 1964 Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*) 1965 Thearch.Wput(2) // dwarf version (appendix F) 1966 1967 value := compunit.offs - COMPUNITHEADERSIZE // debug_info_offset 1968 if Linkmode == LinkExternal { 1969 adddwarfrel(arangessec, infosym, sectionstart, 4, value) 1970 } else { 1971 Thearch.Lput(uint32(value)) 1972 } 1973 1974 Cput(uint8(Thearch.Ptrsize)) // address_size 1975 Cput(0) // segment_size 1976 strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize 1977 1978 if Linkmode == LinkExternal { 1979 adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value) 1980 } else { 1981 addrput(b.value) 1982 } 1983 1984 addrput(e.value - b.value) 1985 addrput(0) 1986 addrput(0) 1987 } 1988 1989 Cflush() 1990 return sectionstart 1991 } 1992 1993 func writegdbscript() int64 { 1994 sectionstart := Cpos() 1995 1996 if gdbscript != "" { 1997 Cput(1) // magic 1 byte? 1998 strnput(gdbscript, len(gdbscript)+1) 1999 Cflush() 2000 } 2001 2002 return sectionstart 2003 } 2004 2005 func align(size int64) { 2006 if HEADTYPE == obj.Hwindows { // Only Windows PE need section align. 2007 strnput("", int(Rnd(size, PEFILEALIGN)-size)) 2008 } 2009 } 2010 2011 func writedwarfreloc(s *LSym) int64 { 2012 start := Cpos() 2013 for ri := 0; ri < len(s.R); ri++ { 2014 r := &s.R[ri] 2015 i := -1 2016 if Iself { 2017 i = Thearch.Elfreloc1(r, int64(r.Off)) 2018 } else if HEADTYPE == obj.Hdarwin { 2019 i = Thearch.Machoreloc1(r, int64(r.Off)) 2020 } 2021 if i < 0 { 2022 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) 2023 } 2024 } 2025 2026 return start 2027 } 2028 2029 func addmachodwarfsect(prev *Section, name string) *Section { 2030 sect := addsection(&Segdwarf, name, 04) 2031 sect.Extnum = prev.Extnum + 1 2032 sym := Linklookup(Ctxt, name, 0) 2033 sym.Sect = sect 2034 return sect 2035 } 2036 2037 /* 2038 * This is the main entry point for generating dwarf. After emitting 2039 * the mandatory debug_abbrev section, it calls writelines() to set up 2040 * the per-compilation unit part of the DIE tree, while simultaneously 2041 * emitting the debug_line section. When the final tree contains 2042 * forward references, it will write the debug_info section in 2 2043 * passes. 2044 * 2045 */ 2046 func Dwarfemitdebugsections() { 2047 if Debug['w'] != 0 { // disable dwarf 2048 return 2049 } 2050 2051 if Linkmode == LinkExternal { 2052 if !Iself && HEADTYPE != obj.Hdarwin { 2053 return 2054 } 2055 if HEADTYPE == obj.Hdarwin { 2056 sect := Segdata.Sect 2057 // find the last section. 2058 for sect.Next != nil { 2059 sect = sect.Next 2060 } 2061 sect = addmachodwarfsect(sect, ".debug_abbrev") 2062 sect = addmachodwarfsect(sect, ".debug_line") 2063 sect = addmachodwarfsect(sect, ".debug_frame") 2064 sect = addmachodwarfsect(sect, ".debug_info") 2065 2066 infosym = Linklookup(Ctxt, ".debug_info", 0) 2067 infosym.Hide = 1 2068 2069 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2070 abbrevsym.Hide = 1 2071 2072 linesym = Linklookup(Ctxt, ".debug_line", 0) 2073 linesym.Hide = 1 2074 2075 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2076 framesym.Hide = 1 2077 } 2078 } 2079 2080 // For diagnostic messages. 2081 newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 2082 2083 mkindex(&dwroot) 2084 mkindex(&dwtypes) 2085 mkindex(&dwglobals) 2086 2087 // Some types that must exist to define other ones. 2088 newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>") 2089 2090 newdie(&dwtypes, DW_ABRV_NULLTYPE, "void") 2091 newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer") 2092 2093 die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size 2094 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 2095 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0) 2096 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0) 2097 2098 // Needed by the prettyprinter code for interface inspection. 2099 defgotype(lookup_or_diag("type.runtime._type")) 2100 2101 defgotype(lookup_or_diag("type.runtime.interfacetype")) 2102 defgotype(lookup_or_diag("type.runtime.itab")) 2103 2104 genasmsym(defdwsymb) 2105 2106 writeabbrev() 2107 align(abbrevsize) 2108 writelines() 2109 align(linesize) 2110 writeframes() 2111 align(framesize) 2112 2113 synthesizestringtypes(dwtypes.child) 2114 synthesizeslicetypes(dwtypes.child) 2115 synthesizemaptypes(dwtypes.child) 2116 synthesizechantypes(dwtypes.child) 2117 2118 reversetree(&dwroot.child) 2119 reversetree(&dwtypes.child) 2120 reversetree(&dwglobals.child) 2121 2122 movetomodule(&dwtypes) 2123 movetomodule(&dwglobals) 2124 2125 infoo = Cpos() 2126 writeinfo() 2127 infoe := Cpos() 2128 pubnameso = infoe 2129 pubtypeso = infoe 2130 arangeso = infoe 2131 gdbscripto = infoe 2132 2133 if fwdcount > 0 { 2134 if Debug['v'] != 0 { 2135 fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime()) 2136 } 2137 Cseek(infoo) 2138 writeinfo() 2139 if fwdcount > 0 { 2140 Exitf("dwarf: unresolved references after first dwarf info pass") 2141 } 2142 2143 if infoe != Cpos() { 2144 Exitf("dwarf: inconsistent second dwarf info pass") 2145 } 2146 } 2147 2148 infosize = infoe - infoo 2149 align(infosize) 2150 2151 pubnameso = writepub(ispubname) 2152 pubnamessize = Cpos() - pubnameso 2153 align(pubnamessize) 2154 2155 pubtypeso = writepub(ispubtype) 2156 pubtypessize = Cpos() - pubtypeso 2157 align(pubtypessize) 2158 2159 arangeso = writearanges() 2160 arangessize = Cpos() - arangeso 2161 align(arangessize) 2162 2163 gdbscripto = writegdbscript() 2164 gdbscriptsize = Cpos() - gdbscripto 2165 align(gdbscriptsize) 2166 2167 for Cpos()&7 != 0 { 2168 Cput(0) 2169 } 2170 if HEADTYPE != obj.Hdarwin { 2171 dwarfemitreloc() 2172 } 2173 } 2174 2175 func dwarfemitreloc() { 2176 if Debug['w'] != 0 { // disable dwarf 2177 return 2178 } 2179 inforeloco = writedwarfreloc(infosec) 2180 inforelocsize = Cpos() - inforeloco 2181 align(inforelocsize) 2182 2183 arangesreloco = writedwarfreloc(arangessec) 2184 arangesrelocsize = Cpos() - arangesreloco 2185 align(arangesrelocsize) 2186 2187 linereloco = writedwarfreloc(linesec) 2188 linerelocsize = Cpos() - linereloco 2189 align(linerelocsize) 2190 2191 framereloco = writedwarfreloc(framesec) 2192 framerelocsize = Cpos() - framereloco 2193 align(framerelocsize) 2194 } 2195 2196 /* 2197 * Elf. 2198 */ 2199 const ( 2200 ElfStrDebugAbbrev = iota 2201 ElfStrDebugAranges 2202 ElfStrDebugFrame 2203 ElfStrDebugInfo 2204 ElfStrDebugLine 2205 ElfStrDebugLoc 2206 ElfStrDebugMacinfo 2207 ElfStrDebugPubNames 2208 ElfStrDebugPubTypes 2209 ElfStrDebugRanges 2210 ElfStrDebugStr 2211 ElfStrGDBScripts 2212 ElfStrRelDebugInfo 2213 ElfStrRelDebugAranges 2214 ElfStrRelDebugLine 2215 ElfStrRelDebugFrame 2216 NElfStrDbg 2217 ) 2218 2219 var elfstrdbg [NElfStrDbg]int64 2220 2221 func dwarfaddshstrings(shstrtab *LSym) { 2222 if Debug['w'] != 0 { // disable dwarf 2223 return 2224 } 2225 2226 elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev") 2227 elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges") 2228 elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame") 2229 elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info") 2230 elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line") 2231 elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc") 2232 elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo") 2233 elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames") 2234 elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes") 2235 elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges") 2236 elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str") 2237 elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts") 2238 if Linkmode == LinkExternal { 2239 switch Thearch.Thechar { 2240 case '0', '6', '7', '9': 2241 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info") 2242 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges") 2243 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line") 2244 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame") 2245 default: 2246 elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info") 2247 elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges") 2248 elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line") 2249 elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame") 2250 } 2251 2252 infosym = Linklookup(Ctxt, ".debug_info", 0) 2253 infosym.Hide = 1 2254 2255 abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0) 2256 abbrevsym.Hide = 1 2257 2258 linesym = Linklookup(Ctxt, ".debug_line", 0) 2259 linesym.Hide = 1 2260 2261 framesym = Linklookup(Ctxt, ".debug_frame", 0) 2262 framesym.Hide = 1 2263 } 2264 } 2265 2266 // Add section symbols for DWARF debug info. This is called before 2267 // dwarfaddelfheaders. 2268 func dwarfaddelfsectionsyms() { 2269 if infosym != nil { 2270 infosympos = Cpos() 2271 putelfsectionsym(infosym, 0) 2272 } 2273 2274 if abbrevsym != nil { 2275 abbrevsympos = Cpos() 2276 putelfsectionsym(abbrevsym, 0) 2277 } 2278 2279 if linesym != nil { 2280 linesympos = Cpos() 2281 putelfsectionsym(linesym, 0) 2282 } 2283 2284 if framesym != nil { 2285 framesympos = Cpos() 2286 putelfsectionsym(framesym, 0) 2287 } 2288 } 2289 2290 func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) { 2291 sh := newElfShdr(elfstrdbg[elfstr]) 2292 switch Thearch.Thechar { 2293 case '0', '6', '7', '9': 2294 sh.type_ = SHT_RELA 2295 default: 2296 sh.type_ = SHT_REL 2297 } 2298 2299 sh.entsize = uint64(Thearch.Ptrsize) * 2 2300 if sh.type_ == SHT_RELA { 2301 sh.entsize += uint64(Thearch.Ptrsize) 2302 } 2303 sh.link = uint32(elfshname(".symtab").shnum) 2304 sh.info = uint32(shdata.shnum) 2305 sh.off = uint64(off) 2306 sh.size = uint64(size) 2307 sh.addralign = uint64(Thearch.Ptrsize) 2308 } 2309 2310 func dwarfaddelfheaders() { 2311 if Debug['w'] != 0 { // disable dwarf 2312 return 2313 } 2314 2315 sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev]) 2316 sh.type_ = SHT_PROGBITS 2317 sh.off = uint64(abbrevo) 2318 sh.size = uint64(abbrevsize) 2319 sh.addralign = 1 2320 if abbrevsympos > 0 { 2321 putelfsymshndx(abbrevsympos, sh.shnum) 2322 } 2323 2324 sh = newElfShdr(elfstrdbg[ElfStrDebugLine]) 2325 sh.type_ = SHT_PROGBITS 2326 sh.off = uint64(lineo) 2327 sh.size = uint64(linesize) 2328 sh.addralign = 1 2329 if linesympos > 0 { 2330 putelfsymshndx(linesympos, sh.shnum) 2331 } 2332 shline := sh 2333 2334 sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]) 2335 sh.type_ = SHT_PROGBITS 2336 sh.off = uint64(frameo) 2337 sh.size = uint64(framesize) 2338 sh.addralign = 1 2339 if framesympos > 0 { 2340 putelfsymshndx(framesympos, sh.shnum) 2341 } 2342 shframe := sh 2343 2344 sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]) 2345 sh.type_ = SHT_PROGBITS 2346 sh.off = uint64(infoo) 2347 sh.size = uint64(infosize) 2348 sh.addralign = 1 2349 if infosympos > 0 { 2350 putelfsymshndx(infosympos, sh.shnum) 2351 } 2352 shinfo := sh 2353 2354 if pubnamessize > 0 { 2355 sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames]) 2356 sh.type_ = SHT_PROGBITS 2357 sh.off = uint64(pubnameso) 2358 sh.size = uint64(pubnamessize) 2359 sh.addralign = 1 2360 } 2361 2362 if pubtypessize > 0 { 2363 sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes]) 2364 sh.type_ = SHT_PROGBITS 2365 sh.off = uint64(pubtypeso) 2366 sh.size = uint64(pubtypessize) 2367 sh.addralign = 1 2368 } 2369 2370 var sharanges *ElfShdr 2371 if arangessize != 0 { 2372 sh := newElfShdr(elfstrdbg[ElfStrDebugAranges]) 2373 sh.type_ = SHT_PROGBITS 2374 sh.off = uint64(arangeso) 2375 sh.size = uint64(arangessize) 2376 sh.addralign = 1 2377 sharanges = sh 2378 } 2379 2380 if gdbscriptsize != 0 { 2381 sh := newElfShdr(elfstrdbg[ElfStrGDBScripts]) 2382 sh.type_ = SHT_PROGBITS 2383 sh.off = uint64(gdbscripto) 2384 sh.size = uint64(gdbscriptsize) 2385 sh.addralign = 1 2386 } 2387 2388 if inforelocsize != 0 { 2389 dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize) 2390 } 2391 2392 if arangesrelocsize != 0 { 2393 dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize) 2394 } 2395 2396 if linerelocsize != 0 { 2397 dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize) 2398 } 2399 2400 if framerelocsize != 0 { 2401 dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize) 2402 } 2403 } 2404 2405 /* 2406 * Macho 2407 */ 2408 func dwarfaddmachoheaders(ms *MachoSeg) { 2409 if Debug['w'] != 0 { // disable dwarf 2410 return 2411 } 2412 2413 // Zero vsize segments won't be loaded in memory, even so they 2414 // have to be page aligned in the file. 2415 fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000) 2416 addr := Segdata.Vaddr + Segdata.Length 2417 2418 nsect := 4 2419 if pubnamessize > 0 { 2420 nsect++ 2421 } 2422 if pubtypessize > 0 { 2423 nsect++ 2424 } 2425 if arangessize > 0 { 2426 nsect++ 2427 } 2428 if gdbscriptsize > 0 { 2429 nsect++ 2430 } 2431 2432 if Linkmode != LinkExternal { 2433 ms = newMachoSeg("__DWARF", nsect) 2434 ms.fileoffset = uint64(fakestart) 2435 ms.filesize = Segdwarf.Filelen 2436 ms.vaddr = addr 2437 } 2438 2439 msect := newMachoSect(ms, "__debug_abbrev", "__DWARF") 2440 msect.off = uint32(abbrevo) 2441 msect.size = uint64(abbrevsize) 2442 msect.addr = addr 2443 addr += msect.size 2444 msect.flag = 0x02000000 2445 if abbrevsym != nil { 2446 abbrevsym.Value = int64(msect.addr) 2447 } 2448 2449 msect = newMachoSect(ms, "__debug_line", "__DWARF") 2450 msect.off = uint32(lineo) 2451 msect.size = uint64(linesize) 2452 msect.addr = addr 2453 addr += msect.size 2454 msect.flag = 0x02000000 2455 if linesym != nil { 2456 linesym.Value = int64(msect.addr) 2457 } 2458 if linerelocsize > 0 { 2459 msect.nreloc = uint32(len(linesec.R)) 2460 msect.reloc = uint32(linereloco) 2461 } 2462 2463 msect = newMachoSect(ms, "__debug_frame", "__DWARF") 2464 msect.off = uint32(frameo) 2465 msect.size = uint64(framesize) 2466 msect.addr = addr 2467 addr += msect.size 2468 msect.flag = 0x02000000 2469 if framesym != nil { 2470 framesym.Value = int64(msect.addr) 2471 } 2472 if framerelocsize > 0 { 2473 msect.nreloc = uint32(len(framesec.R)) 2474 msect.reloc = uint32(framereloco) 2475 } 2476 2477 msect = newMachoSect(ms, "__debug_info", "__DWARF") 2478 msect.off = uint32(infoo) 2479 msect.size = uint64(infosize) 2480 msect.addr = addr 2481 addr += msect.size 2482 msect.flag = 0x02000000 2483 if infosym != nil { 2484 infosym.Value = int64(msect.addr) 2485 } 2486 if inforelocsize > 0 { 2487 msect.nreloc = uint32(len(infosec.R)) 2488 msect.reloc = uint32(inforeloco) 2489 } 2490 2491 if pubnamessize > 0 { 2492 msect := newMachoSect(ms, "__debug_pubnames", "__DWARF") 2493 msect.off = uint32(pubnameso) 2494 msect.size = uint64(pubnamessize) 2495 msect.addr = addr 2496 addr += msect.size 2497 msect.flag = 0x02000000 2498 } 2499 2500 if pubtypessize > 0 { 2501 msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF") 2502 msect.off = uint32(pubtypeso) 2503 msect.size = uint64(pubtypessize) 2504 msect.addr = addr 2505 addr += msect.size 2506 msect.flag = 0x02000000 2507 } 2508 2509 if arangessize > 0 { 2510 msect := newMachoSect(ms, "__debug_aranges", "__DWARF") 2511 msect.off = uint32(arangeso) 2512 msect.size = uint64(arangessize) 2513 msect.addr = addr 2514 addr += msect.size 2515 msect.flag = 0x02000000 2516 if arangesrelocsize > 0 { 2517 msect.nreloc = uint32(len(arangessec.R)) 2518 msect.reloc = uint32(arangesreloco) 2519 } 2520 } 2521 2522 // TODO(lvd) fix gdb/python to load MachO (16 char section name limit) 2523 if gdbscriptsize > 0 { 2524 msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF") 2525 msect.off = uint32(gdbscripto) 2526 msect.size = uint64(gdbscriptsize) 2527 msect.addr = addr 2528 addr += msect.size 2529 msect.flag = 0x02000000 2530 } 2531 } 2532 2533 /* 2534 * Windows PE 2535 */ 2536 func dwarfaddpeheaders() { 2537 if Debug['w'] != 0 { // disable dwarf 2538 return 2539 } 2540 2541 newPEDWARFSection(".debug_abbrev", abbrevsize) 2542 newPEDWARFSection(".debug_line", linesize) 2543 newPEDWARFSection(".debug_frame", framesize) 2544 newPEDWARFSection(".debug_info", infosize) 2545 newPEDWARFSection(".debug_pubnames", pubnamessize) 2546 newPEDWARFSection(".debug_pubtypes", pubtypessize) 2547 newPEDWARFSection(".debug_aranges", arangessize) 2548 newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize) 2549 }