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