github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 "log" 21 "os" 22 "strings" 23 ) 24 25 const infoprefix = "go.dwarf.info." 26 27 /* 28 * Offsets and sizes of the debug_* sections in the cout file. 29 */ 30 var abbrevsym *LSym 31 var arangessec *LSym 32 var framesec *LSym 33 var infosec *LSym 34 var linesec *LSym 35 36 var gdbscript string 37 38 /* 39 * Basic I/O 40 */ 41 func addrput(s *LSym, addr int64) { 42 switch SysArch.PtrSize { 43 case 4: 44 Adduint32(Ctxt, s, uint32(addr)) 45 46 case 8: 47 Adduint64(Ctxt, s, uint64(addr)) 48 } 49 } 50 51 func appendUleb128(b []byte, v uint64) []byte { 52 for { 53 c := uint8(v & 0x7f) 54 v >>= 7 55 if v != 0 { 56 c |= 0x80 57 } 58 b = append(b, c) 59 if c&0x80 == 0 { 60 break 61 } 62 } 63 return b 64 } 65 66 func appendSleb128(b []byte, v int64) []byte { 67 for { 68 c := uint8(v & 0x7f) 69 s := uint8(v & 0x40) 70 v >>= 7 71 if (v != -1 || s == 0) && (v != 0 || s != 0) { 72 c |= 0x80 73 } 74 b = append(b, c) 75 if c&0x80 == 0 { 76 break 77 } 78 } 79 return b 80 } 81 82 var encbuf [10]byte 83 84 func uleb128put(s *LSym, v int64) { 85 b := appendUleb128(encbuf[:0], uint64(v)) 86 Addbytes(Ctxt, s, b) 87 } 88 89 func sleb128put(s *LSym, v int64) { 90 b := appendSleb128(encbuf[:0], v) 91 Addbytes(Ctxt, s, b) 92 } 93 94 /* 95 * Defining Abbrevs. This is hardcoded, and there will be 96 * only a handful of them. The DWARF spec places no restriction on 97 * the ordering of attributes in the Abbrevs and DIEs, and we will 98 * always write them out in the order of declaration in the abbrev. 99 */ 100 type DWAttrForm struct { 101 attr uint16 102 form uint8 103 } 104 105 // Go-specific type attributes. 106 const ( 107 DW_AT_go_kind = 0x2900 108 DW_AT_go_key = 0x2901 109 DW_AT_go_elem = 0x2902 110 111 DW_AT_internal_location = 253 // params and locals; not emitted 112 ) 113 114 // Index into the abbrevs table below. 115 // Keep in sync with ispubname() and ispubtype() below. 116 // ispubtype considers >= NULLTYPE public 117 const ( 118 DW_ABRV_NULL = iota 119 DW_ABRV_COMPUNIT 120 DW_ABRV_FUNCTION 121 DW_ABRV_VARIABLE 122 DW_ABRV_AUTO 123 DW_ABRV_PARAM 124 DW_ABRV_STRUCTFIELD 125 DW_ABRV_FUNCTYPEPARAM 126 DW_ABRV_DOTDOTDOT 127 DW_ABRV_ARRAYRANGE 128 DW_ABRV_NULLTYPE 129 DW_ABRV_BASETYPE 130 DW_ABRV_ARRAYTYPE 131 DW_ABRV_CHANTYPE 132 DW_ABRV_FUNCTYPE 133 DW_ABRV_IFACETYPE 134 DW_ABRV_MAPTYPE 135 DW_ABRV_PTRTYPE 136 DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. 137 DW_ABRV_SLICETYPE 138 DW_ABRV_STRINGTYPE 139 DW_ABRV_STRUCTTYPE 140 DW_ABRV_TYPEDECL 141 DW_NABRV 142 ) 143 144 type DWAbbrev struct { 145 tag uint8 146 children uint8 147 attr []DWAttrForm 148 } 149 150 var abbrevs = [DW_NABRV]DWAbbrev{ 151 /* The mandatory DW_ABRV_NULL entry. */ 152 {0, 0, []DWAttrForm{}}, 153 154 /* COMPUNIT */ 155 { 156 DW_TAG_compile_unit, 157 DW_CHILDREN_yes, 158 []DWAttrForm{ 159 {DW_AT_name, DW_FORM_string}, 160 {DW_AT_language, DW_FORM_data1}, 161 {DW_AT_low_pc, DW_FORM_addr}, 162 {DW_AT_high_pc, DW_FORM_addr}, 163 {DW_AT_stmt_list, DW_FORM_data4}, 164 {DW_AT_comp_dir, DW_FORM_string}, 165 }, 166 }, 167 168 /* FUNCTION */ 169 { 170 DW_TAG_subprogram, 171 DW_CHILDREN_yes, 172 []DWAttrForm{ 173 {DW_AT_name, DW_FORM_string}, 174 {DW_AT_low_pc, DW_FORM_addr}, 175 {DW_AT_high_pc, DW_FORM_addr}, 176 {DW_AT_external, DW_FORM_flag}, 177 }, 178 }, 179 180 /* VARIABLE */ 181 { 182 DW_TAG_variable, 183 DW_CHILDREN_no, 184 []DWAttrForm{ 185 {DW_AT_name, DW_FORM_string}, 186 {DW_AT_location, DW_FORM_block1}, 187 {DW_AT_type, DW_FORM_ref_addr}, 188 {DW_AT_external, DW_FORM_flag}, 189 }, 190 }, 191 192 /* AUTO */ 193 { 194 DW_TAG_variable, 195 DW_CHILDREN_no, 196 []DWAttrForm{ 197 {DW_AT_name, DW_FORM_string}, 198 {DW_AT_location, DW_FORM_block1}, 199 {DW_AT_type, DW_FORM_ref_addr}, 200 }, 201 }, 202 203 /* PARAM */ 204 { 205 DW_TAG_formal_parameter, 206 DW_CHILDREN_no, 207 []DWAttrForm{ 208 {DW_AT_name, DW_FORM_string}, 209 {DW_AT_location, DW_FORM_block1}, 210 {DW_AT_type, DW_FORM_ref_addr}, 211 }, 212 }, 213 214 /* STRUCTFIELD */ 215 { 216 DW_TAG_member, 217 DW_CHILDREN_no, 218 []DWAttrForm{ 219 {DW_AT_name, DW_FORM_string}, 220 {DW_AT_data_member_location, DW_FORM_block1}, 221 {DW_AT_type, DW_FORM_ref_addr}, 222 }, 223 }, 224 225 /* FUNCTYPEPARAM */ 226 { 227 DW_TAG_formal_parameter, 228 DW_CHILDREN_no, 229 230 // No name! 231 []DWAttrForm{ 232 {DW_AT_type, DW_FORM_ref_addr}, 233 }, 234 }, 235 236 /* DOTDOTDOT */ 237 { 238 DW_TAG_unspecified_parameters, 239 DW_CHILDREN_no, 240 []DWAttrForm{}, 241 }, 242 243 /* ARRAYRANGE */ 244 { 245 DW_TAG_subrange_type, 246 DW_CHILDREN_no, 247 248 // No name! 249 []DWAttrForm{ 250 {DW_AT_type, DW_FORM_ref_addr}, 251 {DW_AT_count, DW_FORM_udata}, 252 }, 253 }, 254 255 // Below here are the types considered public by ispubtype 256 /* NULLTYPE */ 257 { 258 DW_TAG_unspecified_type, 259 DW_CHILDREN_no, 260 []DWAttrForm{ 261 {DW_AT_name, DW_FORM_string}, 262 }, 263 }, 264 265 /* BASETYPE */ 266 { 267 DW_TAG_base_type, 268 DW_CHILDREN_no, 269 []DWAttrForm{ 270 {DW_AT_name, DW_FORM_string}, 271 {DW_AT_encoding, DW_FORM_data1}, 272 {DW_AT_byte_size, DW_FORM_data1}, 273 {DW_AT_go_kind, DW_FORM_data1}, 274 }, 275 }, 276 277 /* ARRAYTYPE */ 278 // child is subrange with upper bound 279 { 280 DW_TAG_array_type, 281 DW_CHILDREN_yes, 282 []DWAttrForm{ 283 {DW_AT_name, DW_FORM_string}, 284 {DW_AT_type, DW_FORM_ref_addr}, 285 {DW_AT_byte_size, DW_FORM_udata}, 286 {DW_AT_go_kind, DW_FORM_data1}, 287 }, 288 }, 289 290 /* CHANTYPE */ 291 { 292 DW_TAG_typedef, 293 DW_CHILDREN_no, 294 []DWAttrForm{ 295 {DW_AT_name, DW_FORM_string}, 296 {DW_AT_type, DW_FORM_ref_addr}, 297 {DW_AT_go_kind, DW_FORM_data1}, 298 {DW_AT_go_elem, DW_FORM_ref_addr}, 299 }, 300 }, 301 302 /* FUNCTYPE */ 303 { 304 DW_TAG_subroutine_type, 305 DW_CHILDREN_yes, 306 []DWAttrForm{ 307 {DW_AT_name, DW_FORM_string}, 308 // {DW_AT_type, DW_FORM_ref_addr}, 309 {DW_AT_go_kind, DW_FORM_data1}, 310 }, 311 }, 312 313 /* IFACETYPE */ 314 { 315 DW_TAG_typedef, 316 DW_CHILDREN_yes, 317 []DWAttrForm{ 318 {DW_AT_name, DW_FORM_string}, 319 {DW_AT_type, DW_FORM_ref_addr}, 320 {DW_AT_go_kind, DW_FORM_data1}, 321 }, 322 }, 323 324 /* MAPTYPE */ 325 { 326 DW_TAG_typedef, 327 DW_CHILDREN_no, 328 []DWAttrForm{ 329 {DW_AT_name, DW_FORM_string}, 330 {DW_AT_type, DW_FORM_ref_addr}, 331 {DW_AT_go_kind, DW_FORM_data1}, 332 {DW_AT_go_key, DW_FORM_ref_addr}, 333 {DW_AT_go_elem, DW_FORM_ref_addr}, 334 }, 335 }, 336 337 /* PTRTYPE */ 338 { 339 DW_TAG_pointer_type, 340 DW_CHILDREN_no, 341 []DWAttrForm{ 342 {DW_AT_name, DW_FORM_string}, 343 {DW_AT_type, DW_FORM_ref_addr}, 344 {DW_AT_go_kind, DW_FORM_data1}, 345 }, 346 }, 347 348 /* BARE_PTRTYPE */ 349 { 350 DW_TAG_pointer_type, 351 DW_CHILDREN_no, 352 []DWAttrForm{ 353 {DW_AT_name, DW_FORM_string}, 354 }, 355 }, 356 357 /* SLICETYPE */ 358 { 359 DW_TAG_structure_type, 360 DW_CHILDREN_yes, 361 []DWAttrForm{ 362 {DW_AT_name, DW_FORM_string}, 363 {DW_AT_byte_size, DW_FORM_udata}, 364 {DW_AT_go_kind, DW_FORM_data1}, 365 {DW_AT_go_elem, DW_FORM_ref_addr}, 366 }, 367 }, 368 369 /* STRINGTYPE */ 370 { 371 DW_TAG_structure_type, 372 DW_CHILDREN_yes, 373 []DWAttrForm{ 374 {DW_AT_name, DW_FORM_string}, 375 {DW_AT_byte_size, DW_FORM_udata}, 376 {DW_AT_go_kind, DW_FORM_data1}, 377 }, 378 }, 379 380 /* STRUCTTYPE */ 381 { 382 DW_TAG_structure_type, 383 DW_CHILDREN_yes, 384 []DWAttrForm{ 385 {DW_AT_name, DW_FORM_string}, 386 {DW_AT_byte_size, DW_FORM_udata}, 387 {DW_AT_go_kind, DW_FORM_data1}, 388 }, 389 }, 390 391 /* TYPEDECL */ 392 { 393 DW_TAG_typedef, 394 DW_CHILDREN_no, 395 []DWAttrForm{ 396 {DW_AT_name, DW_FORM_string}, 397 {DW_AT_type, DW_FORM_ref_addr}, 398 }, 399 }, 400 } 401 402 var dwarfp *LSym 403 404 func writeabbrev() *LSym { 405 s := Linklookup(Ctxt, ".debug_abbrev", 0) 406 s.Type = obj.SDWARFSECT 407 abbrevsym = s 408 409 for i := 1; i < DW_NABRV; i++ { 410 // See section 7.5.3 411 uleb128put(s, int64(i)) 412 413 uleb128put(s, int64(abbrevs[i].tag)) 414 Adduint8(Ctxt, s, abbrevs[i].children) 415 for _, f := range abbrevs[i].attr { 416 uleb128put(s, int64(f.attr)) 417 uleb128put(s, int64(f.form)) 418 } 419 uleb128put(s, 0) 420 uleb128put(s, 0) 421 } 422 423 Adduint8(Ctxt, s, 0) 424 return s 425 } 426 427 /* 428 * Debugging Information Entries and their attributes. 429 */ 430 431 // For DW_CLS_string and _block, value should contain the length, and 432 // data the data, for _reference, value is 0 and data is a DWDie* to 433 // the referenced instance, for all others, value is the whole thing 434 // and data is null. 435 436 type DWAttr struct { 437 link *DWAttr 438 atr uint16 // DW_AT_ 439 cls uint8 // DW_CLS_ 440 value int64 441 data interface{} 442 } 443 444 type DWDie struct { 445 abbrev int 446 link *DWDie 447 child *DWDie 448 attr *DWAttr 449 sym *LSym 450 } 451 452 /* 453 * Root DIEs for compilation units, types and global variables. 454 */ 455 var dwroot DWDie 456 457 var dwtypes DWDie 458 459 var dwglobals DWDie 460 461 func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr { 462 a := new(DWAttr) 463 a.link = die.attr 464 die.attr = a 465 a.atr = attr 466 a.cls = uint8(cls) 467 a.value = value 468 a.data = data 469 return a 470 } 471 472 // Each DIE (except the root ones) has at least 1 attribute: its 473 // name. getattr moves the desired one to the front so 474 // frequently searched ones are found faster. 475 func getattr(die *DWDie, attr uint16) *DWAttr { 476 if die.attr.atr == attr { 477 return die.attr 478 } 479 480 a := die.attr 481 b := a.link 482 for b != nil { 483 if b.atr == attr { 484 a.link = b.link 485 b.link = die.attr 486 die.attr = b 487 return b 488 } 489 490 a = b 491 b = b.link 492 } 493 494 return nil 495 } 496 497 // Every DIE has at least a DW_AT_name attribute (but it will only be 498 // written out if it is listed in the abbrev). 499 func newdie(parent *DWDie, abbrev int, name string, version int) *DWDie { 500 die := new(DWDie) 501 die.abbrev = abbrev 502 die.link = parent.child 503 parent.child = die 504 505 newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name) 506 507 if name != "" && (abbrev <= DW_ABRV_VARIABLE || abbrev >= DW_ABRV_NULLTYPE) { 508 if abbrev != DW_ABRV_VARIABLE || version == 0 { 509 die.sym = Linklookup(Ctxt, infoprefix+name, version) 510 die.sym.Attr |= AttrHidden 511 die.sym.Type = obj.SDWARFINFO 512 } 513 } 514 515 return die 516 } 517 518 func walktypedef(die *DWDie) *DWDie { 519 // Resolve typedef if present. 520 if die.abbrev == DW_ABRV_TYPEDECL { 521 for attr := die.attr; attr != nil; attr = attr.link { 522 if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil { 523 return attr.data.(*DWDie) 524 } 525 } 526 } 527 528 return die 529 } 530 531 func walksymtypedef(s *LSym) *LSym { 532 if t := Linkrlookup(Ctxt, s.Name+".def", int(s.Version)); t != nil { 533 return t 534 } 535 return s 536 } 537 538 // Find child by AT_name using hashtable if available or linear scan 539 // if not. 540 func findchild(die *DWDie, name string) *DWDie { 541 var prev *DWDie 542 for ; die != prev; prev, die = die, walktypedef(die) { 543 for a := die.child; a != nil; a = a.link { 544 if name == getattr(a, DW_AT_name).data { 545 return a 546 } 547 } 548 continue 549 } 550 return nil 551 } 552 553 // Used to avoid string allocation when looking up dwarf symbols 554 var prefixBuf = []byte(infoprefix) 555 556 func find(name string) *LSym { 557 n := append(prefixBuf, name...) 558 // The string allocation below is optimized away because it is only used in a map lookup. 559 s := Linkrlookup(Ctxt, string(n), 0) 560 prefixBuf = n[:len(infoprefix)] 561 return s 562 } 563 564 func mustFind(name string) *LSym { 565 r := find(name) 566 if r == nil { 567 Exitf("dwarf find: cannot find %s", name) 568 } 569 return r 570 } 571 572 func adddwarfref(ctxt *Link, s *LSym, t *LSym, size int) int64 { 573 var result int64 574 switch size { 575 default: 576 Diag("invalid size %d in adddwarfref\n", size) 577 fallthrough 578 case SysArch.PtrSize: 579 result = Addaddr(ctxt, s, t) 580 case 4: 581 result = addaddrplus4(ctxt, s, t, 0) 582 } 583 r := &s.R[len(s.R)-1] 584 r.Type = obj.R_DWARFREF 585 return result 586 } 587 588 func newrefattr(die *DWDie, attr uint16, ref *LSym) *DWAttr { 589 if ref == nil { 590 return nil 591 } 592 return newattr(die, attr, DW_CLS_REFERENCE, 0, ref) 593 } 594 595 func putattr(s *LSym, abbrev int, form int, cls int, value int64, data interface{}) { 596 switch form { 597 case DW_FORM_addr: // address 598 if Linkmode == LinkExternal { 599 value -= (data.(*LSym)).Value 600 Addaddrplus(Ctxt, s, data.(*LSym), value) 601 break 602 } 603 604 addrput(s, value) 605 606 case DW_FORM_block1: // block 607 if cls == DW_CLS_ADDRESS { 608 Adduint8(Ctxt, s, uint8(1+SysArch.PtrSize)) 609 Adduint8(Ctxt, s, DW_OP_addr) 610 Addaddr(Ctxt, s, data.(*LSym)) 611 break 612 } 613 614 value &= 0xff 615 Adduint8(Ctxt, s, uint8(value)) 616 p := data.([]byte) 617 for i := 0; int64(i) < value; i++ { 618 Adduint8(Ctxt, s, p[i]) 619 } 620 621 case DW_FORM_block2: // block 622 value &= 0xffff 623 624 Adduint16(Ctxt, s, uint16(value)) 625 p := data.([]byte) 626 for i := 0; int64(i) < value; i++ { 627 Adduint8(Ctxt, s, p[i]) 628 } 629 630 case DW_FORM_block4: // block 631 value &= 0xffffffff 632 633 Adduint32(Ctxt, s, uint32(value)) 634 p := data.([]byte) 635 for i := 0; int64(i) < value; i++ { 636 Adduint8(Ctxt, s, p[i]) 637 } 638 639 case DW_FORM_block: // block 640 uleb128put(s, value) 641 642 p := data.([]byte) 643 for i := 0; int64(i) < value; i++ { 644 Adduint8(Ctxt, s, p[i]) 645 } 646 647 case DW_FORM_data1: // constant 648 Adduint8(Ctxt, s, uint8(value)) 649 650 case DW_FORM_data2: // constant 651 Adduint16(Ctxt, s, uint16(value)) 652 653 case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr 654 if Linkmode == LinkExternal && cls == DW_CLS_PTR { 655 adddwarfref(Ctxt, s, linesec, 4) 656 break 657 } 658 659 Adduint32(Ctxt, s, uint32(value)) 660 661 case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr 662 Adduint64(Ctxt, s, uint64(value)) 663 664 case DW_FORM_sdata: // constant 665 sleb128put(s, value) 666 667 case DW_FORM_udata: // constant 668 uleb128put(s, value) 669 670 case DW_FORM_string: // string 671 str := data.(string) 672 Addstring(s, str) 673 for i := int64(len(str)); i < value; i++ { 674 Adduint8(Ctxt, s, 0) 675 } 676 677 case DW_FORM_flag: // flag 678 if value != 0 { 679 Adduint8(Ctxt, s, 1) 680 } else { 681 Adduint8(Ctxt, s, 0) 682 } 683 684 // In DWARF 2 (which is what we claim to generate), 685 // the ref_addr is the same size as a normal address. 686 // In DWARF 3 it is always 32 bits, unless emitting a large 687 // (> 4 GB of debug info aka "64-bit") unit, which we don't implement. 688 case DW_FORM_ref_addr: // reference to a DIE in the .info section 689 if data == nil { 690 Diag("dwarf: null reference in %d", abbrev) 691 if SysArch.PtrSize == 8 { 692 Adduint64(Ctxt, s, 0) // invalid dwarf, gdb will complain. 693 } else { 694 Adduint32(Ctxt, s, 0) // invalid dwarf, gdb will complain. 695 } 696 } else { 697 dsym := data.(*LSym) 698 adddwarfref(Ctxt, s, dsym, SysArch.PtrSize) 699 } 700 701 case DW_FORM_ref1, // reference within the compilation unit 702 DW_FORM_ref2, // reference 703 DW_FORM_ref4, // reference 704 DW_FORM_ref8, // reference 705 DW_FORM_ref_udata, // reference 706 707 DW_FORM_strp, // string 708 DW_FORM_indirect: // (see Section 7.5.3) 709 fallthrough 710 default: 711 Exitf("dwarf: unsupported attribute form %d / class %d", form, cls) 712 } 713 } 714 715 // Note that we can (and do) add arbitrary attributes to a DIE, but 716 // only the ones actually listed in the Abbrev will be written out. 717 func putattrs(s *LSym, abbrev int, attr *DWAttr) { 718 Outer: 719 for _, f := range abbrevs[abbrev].attr { 720 for ap := attr; ap != nil; ap = ap.link { 721 if ap.atr == f.attr { 722 putattr(s, abbrev, int(f.form), int(ap.cls), ap.value, ap.data) 723 continue Outer 724 } 725 } 726 727 putattr(s, abbrev, int(f.form), 0, 0, nil) 728 } 729 } 730 731 func putdies(prev *LSym, die *DWDie) *LSym { 732 for ; die != nil; die = die.link { 733 prev = putdie(prev, die) 734 } 735 Adduint8(Ctxt, prev, 0) 736 return prev 737 } 738 739 func putdie(prev *LSym, die *DWDie) *LSym { 740 s := die.sym 741 if s == nil { 742 s = prev 743 } else { 744 if s.Attr.OnList() { 745 log.Fatalf("symbol %s listed multiple times", s.Name) 746 } 747 s.Attr |= AttrOnList 748 prev.Next = s 749 } 750 uleb128put(s, int64(die.abbrev)) 751 putattrs(s, die.abbrev, die.attr) 752 if abbrevs[die.abbrev].children != 0 { 753 return putdies(s, die.child) 754 } 755 return s 756 } 757 758 func reverselist(list **DWDie) { 759 curr := *list 760 var prev *DWDie 761 for curr != nil { 762 var next *DWDie = curr.link 763 curr.link = prev 764 prev = curr 765 curr = next 766 } 767 768 *list = prev 769 } 770 771 func reversetree(list **DWDie) { 772 reverselist(list) 773 for die := *list; die != nil; die = die.link { 774 if abbrevs[die.abbrev].children != 0 { 775 reversetree(&die.child) 776 } 777 } 778 } 779 780 func newmemberoffsetattr(die *DWDie, offs int32) { 781 var block [20]byte 782 b := append(block[:0], DW_OP_plus_uconst) 783 b = appendUleb128(b, uint64(offs)) 784 newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(len(b)), b) 785 } 786 787 // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a 788 // location expression that evals to a const. 789 func newabslocexprattr(die *DWDie, addr int64, sym *LSym) { 790 newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym) 791 // below 792 } 793 794 // Lookup predefined types 795 func lookup_or_diag(n string) *LSym { 796 s := Linkrlookup(Ctxt, n, 0) 797 if s == nil || s.Size == 0 { 798 Exitf("dwarf: missing type: %s", n) 799 } 800 801 return s 802 } 803 804 func dotypedef(parent *DWDie, name string, def *DWDie) { 805 // Only emit typedefs for real names. 806 if strings.HasPrefix(name, "map[") { 807 return 808 } 809 if strings.HasPrefix(name, "struct {") { 810 return 811 } 812 if strings.HasPrefix(name, "chan ") { 813 return 814 } 815 if name[0] == '[' || name[0] == '*' { 816 return 817 } 818 if def == nil { 819 Diag("dwarf: bad def in dotypedef") 820 } 821 822 def.sym = Linklookup(Ctxt, def.sym.Name+".def", 0) 823 def.sym.Attr |= AttrHidden 824 def.sym.Type = obj.SDWARFINFO 825 826 // The typedef entry must be created after the def, 827 // so that future lookups will find the typedef instead 828 // of the real definition. This hooks the typedef into any 829 // circular definition loops, so that gdb can understand them. 830 die := newdie(parent, DW_ABRV_TYPEDECL, name, 0) 831 832 newrefattr(die, DW_AT_type, def.sym) 833 } 834 835 // Define gotype, for composite ones recurse into constituents. 836 func defgotype(gotype *LSym) *LSym { 837 if gotype == nil { 838 return mustFind("<unspecified>") 839 } 840 841 if !strings.HasPrefix(gotype.Name, "type.") { 842 Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name) 843 return mustFind("<unspecified>") 844 } 845 846 name := gotype.Name[5:] // could also decode from Type.string 847 848 sdie := find(name) 849 850 if sdie != nil { 851 return sdie 852 } 853 854 return newtype(gotype).sym 855 } 856 857 func newtype(gotype *LSym) *DWDie { 858 name := gotype.Name[5:] // could also decode from Type.string 859 kind := decodetype_kind(gotype) 860 bytesize := decodetype_size(gotype) 861 862 var die *DWDie 863 switch kind { 864 case obj.KindBool: 865 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0) 866 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_boolean, 0) 867 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 868 869 case obj.KindInt, 870 obj.KindInt8, 871 obj.KindInt16, 872 obj.KindInt32, 873 obj.KindInt64: 874 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0) 875 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_signed, 0) 876 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 877 878 case obj.KindUint, 879 obj.KindUint8, 880 obj.KindUint16, 881 obj.KindUint32, 882 obj.KindUint64, 883 obj.KindUintptr: 884 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0) 885 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 886 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 887 888 case obj.KindFloat32, 889 obj.KindFloat64: 890 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0) 891 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_float, 0) 892 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 893 894 case obj.KindComplex64, 895 obj.KindComplex128: 896 die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0) 897 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_complex_float, 0) 898 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 899 900 case obj.KindArray: 901 die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name, 0) 902 dotypedef(&dwtypes, name, die) 903 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 904 s := decodetype_arrayelem(gotype) 905 newrefattr(die, DW_AT_type, defgotype(s)) 906 fld := newdie(die, DW_ABRV_ARRAYRANGE, "range", 0) 907 908 // use actual length not upper bound; correct for 0-length arrays. 909 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0) 910 911 newrefattr(fld, DW_AT_type, mustFind("uintptr")) 912 913 case obj.KindChan: 914 die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name, 0) 915 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 916 s := decodetype_chanelem(gotype) 917 newrefattr(die, DW_AT_go_elem, defgotype(s)) 918 // Save elem type for synthesizechantypes. We could synthesize here 919 // but that would change the order of DIEs we output. 920 newrefattr(die, DW_AT_type, s) 921 922 case obj.KindFunc: 923 die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name, 0) 924 dotypedef(&dwtypes, name, die) 925 newrefattr(die, DW_AT_type, mustFind("void")) 926 nfields := decodetype_funcincount(gotype) 927 var fld *DWDie 928 var s *LSym 929 for i := 0; i < nfields; i++ { 930 s = decodetype_funcintype(gotype, i) 931 fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0) 932 newrefattr(fld, DW_AT_type, defgotype(s)) 933 } 934 935 if decodetype_funcdotdotdot(gotype) { 936 newdie(die, DW_ABRV_DOTDOTDOT, "...", 0) 937 } 938 nfields = decodetype_funcoutcount(gotype) 939 for i := 0; i < nfields; i++ { 940 s = decodetype_funcouttype(gotype, i) 941 fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0) 942 newrefattr(fld, DW_AT_type, defptrto(defgotype(s))) 943 } 944 945 case obj.KindInterface: 946 die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name, 0) 947 dotypedef(&dwtypes, name, die) 948 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 949 nfields := int(decodetype_ifacemethodcount(gotype)) 950 var s *LSym 951 if nfields == 0 { 952 s = lookup_or_diag("type.runtime.eface") 953 } else { 954 s = lookup_or_diag("type.runtime.iface") 955 } 956 newrefattr(die, DW_AT_type, defgotype(s)) 957 958 case obj.KindMap: 959 die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name, 0) 960 s := decodetype_mapkey(gotype) 961 newrefattr(die, DW_AT_go_key, defgotype(s)) 962 s = decodetype_mapvalue(gotype) 963 newrefattr(die, DW_AT_go_elem, defgotype(s)) 964 // Save gotype for use in synthesizemaptypes. We could synthesize here, 965 // but that would change the order of the DIEs. 966 newrefattr(die, DW_AT_type, gotype) 967 968 case obj.KindPtr: 969 die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name, 0) 970 dotypedef(&dwtypes, name, die) 971 s := decodetype_ptrelem(gotype) 972 newrefattr(die, DW_AT_type, defgotype(s)) 973 974 case obj.KindSlice: 975 die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name, 0) 976 dotypedef(&dwtypes, name, die) 977 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 978 s := decodetype_arrayelem(gotype) 979 elem := defgotype(s) 980 newrefattr(die, DW_AT_go_elem, elem) 981 982 case obj.KindString: 983 die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name, 0) 984 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 985 986 case obj.KindStruct: 987 die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name, 0) 988 dotypedef(&dwtypes, name, die) 989 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0) 990 nfields := decodetype_structfieldcount(gotype) 991 var f string 992 var fld *DWDie 993 var s *LSym 994 for i := 0; i < nfields; i++ { 995 f = decodetype_structfieldname(gotype, i) 996 s = decodetype_structfieldtype(gotype, i) 997 if f == "" { 998 f = s.Name[5:] // skip "type." 999 } 1000 fld = newdie(die, DW_ABRV_STRUCTFIELD, f, 0) 1001 newrefattr(fld, DW_AT_type, defgotype(s)) 1002 newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i))) 1003 } 1004 1005 case obj.KindUnsafePointer: 1006 die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name, 0) 1007 1008 default: 1009 Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name) 1010 die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name, 0) 1011 newrefattr(die, DW_AT_type, mustFind("<unspecified>")) 1012 } 1013 1014 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0) 1015 1016 if _, ok := prototypedies[gotype.Name]; ok { 1017 prototypedies[gotype.Name] = die 1018 } 1019 1020 return die 1021 } 1022 1023 func nameFromDIESym(dwtype *LSym) string { 1024 return strings.TrimSuffix(dwtype.Name[len(infoprefix):], ".def") 1025 } 1026 1027 // Find or construct *T given T. 1028 func defptrto(dwtype *LSym) *LSym { 1029 ptrname := "*" + nameFromDIESym(dwtype) 1030 die := find(ptrname) 1031 if die == nil { 1032 pdie := newdie(&dwtypes, DW_ABRV_PTRTYPE, ptrname, 0) 1033 newrefattr(pdie, DW_AT_type, dwtype) 1034 return pdie.sym 1035 } 1036 1037 return die 1038 } 1039 1040 // Copies src's children into dst. Copies attributes by value. 1041 // DWAttr.data is copied as pointer only. If except is one of 1042 // the top-level children, it will not be copied. 1043 func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) { 1044 for src = src.child; src != nil; src = src.link { 1045 if src == except { 1046 continue 1047 } 1048 c := newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string), 0) 1049 for a := src.attr; a != nil; a = a.link { 1050 newattr(c, a.atr, int(a.cls), a.value, a.data) 1051 } 1052 copychildrenexcept(c, src, nil) 1053 } 1054 1055 reverselist(&dst.child) 1056 } 1057 1058 func copychildren(dst *DWDie, src *DWDie) { 1059 copychildrenexcept(dst, src, nil) 1060 } 1061 1062 // Search children (assumed to have DW_TAG_member) for the one named 1063 // field and set its DW_AT_type to dwtype 1064 func substitutetype(structdie *DWDie, field string, dwtype *LSym) { 1065 child := findchild(structdie, field) 1066 if child == nil { 1067 Exitf("dwarf substitutetype: %s does not have member %s", 1068 getattr(structdie, DW_AT_name).data, field) 1069 return 1070 } 1071 1072 a := getattr(child, DW_AT_type) 1073 if a != nil { 1074 a.data = dwtype 1075 } else { 1076 newrefattr(child, DW_AT_type, dwtype) 1077 } 1078 } 1079 1080 func findprotodie(name string) *DWDie { 1081 die, ok := prototypedies[name] 1082 if ok && die == nil { 1083 defgotype(lookup_or_diag(name)) 1084 die = prototypedies[name] 1085 } 1086 return die 1087 } 1088 1089 func synthesizestringtypes(die *DWDie) { 1090 prototype := walktypedef(findprotodie("type.runtime.stringStructDWARF")) 1091 if prototype == nil { 1092 return 1093 } 1094 1095 for ; die != nil; die = die.link { 1096 if die.abbrev != DW_ABRV_STRINGTYPE { 1097 continue 1098 } 1099 copychildren(die, prototype) 1100 } 1101 } 1102 1103 func synthesizeslicetypes(die *DWDie) { 1104 prototype := walktypedef(findprotodie("type.runtime.slice")) 1105 if prototype == nil { 1106 return 1107 } 1108 1109 for ; die != nil; die = die.link { 1110 if die.abbrev != DW_ABRV_SLICETYPE { 1111 continue 1112 } 1113 copychildren(die, prototype) 1114 elem := getattr(die, DW_AT_go_elem).data.(*LSym) 1115 substitutetype(die, "array", defptrto(elem)) 1116 } 1117 } 1118 1119 func mkinternaltypename(base string, arg1 string, arg2 string) string { 1120 var buf string 1121 1122 if arg2 == "" { 1123 buf = fmt.Sprintf("%s<%s>", base, arg1) 1124 } else { 1125 buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2) 1126 } 1127 n := buf 1128 return n 1129 } 1130 1131 // synthesizemaptypes is way too closely married to runtime/hashmap.c 1132 const ( 1133 MaxKeySize = 128 1134 MaxValSize = 128 1135 BucketSize = 8 1136 ) 1137 1138 func mkinternaltype(abbrev int, typename, keyname, valname string, f func(*DWDie)) *LSym { 1139 name := mkinternaltypename(typename, keyname, valname) 1140 symname := infoprefix + name 1141 s := Linkrlookup(Ctxt, symname, 0) 1142 if s != nil { 1143 return s 1144 } 1145 die := newdie(&dwtypes, abbrev, name, 0) 1146 f(die) 1147 return die.sym 1148 } 1149 1150 func synthesizemaptypes(die *DWDie) { 1151 hash := walktypedef(findprotodie("type.runtime.hmap")) 1152 bucket := walktypedef(findprotodie("type.runtime.bmap")) 1153 1154 if hash == nil { 1155 return 1156 } 1157 1158 for ; die != nil; die = die.link { 1159 if die.abbrev != DW_ABRV_MAPTYPE { 1160 continue 1161 } 1162 gotype := getattr(die, DW_AT_type).data.(*LSym) 1163 keytype := decodetype_mapkey(gotype) 1164 valtype := decodetype_mapvalue(gotype) 1165 keysize, valsize := decodetype_size(keytype), decodetype_size(valtype) 1166 keytype, valtype = walksymtypedef(defgotype(keytype)), walksymtypedef(defgotype(valtype)) 1167 1168 // compute size info like hashmap.c does. 1169 indirect_key, indirect_val := false, false 1170 if keysize > MaxKeySize { 1171 keysize = int64(SysArch.PtrSize) 1172 indirect_key = true 1173 } 1174 if valsize > MaxValSize { 1175 valsize = int64(SysArch.PtrSize) 1176 indirect_val = true 1177 } 1178 1179 // Construct type to represent an array of BucketSize keys 1180 keyname := nameFromDIESym(keytype) 1181 dwhks := mkinternaltype(DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *DWDie) { 1182 newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*keysize, 0) 1183 t := keytype 1184 if indirect_key { 1185 t = defptrto(keytype) 1186 } 1187 newrefattr(dwhk, DW_AT_type, t) 1188 fld := newdie(dwhk, DW_ABRV_ARRAYRANGE, "size", 0) 1189 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) 1190 newrefattr(fld, DW_AT_type, mustFind("uintptr")) 1191 }) 1192 1193 // Construct type to represent an array of BucketSize values 1194 valname := nameFromDIESym(valtype) 1195 dwhvs := mkinternaltype(DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *DWDie) { 1196 newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*valsize, 0) 1197 t := valtype 1198 if indirect_val { 1199 t = defptrto(valtype) 1200 } 1201 newrefattr(dwhv, DW_AT_type, t) 1202 fld := newdie(dwhv, DW_ABRV_ARRAYRANGE, "size", 0) 1203 newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) 1204 newrefattr(fld, DW_AT_type, mustFind("uintptr")) 1205 }) 1206 1207 // Construct bucket<K,V> 1208 dwhbs := mkinternaltype(DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *DWDie) { 1209 // Copy over all fields except the field "data" from the generic 1210 // bucket. "data" will be replaced with keys/values below. 1211 copychildrenexcept(dwhb, bucket, findchild(bucket, "data")) 1212 1213 fld := newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys", 0) 1214 newrefattr(fld, DW_AT_type, dwhks) 1215 newmemberoffsetattr(fld, BucketSize) 1216 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values", 0) 1217 newrefattr(fld, DW_AT_type, dwhvs) 1218 newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize)) 1219 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow", 0) 1220 newrefattr(fld, DW_AT_type, defptrto(dwhb.sym)) 1221 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))) 1222 if SysArch.RegSize > SysArch.PtrSize { 1223 fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad", 0) 1224 newrefattr(fld, DW_AT_type, mustFind("uintptr")) 1225 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize)) 1226 } 1227 1228 newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(SysArch.RegSize), 0) 1229 }) 1230 1231 // Construct hash<K,V> 1232 dwhs := mkinternaltype(DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *DWDie) { 1233 copychildren(dwh, hash) 1234 substitutetype(dwh, "buckets", defptrto(dwhbs)) 1235 substitutetype(dwh, "oldbuckets", defptrto(dwhbs)) 1236 newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil) 1237 }) 1238 1239 // make map type a pointer to hash<K,V> 1240 newrefattr(die, DW_AT_type, defptrto(dwhs)) 1241 } 1242 } 1243 1244 func synthesizechantypes(die *DWDie) { 1245 sudog := walktypedef(findprotodie("type.runtime.sudog")) 1246 waitq := walktypedef(findprotodie("type.runtime.waitq")) 1247 hchan := walktypedef(findprotodie("type.runtime.hchan")) 1248 if sudog == nil || waitq == nil || hchan == nil { 1249 return 1250 } 1251 1252 sudogsize := int(getattr(sudog, DW_AT_byte_size).value) 1253 1254 for ; die != nil; die = die.link { 1255 if die.abbrev != DW_ABRV_CHANTYPE { 1256 continue 1257 } 1258 elemgotype := getattr(die, DW_AT_type).data.(*LSym) 1259 elemsize := decodetype_size(elemgotype) 1260 elemname := elemgotype.Name[5:] 1261 elemtype := walksymtypedef(defgotype(elemgotype)) 1262 1263 // sudog<T> 1264 dwss := mkinternaltype(DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *DWDie) { 1265 copychildren(dws, sudog) 1266 substitutetype(dws, "elem", elemtype) 1267 if elemsize > 8 { 1268 elemsize -= 8 1269 } else { 1270 elemsize = 0 1271 } 1272 newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+elemsize, nil) 1273 }) 1274 1275 // waitq<T> 1276 dwws := mkinternaltype(DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *DWDie) { 1277 1278 copychildren(dww, waitq) 1279 substitutetype(dww, "first", defptrto(dwss)) 1280 substitutetype(dww, "last", defptrto(dwss)) 1281 newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil) 1282 }) 1283 1284 // hchan<T> 1285 dwhs := mkinternaltype(DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *DWDie) { 1286 copychildren(dwh, hchan) 1287 substitutetype(dwh, "recvq", dwws) 1288 substitutetype(dwh, "sendq", dwws) 1289 newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil) 1290 }) 1291 1292 newrefattr(die, DW_AT_type, defptrto(dwhs)) 1293 } 1294 } 1295 1296 // For use with pass.c::genasmsym 1297 func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) { 1298 if strings.HasPrefix(s, "go.string.") { 1299 return 1300 } 1301 if strings.HasPrefix(s, "runtime.gcbits.") { 1302 return 1303 } 1304 1305 if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { 1306 defgotype(sym) 1307 return 1308 } 1309 1310 var dv *DWDie 1311 1312 var dt *LSym 1313 switch t { 1314 default: 1315 return 1316 1317 case 'd', 'b', 'D', 'B': 1318 dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s, ver) 1319 newabslocexprattr(dv, v, sym) 1320 if ver == 0 { 1321 newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0) 1322 } 1323 fallthrough 1324 1325 case 'a', 'p': 1326 dt = defgotype(gotype) 1327 } 1328 1329 if dv != nil { 1330 newrefattr(dv, DW_AT_type, dt) 1331 } 1332 } 1333 1334 func movetomodule(parent *DWDie) { 1335 die := dwroot.child.child 1336 for die.link != nil { 1337 die = die.link 1338 } 1339 die.link = parent.child 1340 } 1341 1342 // If the pcln table contains runtime/runtime.go, use that to set gdbscript path. 1343 func finddebugruntimepath(s *LSym) { 1344 if gdbscript != "" { 1345 return 1346 } 1347 1348 for i := range s.FuncInfo.File { 1349 f := s.FuncInfo.File[i] 1350 if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 { 1351 gdbscript = f.Name[:i] + "runtime/runtime-gdb.py" 1352 break 1353 } 1354 } 1355 } 1356 1357 /* 1358 * Generate short opcodes when possible, long ones when necessary. 1359 * See section 6.2.5 1360 */ 1361 const ( 1362 LINE_BASE = -1 1363 LINE_RANGE = 4 1364 OPCODE_BASE = 10 1365 ) 1366 1367 func putpclcdelta(s *LSym, delta_pc int64, delta_lc int64) { 1368 if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE { 1369 var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc) 1370 if OPCODE_BASE <= opcode && opcode < 256 { 1371 Adduint8(Ctxt, s, uint8(opcode)) 1372 return 1373 } 1374 } 1375 1376 if delta_pc != 0 { 1377 Adduint8(Ctxt, s, DW_LNS_advance_pc) 1378 sleb128put(s, delta_pc) 1379 } 1380 1381 Adduint8(Ctxt, s, DW_LNS_advance_line) 1382 sleb128put(s, delta_lc) 1383 Adduint8(Ctxt, s, DW_LNS_copy) 1384 } 1385 1386 func newcfaoffsetattr(die *DWDie, offs int32) { 1387 var block [20]byte 1388 b := append(block[:0], DW_OP_call_frame_cfa) 1389 1390 if offs != 0 { 1391 b = append(b, DW_OP_consts) 1392 b = appendSleb128(b, int64(offs)) 1393 b = append(b, DW_OP_plus) 1394 } 1395 1396 newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(len(b)), b) 1397 } 1398 1399 func mkvarname(name string, da int) string { 1400 buf := fmt.Sprintf("%s#%d", name, da) 1401 n := buf 1402 return n 1403 } 1404 1405 /* 1406 * Walk prog table, emit line program and build DIE tree. 1407 */ 1408 1409 func getCompilationDir() string { 1410 if dir, err := os.Getwd(); err == nil { 1411 return dir 1412 } 1413 return "/" 1414 } 1415 1416 func writelines(prev *LSym) *LSym { 1417 if linesec == nil { 1418 linesec = Linklookup(Ctxt, ".debug_line", 0) 1419 } 1420 linesec.Type = obj.SDWARFSECT 1421 linesec.R = linesec.R[:0] 1422 1423 ls := linesec 1424 prev.Next = ls 1425 1426 unitstart := int64(-1) 1427 headerstart := int64(-1) 1428 headerend := int64(-1) 1429 epc := int64(0) 1430 var epcs *LSym 1431 var dwinfo *DWDie 1432 1433 lang := DW_LANG_Go 1434 1435 s := Ctxt.Textp[0] 1436 1437 dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go", 0) 1438 newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0) 1439 newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, 0, 0) 1440 newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1441 // OS X linker requires compilation dir or absolute path in comp unit name to output debug info. 1442 compDir := getCompilationDir() 1443 newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir) 1444 1445 // Write .debug_line Line Number Program Header (sec 6.2.4) 1446 // Fields marked with (*) must be changed for 64-bit dwarf 1447 unit_length_offset := ls.Size 1448 Adduint32(Ctxt, ls, 0) // unit_length (*), filled in at end. 1449 unitstart = ls.Size 1450 Adduint16(Ctxt, ls, 2) // dwarf version (appendix F) 1451 header_length_offset := ls.Size 1452 Adduint32(Ctxt, ls, 0) // header_length (*), filled in at end. 1453 headerstart = ls.Size 1454 1455 // cpos == unitstart + 4 + 2 + 4 1456 Adduint8(Ctxt, ls, 1) // minimum_instruction_length 1457 Adduint8(Ctxt, ls, 1) // default_is_stmt 1458 Adduint8(Ctxt, ls, LINE_BASE&0xFF) // line_base 1459 Adduint8(Ctxt, ls, LINE_RANGE) // line_range 1460 Adduint8(Ctxt, ls, OPCODE_BASE) // opcode_base 1461 Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[1] 1462 Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[2] 1463 Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[3] 1464 Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[4] 1465 Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[5] 1466 Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[6] 1467 Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[7] 1468 Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[8] 1469 Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[9] 1470 Adduint8(Ctxt, ls, 0) // include_directories (empty) 1471 1472 for _, f := range Ctxt.Filesyms { 1473 Addstring(ls, f.Name) 1474 Adduint8(Ctxt, ls, 0) 1475 Adduint8(Ctxt, ls, 0) 1476 Adduint8(Ctxt, ls, 0) 1477 } 1478 1479 // 4 zeros: the string termination + 3 fields. 1480 Adduint8(Ctxt, ls, 0) 1481 // terminate file_names. 1482 headerend = ls.Size 1483 1484 Adduint8(Ctxt, ls, 0) // start extended opcode 1485 uleb128put(ls, 1+int64(SysArch.PtrSize)) 1486 Adduint8(Ctxt, ls, DW_LNE_set_address) 1487 1488 pc := s.Value 1489 line := 1 1490 file := 1 1491 if Linkmode == LinkExternal { 1492 Addaddr(Ctxt, ls, s) 1493 } else { 1494 addrput(ls, pc) 1495 } 1496 1497 var pcfile Pciter 1498 var pcline Pciter 1499 for _, Ctxt.Cursym = range Ctxt.Textp { 1500 s := Ctxt.Cursym 1501 1502 dwfunc := newdie(dwinfo, DW_ABRV_FUNCTION, s.Name, int(s.Version)) 1503 newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s) 1504 epc = s.Value + s.Size 1505 epcs = s 1506 newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s) 1507 if s.Version == 0 { 1508 newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0) 1509 } 1510 1511 if s.FuncInfo == nil { 1512 continue 1513 } 1514 1515 finddebugruntimepath(s) 1516 1517 pciterinit(Ctxt, &pcfile, &s.FuncInfo.Pcfile) 1518 pciterinit(Ctxt, &pcline, &s.FuncInfo.Pcline) 1519 epc = pc 1520 for pcfile.done == 0 && pcline.done == 0 { 1521 if epc-s.Value >= int64(pcfile.nextpc) { 1522 pciternext(&pcfile) 1523 continue 1524 } 1525 1526 if epc-s.Value >= int64(pcline.nextpc) { 1527 pciternext(&pcline) 1528 continue 1529 } 1530 1531 if int32(file) != pcfile.value { 1532 Adduint8(Ctxt, ls, DW_LNS_set_file) 1533 uleb128put(ls, int64(pcfile.value)) 1534 file = int(pcfile.value) 1535 } 1536 1537 putpclcdelta(ls, s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line)) 1538 1539 pc = s.Value + int64(pcline.pc) 1540 line = int(pcline.value) 1541 if pcfile.nextpc < pcline.nextpc { 1542 epc = int64(pcfile.nextpc) 1543 } else { 1544 epc = int64(pcline.nextpc) 1545 } 1546 epc += s.Value 1547 } 1548 1549 var ( 1550 dt, da int 1551 offs int64 1552 ) 1553 for _, a := range s.FuncInfo.Autom { 1554 switch a.Name { 1555 case obj.A_AUTO: 1556 dt = DW_ABRV_AUTO 1557 offs = int64(a.Aoffset) 1558 if !haslinkregister() { 1559 offs -= int64(SysArch.PtrSize) 1560 } 1561 if obj.Framepointer_enabled(obj.Getgoos(), obj.Getgoarch()) { 1562 // The frame pointer is saved 1563 // between the CFA and the 1564 // autos. 1565 offs -= int64(SysArch.PtrSize) 1566 } 1567 1568 case obj.A_PARAM: 1569 dt = DW_ABRV_PARAM 1570 offs = int64(a.Aoffset) + Ctxt.FixedFrameSize() 1571 1572 default: 1573 continue 1574 } 1575 1576 if strings.Contains(a.Asym.Name, ".autotmp_") { 1577 continue 1578 } 1579 var n string 1580 if findchild(dwfunc, a.Asym.Name) != nil { 1581 n = mkvarname(a.Asym.Name, da) 1582 } else { 1583 n = a.Asym.Name 1584 } 1585 1586 // Drop the package prefix from locals and arguments. 1587 if i := strings.LastIndex(n, "."); i >= 0 { 1588 n = n[i+1:] 1589 } 1590 1591 dwvar := newdie(dwfunc, dt, n, 0) 1592 newcfaoffsetattr(dwvar, int32(offs)) 1593 newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype)) 1594 1595 // push dwvar down dwfunc->child to preserve order 1596 newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil) 1597 1598 dwfunc.child = dwvar.link // take dwvar out from the top of the list 1599 dws := &dwfunc.child 1600 for ; *dws != nil; dws = &(*dws).link { 1601 if offs > getattr(*dws, DW_AT_internal_location).value { 1602 break 1603 } 1604 } 1605 dwvar.link = *dws 1606 *dws = dwvar 1607 1608 da++ 1609 } 1610 } 1611 1612 Adduint8(Ctxt, ls, 0) // start extended opcode 1613 uleb128put(ls, 1) 1614 Adduint8(Ctxt, ls, DW_LNE_end_sequence) 1615 1616 newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, epc+1, epcs) 1617 1618 setuint32(Ctxt, ls, unit_length_offset, uint32(ls.Size-unitstart)) 1619 setuint32(Ctxt, ls, header_length_offset, uint32(headerend-headerstart)) 1620 1621 return ls 1622 } 1623 1624 /* 1625 * Emit .debug_frame 1626 */ 1627 const ( 1628 dataAlignmentFactor = -4 1629 ) 1630 1631 // appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice. 1632 func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte { 1633 b = append(b, DW_CFA_def_cfa_offset_sf) 1634 b = appendSleb128(b, cfa/dataAlignmentFactor) 1635 1636 switch { 1637 case deltapc < 0x40: 1638 b = append(b, uint8(DW_CFA_advance_loc+deltapc)) 1639 case deltapc < 0x100: 1640 b = append(b, DW_CFA_advance_loc1) 1641 b = append(b, uint8(deltapc)) 1642 case deltapc < 0x10000: 1643 b = append(b, DW_CFA_advance_loc2) 1644 b = Thearch.Append16(b, uint16(deltapc)) 1645 default: 1646 b = append(b, DW_CFA_advance_loc4) 1647 b = Thearch.Append32(b, uint32(deltapc)) 1648 } 1649 return b 1650 } 1651 1652 func writeframes(prev *LSym) *LSym { 1653 if framesec == nil { 1654 framesec = Linklookup(Ctxt, ".debug_frame", 0) 1655 } 1656 framesec.Type = obj.SDWARFSECT 1657 framesec.R = framesec.R[:0] 1658 fs := framesec 1659 prev.Next = fs 1660 1661 // Emit the CIE, Section 6.4.1 1662 cieReserve := uint32(16) 1663 if haslinkregister() { 1664 cieReserve = 32 1665 } 1666 Adduint32(Ctxt, fs, cieReserve) // initial length, must be multiple of pointer size 1667 Adduint32(Ctxt, fs, 0xffffffff) // cid. 1668 Adduint8(Ctxt, fs, 3) // dwarf version (appendix F) 1669 Adduint8(Ctxt, fs, 0) // augmentation "" 1670 uleb128put(fs, 1) // code_alignment_factor 1671 sleb128put(fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this factor 1672 uleb128put(fs, int64(Thearch.Dwarfreglr)) // return_address_register 1673 1674 Adduint8(Ctxt, fs, DW_CFA_def_cfa) // Set the current frame address.. 1675 uleb128put(fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)... 1676 if haslinkregister() { 1677 uleb128put(fs, int64(0)) // ...plus a 0 offset. 1678 1679 Adduint8(Ctxt, fs, DW_CFA_same_value) // The platform's link register is unchanged during the prologue. 1680 uleb128put(fs, int64(Thearch.Dwarfreglr)) 1681 1682 Adduint8(Ctxt, fs, DW_CFA_val_offset) // The previous value... 1683 uleb128put(fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register... 1684 uleb128put(fs, int64(0)) // ...is CFA+0. 1685 } else { 1686 uleb128put(fs, int64(SysArch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame). 1687 1688 Adduint8(Ctxt, fs, DW_CFA_offset_extended) // The previous value... 1689 uleb128put(fs, int64(Thearch.Dwarfreglr)) // ...of the return address... 1690 uleb128put(fs, int64(-SysArch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)]. 1691 } 1692 1693 // 4 is to exclude the length field. 1694 pad := int64(cieReserve) + 4 - fs.Size 1695 1696 if pad < 0 { 1697 Exitf("dwarf: cieReserve too small by %d bytes.", -pad) 1698 } 1699 1700 Addbytes(Ctxt, fs, zeros[:pad]) 1701 1702 var deltaBuf []byte 1703 var pcsp Pciter 1704 for _, Ctxt.Cursym = range Ctxt.Textp { 1705 s := Ctxt.Cursym 1706 if s.FuncInfo == nil { 1707 continue 1708 } 1709 1710 // Emit a FDE, Section 6.4.1. 1711 // First build the section contents into a byte buffer. 1712 deltaBuf = deltaBuf[:0] 1713 for pciterinit(Ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1714 nextpc := pcsp.nextpc 1715 1716 // pciterinit goes up to the end of the function, 1717 // but DWARF expects us to stop just before the end. 1718 if int64(nextpc) == s.Size { 1719 nextpc-- 1720 if nextpc < pcsp.pc { 1721 continue 1722 } 1723 } 1724 1725 if haslinkregister() { 1726 // TODO(bryanpkc): This is imprecise. In general, the instruction 1727 // that stores the return address to the stack frame is not the 1728 // same one that allocates the frame. 1729 if pcsp.value > 0 { 1730 // The return address is preserved at (CFA-frame_size) 1731 // after a stack frame has been allocated. 1732 deltaBuf = append(deltaBuf, DW_CFA_offset_extended_sf) 1733 deltaBuf = appendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr)) 1734 deltaBuf = appendSleb128(deltaBuf, -int64(pcsp.value)/dataAlignmentFactor) 1735 } else { 1736 // The return address is restored into the link register 1737 // when a stack frame has been de-allocated. 1738 deltaBuf = append(deltaBuf, DW_CFA_same_value) 1739 deltaBuf = appendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr)) 1740 } 1741 deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value)) 1742 } else { 1743 deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(SysArch.PtrSize)+int64(pcsp.value)) 1744 } 1745 } 1746 pad := int(Rnd(int64(len(deltaBuf)), int64(SysArch.PtrSize))) - len(deltaBuf) 1747 deltaBuf = append(deltaBuf, zeros[:pad]...) 1748 1749 // Emit the FDE header, Section 6.4.1. 1750 // 4 bytes: length, must be multiple of thearch.ptrsize 1751 // 4 bytes: Pointer to the CIE above, at offset 0 1752 // ptrsize: initial location 1753 // ptrsize: address range 1754 Adduint32(Ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself) 1755 if Linkmode == LinkExternal { 1756 adddwarfref(Ctxt, fs, framesec, 4) 1757 } else { 1758 Adduint32(Ctxt, fs, 0) // CIE offset 1759 } 1760 Addaddr(Ctxt, fs, s) 1761 addrput(fs, s.Size) // address range 1762 Addbytes(Ctxt, fs, deltaBuf) 1763 } 1764 return fs 1765 } 1766 1767 /* 1768 * Walk DWarfDebugInfoEntries, and emit .debug_info 1769 */ 1770 const ( 1771 COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 1772 ) 1773 1774 func writeinfo(prev *LSym) *LSym { 1775 if infosec == nil { 1776 infosec = Linklookup(Ctxt, ".debug_info", 0) 1777 } 1778 infosec.R = infosec.R[:0] 1779 infosec.Type = obj.SDWARFINFO 1780 infosec.Attr |= AttrReachable 1781 prev.Next, prev = infosec, infosec 1782 1783 if arangessec == nil { 1784 arangessec = Linklookup(Ctxt, ".dwarfaranges", 0) 1785 } 1786 arangessec.R = arangessec.R[:0] 1787 1788 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1789 s := compunit.sym 1790 prev.Next, prev = s, s 1791 1792 // Write .debug_info Compilation Unit Header (sec 7.5.1) 1793 // Fields marked with (*) must be changed for 64-bit dwarf 1794 // This must match COMPUNITHEADERSIZE above. 1795 Adduint32(Ctxt, s, 0) // unit_length (*), will be filled in later. 1796 Adduint16(Ctxt, s, 2) // dwarf version (appendix F) 1797 1798 // debug_abbrev_offset (*) 1799 adddwarfref(Ctxt, s, abbrevsym, 4) 1800 1801 Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size 1802 1803 prev = putdie(prev, compunit) 1804 cusize := s.Size - 4 // exclude the length field. 1805 for child := s.Next; child != nil; child = child.Next { 1806 cusize += child.Size 1807 } 1808 1809 setuint32(Ctxt, s, 0, uint32(cusize)) 1810 newattr(compunit, DW_AT_byte_size, DW_CLS_CONSTANT, cusize, 0) 1811 } 1812 return prev 1813 } 1814 1815 /* 1816 * Emit .debug_pubnames/_types. _info must have been written before, 1817 * because we need die->offs and infoo/infosize; 1818 */ 1819 func ispubname(die *DWDie) bool { 1820 switch die.abbrev { 1821 case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE: 1822 a := getattr(die, DW_AT_external) 1823 return a != nil && a.value != 0 1824 } 1825 1826 return false 1827 } 1828 1829 func ispubtype(die *DWDie) bool { 1830 return die.abbrev >= DW_ABRV_NULLTYPE 1831 } 1832 1833 func writepub(sname string, ispub func(*DWDie) bool, prev *LSym) *LSym { 1834 s := Linklookup(Ctxt, sname, 0) 1835 s.Type = obj.SDWARFSECT 1836 prev.Next = s 1837 1838 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1839 sectionstart := s.Size 1840 culength := uint32(getattr(compunit, DW_AT_byte_size).value) + 4 1841 1842 // Write .debug_pubnames/types Header (sec 6.1.1) 1843 Adduint32(Ctxt, s, 0) // unit_length (*), will be filled in later. 1844 Adduint16(Ctxt, s, 2) // dwarf version (appendix F) 1845 adddwarfref(Ctxt, s, compunit.sym, 4) // debug_info_offset (of the Comp unit Header) 1846 Adduint32(Ctxt, s, culength) // debug_info_length 1847 1848 for die := compunit.child; die != nil; die = die.link { 1849 if !ispub(die) { 1850 continue 1851 } 1852 dwa := getattr(die, DW_AT_name) 1853 name := dwa.data.(string) 1854 if die.sym == nil { 1855 fmt.Println("Missing sym for ", name) 1856 } 1857 adddwarfref(Ctxt, s, die.sym, 4) 1858 Addstring(s, name) 1859 } 1860 1861 Adduint32(Ctxt, s, 0) 1862 1863 setuint32(Ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field. 1864 } 1865 1866 return s 1867 } 1868 1869 /* 1870 * emit .debug_aranges. _info must have been written before, 1871 * because we need die->offs of dw_globals. 1872 */ 1873 func writearanges(prev *LSym) *LSym { 1874 s := Linklookup(Ctxt, ".debug_aranges", 0) 1875 s.Type = obj.SDWARFSECT 1876 // The first tuple is aligned to a multiple of the size of a single tuple 1877 // (twice the size of an address) 1878 headersize := int(Rnd(4+2+4+1+1, int64(SysArch.PtrSize*2))) // don't count unit_length field itself 1879 1880 for compunit := dwroot.child; compunit != nil; compunit = compunit.link { 1881 b := getattr(compunit, DW_AT_low_pc) 1882 if b == nil { 1883 continue 1884 } 1885 e := getattr(compunit, DW_AT_high_pc) 1886 if e == nil { 1887 continue 1888 } 1889 1890 // Write .debug_aranges Header + entry (sec 6.1.2) 1891 unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4 1892 Adduint32(Ctxt, s, unitlength) // unit_length (*) 1893 Adduint16(Ctxt, s, 2) // dwarf version (appendix F) 1894 1895 adddwarfref(Ctxt, s, compunit.sym, 4) 1896 1897 Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size 1898 Adduint8(Ctxt, s, 0) // segment_size 1899 padding := headersize - (4 + 2 + 4 + 1 + 1) 1900 for i := 0; i < padding; i++ { 1901 Adduint8(Ctxt, s, 0) 1902 } 1903 1904 Addaddrplus(Ctxt, s, b.data.(*LSym), b.value-(b.data.(*LSym)).Value) 1905 addrput(s, e.value-b.value) 1906 addrput(s, 0) 1907 addrput(s, 0) 1908 } 1909 if s.Size > 0 { 1910 prev.Next = s 1911 prev = s 1912 } 1913 return prev 1914 } 1915 1916 func writegdbscript(prev *LSym) *LSym { 1917 1918 if gdbscript != "" { 1919 s := Linklookup(Ctxt, ".debug_gdb_scripts", 0) 1920 s.Type = obj.SDWARFSECT 1921 prev.Next = s 1922 prev = s 1923 Adduint8(Ctxt, s, 1) // magic 1 byte? 1924 Addstring(s, gdbscript) 1925 } 1926 1927 return prev 1928 } 1929 1930 var prototypedies map[string]*DWDie 1931 1932 /* 1933 * This is the main entry point for generating dwarf. After emitting 1934 * the mandatory debug_abbrev section, it calls writelines() to set up 1935 * the per-compilation unit part of the DIE tree, while simultaneously 1936 * emitting the debug_line section. When the final tree contains 1937 * forward references, it will write the debug_info section in 2 1938 * passes. 1939 * 1940 */ 1941 func dwarfgeneratedebugsyms() { 1942 if Debug['w'] != 0 { // disable dwarf 1943 return 1944 } 1945 if Debug['s'] != 0 && HEADTYPE != obj.Hdarwin { 1946 return 1947 } 1948 if HEADTYPE == obj.Hplan9 { 1949 return 1950 } 1951 1952 if Linkmode == LinkExternal { 1953 if !Iself && HEADTYPE != obj.Hdarwin { 1954 return 1955 } 1956 } 1957 1958 if Debug['v'] != 0 { 1959 fmt.Fprintf(Bso, "%5.2f dwarf\n", obj.Cputime()) 1960 } 1961 1962 // For diagnostic messages. 1963 newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 1964 1965 // Some types that must exist to define other ones. 1966 newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>", 0) 1967 1968 newdie(&dwtypes, DW_ABRV_NULLTYPE, "void", 0) 1969 newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0) 1970 1971 die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size 1972 newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0) 1973 newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0) 1974 newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0) 1975 1976 // Prototypes needed for type synthesis. 1977 prototypedies = map[string]*DWDie{ 1978 "type.runtime.stringStructDWARF": nil, 1979 "type.runtime.slice": nil, 1980 "type.runtime.hmap": nil, 1981 "type.runtime.bmap": nil, 1982 "type.runtime.sudog": nil, 1983 "type.runtime.waitq": nil, 1984 "type.runtime.hchan": nil, 1985 } 1986 1987 // Needed by the prettyprinter code for interface inspection. 1988 defgotype(lookup_or_diag("type.runtime._type")) 1989 1990 defgotype(lookup_or_diag("type.runtime.interfacetype")) 1991 defgotype(lookup_or_diag("type.runtime.itab")) 1992 1993 genasmsym(defdwsymb) 1994 1995 dwarfp = writeabbrev() 1996 last := dwarfp 1997 last = writelines(last) 1998 last = writeframes(last) 1999 2000 synthesizestringtypes(dwtypes.child) 2001 synthesizeslicetypes(dwtypes.child) 2002 synthesizemaptypes(dwtypes.child) 2003 synthesizechantypes(dwtypes.child) 2004 2005 reversetree(&dwroot.child) 2006 reversetree(&dwtypes.child) 2007 reversetree(&dwglobals.child) 2008 2009 movetomodule(&dwtypes) 2010 movetomodule(&dwglobals) 2011 2012 // Need to reorder symbols so SDWARFINFO is after all SDWARFSECT 2013 // (but we need to generate dies before writepub) 2014 writeinfo(last) 2015 infosyms := last.Next 2016 2017 last = writepub(".debug_pubnames", ispubname, last) 2018 last = writepub(".debug_pubtypes", ispubtype, last) 2019 last = writearanges(last) 2020 last = writegdbscript(last) 2021 last.Next = infosyms 2022 } 2023 2024 /* 2025 * Elf. 2026 */ 2027 func dwarfaddshstrings(shstrtab *LSym) { 2028 if Debug['w'] != 0 { // disable dwarf 2029 return 2030 } 2031 2032 Addstring(shstrtab, ".debug_abbrev") 2033 Addstring(shstrtab, ".debug_aranges") 2034 Addstring(shstrtab, ".debug_frame") 2035 Addstring(shstrtab, ".debug_info") 2036 Addstring(shstrtab, ".debug_line") 2037 Addstring(shstrtab, ".debug_pubnames") 2038 Addstring(shstrtab, ".debug_pubtypes") 2039 Addstring(shstrtab, ".debug_gdb_scripts") 2040 if Linkmode == LinkExternal { 2041 Addstring(shstrtab, elfRelType+".debug_info") 2042 Addstring(shstrtab, elfRelType+".debug_aranges") 2043 Addstring(shstrtab, elfRelType+".debug_line") 2044 Addstring(shstrtab, elfRelType+".debug_frame") 2045 Addstring(shstrtab, elfRelType+".debug_pubnames") 2046 Addstring(shstrtab, elfRelType+".debug_pubtypes") 2047 } 2048 } 2049 2050 // Add section symbols for DWARF debug info. This is called before 2051 // dwarfaddelfheaders. 2052 func dwarfaddelfsectionsyms() { 2053 if Debug['w'] != 0 { // disable dwarf 2054 return 2055 } 2056 if Linkmode != LinkExternal { 2057 return 2058 } 2059 sym := Linklookup(Ctxt, ".debug_info", 0) 2060 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 2061 sym = Linklookup(Ctxt, ".debug_abbrev", 0) 2062 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 2063 sym = Linklookup(Ctxt, ".debug_line", 0) 2064 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 2065 sym = Linklookup(Ctxt, ".debug_frame", 0) 2066 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 2067 } 2068 2069 /* 2070 * Windows PE 2071 */ 2072 func dwarfaddpeheaders() { 2073 if Debug['w'] != 0 { // disable dwarf 2074 return 2075 } 2076 for sect := Segdwarf.Sect; sect != nil; sect = sect.Next { 2077 h := newPEDWARFSection(sect.Name, int64(sect.Length)) 2078 fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff 2079 if uint64(h.PointerToRawData) != fileoff { 2080 Diag("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff) 2081 errorexit() 2082 } 2083 } 2084 }