1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved 6 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 8 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/dwarfdbginf.d, backend/dwarfdbginf.d) 9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/backend/dwarfdbginf.d 10 */ 11 12 // Emit Dwarf symbolic debug info 13 14 /* 15 Some generic information for debug info on macOS: 16 17 The linker on macOS will remove any debug info, i.e. every section with the 18 `S_ATTR_DEBUG` flag, this includes everything in the `__DWARF` section. By using 19 the `S_REGULAR` flag the linker will not remove this section. This allows to get 20 the filenames and line numbers for backtraces from the executable. 21 22 Normally the linker removes all the debug info but adds a reference to the 23 object files. The debugger can then read the object files to get filename and 24 line number information. It's also possible to use an additional tool that 25 generates a separate `.dSYM` file. This file can then later be deployed with the 26 application if debug info is needed when the application is deployed. 27 */ 28 29 module dmd.backend.dwarfdbginf; 30 31 version (SCPP) 32 version = COMPILE; 33 version (MARS) 34 version = COMPILE; 35 36 version (COMPILE) 37 { 38 39 import core.stdc.stdio; 40 import core.stdc.stdlib; 41 import core.stdc.string; 42 import core.stdc.errno; 43 44 version(Windows) 45 { 46 extern (C) char* getcwd(char* buffer, size_t maxlen); 47 extern (C) int* _errno(); // not the multi-threaded version 48 } 49 else 50 { 51 import core.sys.posix.unistd : getcwd; 52 } 53 54 import dmd.backend.cc; 55 import dmd.backend.cdef; 56 import dmd.backend.code; 57 import dmd.backend.code_x86; 58 import dmd.backend.mem; 59 import dmd.backend.dlist; 60 import dmd.backend.el; 61 import dmd.backend.global; 62 import dmd.backend.obj; 63 import dmd.backend.oper; 64 import dmd.backend.outbuf; 65 import dmd.backend.ty; 66 import dmd.backend.type; 67 68 static if (ELFOBJ || MACHOBJ) 69 { 70 71 import dmd.backend.aarray; 72 73 static if (ELFOBJ) 74 import dmd.backend.melf; 75 76 static if (MACHOBJ) 77 import dmd.backend.mach; 78 79 import dmd.backend.dwarf; 80 import dmd.backend.dwarf2; 81 82 83 extern (C++): 84 85 nothrow: 86 87 int REGSIZE(); 88 89 __gshared 90 { 91 extern int seg_count; 92 93 static if (MACHOBJ) 94 { 95 int except_table_seg = 0; // __gcc_except_tab segment 96 int except_table_num = 0; // sequence number for GCC_except_table%d symbols 97 int eh_frame_seg = 0; // __eh_frame segment 98 Symbol *eh_frame_sym = null; // past end of __eh_frame 99 } 100 101 uint CIE_offset_unwind; // CIE offset for unwind data 102 uint CIE_offset_no_unwind; // CIE offset for no unwind data 103 104 static if (ELFOBJ) 105 { 106 IDXSYM elf_addsym(IDXSTR nam, targ_size_t val, uint sz, 107 uint typ, uint bind, IDXSEC sec, 108 ubyte visibility = STV_DEFAULT); 109 void addSegmentToComdat(segidx_t seg, segidx_t comdatseg); 110 } 111 112 Symbol* getRtlsymPersonality(); 113 114 private Outbuffer *reset_symbuf; // Keep pointers to reset symbols 115 } 116 117 /*********************************** 118 * Determine if generating a eh_frame with full 119 * unwinding information. 120 * This decision is done on a per-function basis. 121 * Returns: 122 * true if unwinding needs to be done 123 */ 124 bool doUnwindEhFrame() 125 { 126 if (funcsym_p.Sfunc.Fflags3 & Feh_none) 127 { 128 return (config.exe & (EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64)) != 0; 129 } 130 131 /* FreeBSD fails when having some frames as having unwinding info and some not. 132 * (It hangs in unittests for std.datetime.) 133 * g++ on FreeBSD does not generate mixed frames, while g++ on OSX and Linux does. 134 */ 135 assert(!(usednteh & ~(EHtry | EHcleanup))); 136 return (usednteh & (EHtry | EHcleanup)) || 137 (config.exe & (EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64)) && config.useExceptions; 138 } 139 140 static if (ELFOBJ) 141 SYMIDX MAP_SEG2SYMIDX(int seg) { return SegData[seg].SDsymidx; } 142 else 143 SYMIDX MAP_SEG2SYMIDX(int seg) { assert(0); } 144 145 146 int OFFSET_FAC() { return REGSIZE(); } 147 148 int dwarf_getsegment(const(char)* name, int align_, int flags) 149 { 150 static if (ELFOBJ) 151 return Obj.getsegment(name, null, flags, 0, align_ * 4); 152 else static if (MACHOBJ) 153 return Obj.getsegment(name, "__DWARF", align_ * 2, flags); 154 else 155 assert(0); 156 } 157 158 static if (ELFOBJ) 159 { 160 int dwarf_getsegment_alloc(const(char)* name, const(char)* suffix, int align_) 161 { 162 return Obj.getsegment(name, suffix, SHT_PROGBITS, SHF_ALLOC, align_ * 4); 163 } 164 } 165 166 int dwarf_except_table_alloc(Symbol *s) 167 { 168 //printf("dwarf_except_table_alloc('%s')\n", s.Sident.ptr); 169 static if (ELFOBJ) 170 { 171 /* If `s` is in a COMDAT, then this table needs to go into 172 * a unique section, which then gets added to the COMDAT group 173 * associated with `s`. 174 */ 175 seg_data *pseg = SegData[s.Sseg]; 176 if (pseg.SDassocseg) 177 { 178 const(char)* suffix = s.Sident.ptr; // cpp_mangle(s); 179 segidx_t tableseg = Obj.getsegment(".gcc_except_table.", suffix, SHT_PROGBITS, SHF_ALLOC|SHF_GROUP, 1); 180 addSegmentToComdat(tableseg, s.Sseg); 181 return tableseg; 182 } 183 else 184 return dwarf_getsegment_alloc(".gcc_except_table", null, 1); 185 } 186 else static if (MACHOBJ) 187 { 188 int seg = Obj.getsegment("__gcc_except_tab", "__TEXT", 2, S_REGULAR); 189 except_table_seg = seg; 190 return seg; 191 } 192 else 193 assert(0); 194 } 195 196 int dwarf_eh_frame_alloc() 197 { 198 static if (ELFOBJ) 199 return dwarf_getsegment_alloc(".eh_frame", null, I64 ? 2 : 1); 200 else static if (MACHOBJ) 201 { 202 int seg = Obj.getsegment("__eh_frame", "__TEXT", I64 ? 3 : 2, 203 S_COALESCED | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS | S_ATTR_LIVE_SUPPORT); 204 /* Generate symbol for it to use for fixups 205 */ 206 if (!eh_frame_sym) 207 { 208 type *t = tspvoid; 209 t.Tcount++; 210 type_setmangle(&t, mTYman_sys); // no leading '_' for mangled name 211 eh_frame_sym = symbol_name("EH_frame0", SCstatic, t); 212 Obj.pubdef(seg, eh_frame_sym, 0); 213 symbol_keep(eh_frame_sym); 214 eh_frame_seg = seg; 215 } 216 return seg; 217 } 218 else 219 assert(0); 220 } 221 222 // machobj.c 223 enum RELaddr = 0; // straight address 224 enum RELrel = 1; // relative to location to be fixed up 225 226 void dwarf_addrel(int seg, targ_size_t offset, int targseg, targ_size_t val = 0) 227 { 228 static if (ELFOBJ) 229 Obj.addrel(seg, offset, I64 ? R_X86_64_32 : R_386_32, MAP_SEG2SYMIDX(targseg), val); 230 else static if (MACHOBJ) 231 Obj.addrel(seg, offset, null, targseg, RELaddr, cast(uint)val); 232 else 233 assert(0); 234 } 235 236 void dwarf_addrel64(int seg, targ_size_t offset, int targseg, targ_size_t val) 237 { 238 static if (ELFOBJ) 239 Obj.addrel(seg, offset, R_X86_64_64, MAP_SEG2SYMIDX(targseg), val); 240 else static if (MACHOBJ) 241 Obj.addrel(seg, offset, null, targseg, RELaddr, cast(uint)val); 242 else 243 assert(0); 244 } 245 246 void dwarf_appreladdr(int seg, Outbuffer *buf, int targseg, targ_size_t val) 247 { 248 if (I64) 249 { 250 dwarf_addrel64(seg, buf.length(), targseg, val); 251 buf.write64(0); 252 } 253 else 254 { 255 dwarf_addrel(seg, buf.length(), targseg, 0); 256 buf.write32(cast(uint)val); 257 } 258 } 259 260 void dwarf_apprel32(int seg, Outbuffer *buf, int targseg, targ_size_t val) 261 { 262 dwarf_addrel(seg, buf.length(), targseg, I64 ? val : 0); 263 buf.write32(I64 ? 0 : cast(uint)val); 264 } 265 266 void append_addr(Outbuffer *buf, targ_size_t addr) 267 { 268 if (I64) 269 buf.write64(addr); 270 else 271 buf.write32(cast(uint)addr); 272 } 273 274 275 /************************ DWARF DEBUG OUTPUT ********************************/ 276 277 // Dwarf Symbolic Debugging Information 278 279 // CFA = value of the stack pointer at the call site in the previous frame 280 281 struct CFA_reg 282 { 283 int offset; // offset from CFA 284 } 285 286 // Current CFA state for .debug_frame 287 struct CFA_state 288 { 289 size_t location; 290 int reg; // CFA register number 291 int offset; // CFA register offset 292 CFA_reg[17] regstates; // register states 293 } 294 295 /*********************** 296 * Convert CPU register number to Dwarf register number. 297 * Params: 298 * reg = CPU register 299 * Returns: 300 * dwarf register 301 */ 302 int dwarf_regno(int reg) 303 { 304 assert(reg < NUMGENREGS); 305 if (I32) 306 { 307 static if (MACHOBJ) 308 { 309 if (reg == BP || reg == SP) 310 reg ^= BP ^ SP; // swap EBP and ESP register values for OSX (!) 311 } 312 return reg; 313 } 314 else 315 { 316 assert(I64); 317 /* See https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf 318 * Figure 3.3.8 pg. 62 319 * R8..15 : 8..15 320 * XMM0..15 : 17..32 321 * ST0..7 : 33..40 322 * MM0..7 : 41..48 323 * XMM16..31 : 67..82 324 */ 325 static immutable int[8] to_amd64_reg_map = 326 // AX CX DX BX SP BP SI DI 327 [ 0, 2, 1, 3, 7, 6, 4, 5 ]; 328 return reg < 8 ? to_amd64_reg_map[reg] : reg; 329 } 330 } 331 332 private __gshared 333 { 334 CFA_state CFA_state_init_32 = // initial CFA state as defined by CIE 335 { 0, // location 336 -1, // register 337 4, // offset 338 [ { 0 }, // 0: EAX 339 { 0 }, // 1: ECX 340 { 0 }, // 2: EDX 341 { 0 }, // 3: EBX 342 { 0 }, // 4: ESP 343 { 0 }, // 5: EBP 344 { 0 }, // 6: ESI 345 { 0 }, // 7: EDI 346 { -4 }, // 8: EIP 347 ] 348 }; 349 350 CFA_state CFA_state_init_64 = // initial CFA state as defined by CIE 351 { 0, // location 352 -1, // register 353 8, // offset 354 [ { 0 }, // 0: RAX 355 { 0 }, // 1: RBX 356 { 0 }, // 2: RCX 357 { 0 }, // 3: RDX 358 { 0 }, // 4: RSI 359 { 0 }, // 5: RDI 360 { 0 }, // 6: RBP 361 { 0 }, // 7: RSP 362 { 0 }, // 8: R8 363 { 0 }, // 9: R9 364 { 0 }, // 10: R10 365 { 0 }, // 11: R11 366 { 0 }, // 12: R12 367 { 0 }, // 13: R13 368 { 0 }, // 14: R14 369 { 0 }, // 15: R15 370 { -8 }, // 16: RIP 371 ] 372 }; 373 374 CFA_state CFA_state_current; // current CFA state 375 Outbuffer cfa_buf; // CFA instructions 376 } 377 378 /*********************************** 379 * Set the location, i.e. the offset from the start 380 * of the function. It must always be greater than 381 * the current location. 382 * Params: 383 * location = offset from the start of the function 384 */ 385 void dwarf_CFA_set_loc(uint location) 386 { 387 assert(location >= CFA_state_current.location); 388 uint inc = cast(uint)(location - CFA_state_current.location); 389 if (inc <= 63) 390 cfa_buf.writeByte(DW_CFA_advance_loc + inc); 391 else if (inc <= 255) 392 { cfa_buf.writeByte(DW_CFA_advance_loc1); 393 cfa_buf.writeByte(inc); 394 } 395 else if (inc <= 0xFFFF) 396 { cfa_buf.writeByte(DW_CFA_advance_loc2); 397 cfa_buf.write16(inc); 398 } 399 else 400 { cfa_buf.writeByte(DW_CFA_advance_loc4); 401 cfa_buf.write32(inc); 402 } 403 CFA_state_current.location = location; 404 } 405 406 /******************************************* 407 * Set the frame register, and its offset. 408 * Params: 409 * reg = machine register 410 * offset = offset from frame register 411 */ 412 void dwarf_CFA_set_reg_offset(int reg, int offset) 413 { 414 int dw_reg = dwarf_regno(reg); 415 if (dw_reg != CFA_state_current.reg) 416 { 417 if (offset == CFA_state_current.offset) 418 { 419 cfa_buf.writeByte(DW_CFA_def_cfa_register); 420 cfa_buf.writeuLEB128(dw_reg); 421 } 422 else if (offset < 0) 423 { 424 cfa_buf.writeByte(DW_CFA_def_cfa_sf); 425 cfa_buf.writeuLEB128(dw_reg); 426 cfa_buf.writesLEB128(offset / -OFFSET_FAC); 427 } 428 else 429 { 430 cfa_buf.writeByte(DW_CFA_def_cfa); 431 cfa_buf.writeuLEB128(dw_reg); 432 cfa_buf.writeuLEB128(offset); 433 } 434 } 435 else if (offset < 0) 436 { 437 cfa_buf.writeByte(DW_CFA_def_cfa_offset_sf); 438 cfa_buf.writesLEB128(offset / -OFFSET_FAC); 439 } 440 else 441 { 442 cfa_buf.writeByte(DW_CFA_def_cfa_offset); 443 cfa_buf.writeuLEB128(offset); 444 } 445 CFA_state_current.reg = dw_reg; 446 CFA_state_current.offset = offset; 447 } 448 449 /*********************************************** 450 * Set reg to be at offset from frame register. 451 * Params: 452 * reg = machine register 453 * offset = offset from frame register 454 */ 455 void dwarf_CFA_offset(int reg, int offset) 456 { 457 int dw_reg = dwarf_regno(reg); 458 if (CFA_state_current.regstates[dw_reg].offset != offset) 459 { 460 if (offset <= 0) 461 { 462 cfa_buf.writeByte(DW_CFA_offset + dw_reg); 463 cfa_buf.writeuLEB128(offset / -OFFSET_FAC); 464 } 465 else 466 { 467 cfa_buf.writeByte(DW_CFA_offset_extended_sf); 468 cfa_buf.writeuLEB128(dw_reg); 469 cfa_buf.writesLEB128(offset / -OFFSET_FAC); 470 } 471 } 472 CFA_state_current.regstates[dw_reg].offset = offset; 473 } 474 475 /************************************** 476 * Set total size of arguments pushed on the stack. 477 * Params: 478 * sz = total size 479 */ 480 void dwarf_CFA_args_size(size_t sz) 481 { 482 cfa_buf.writeByte(DW_CFA_GNU_args_size); 483 cfa_buf.writeuLEB128(cast(uint)sz); 484 } 485 486 struct Section 487 { 488 segidx_t seg = 0; 489 IDXSEC secidx = 0; 490 Outbuffer *buf = null; 491 const(char)* name; 492 493 static if (MACHOBJ) 494 immutable flags = S_ATTR_DEBUG; 495 else 496 immutable flags = SHT_PROGBITS; 497 498 /* Allocate and initialize Section 499 */ 500 nothrow void initialize() 501 { 502 const segidx_t segi = dwarf_getsegment(name, 0, flags); 503 seg = segi; 504 secidx = SegData[segi].SDshtidx; 505 buf = SegData[segi].SDbuf; 506 buf.reserve(1000); 507 } 508 } 509 510 511 private __gshared 512 { 513 514 static if (MACHOBJ) 515 { 516 Section debug_pubnames = { name: "__debug_pubnames" }; 517 Section debug_aranges = { name: "__debug_aranges" }; 518 Section debug_ranges = { name: "__debug_ranges" }; 519 Section debug_loc = { name: "__debug_loc" }; 520 Section debug_abbrev = { name: "__debug_abbrev" }; 521 Section debug_info = { name: "__debug_info" }; 522 Section debug_str = { name: "__debug_str" }; 523 // We use S_REGULAR to make sure the linker doesn't remove this section. Needed 524 // for filenames and line numbers in backtraces. 525 Section debug_line = { name: "__debug_line", flags: S_REGULAR }; 526 } 527 else static if (ELFOBJ) 528 { 529 Section debug_pubnames = { name: ".debug_pubnames" }; 530 Section debug_aranges = { name: ".debug_aranges" }; 531 Section debug_ranges = { name: ".debug_ranges" }; 532 Section debug_loc = { name: ".debug_loc" }; 533 Section debug_abbrev = { name: ".debug_abbrev" }; 534 Section debug_info = { name: ".debug_info" }; 535 Section debug_str = { name: ".debug_str" }; 536 Section debug_line = { name: ".debug_line" }; 537 } 538 539 static if (MACHOBJ) 540 const char* debug_frame_name = "__debug_frame"; 541 else static if (ELFOBJ) 542 const char* debug_frame_name = ".debug_frame"; 543 544 545 /* DWARF 7.5.3: "Each declaration begins with an unsigned LEB128 number 546 * representing the abbreviation code itself." 547 */ 548 uint abbrevcode = 1; 549 AApair *abbrev_table; 550 int hasModname; // 1 if has DW_TAG_module 551 552 // .debug_info 553 AAchars *infoFileName_table; 554 555 AApair *type_table; 556 AApair *functype_table; // not sure why this cannot be combined with type_table 557 Outbuffer *functypebuf; 558 559 struct DebugInfoHeader 560 { 561 align (1): 562 uint total_length; 563 ushort version_; 564 uint abbrev_offset; 565 ubyte address_size; 566 } 567 // Workaround https://issues.dlang.org/show_bug.cgi?id=16563 568 // Struct alignment is ignored due to 2.072 regression. 569 static assert((DebugInfoHeader.alignof == 1 && DebugInfoHeader.sizeof == 11) || 570 (DebugInfoHeader.alignof == 4 && DebugInfoHeader.sizeof == 12)); 571 572 DebugInfoHeader debuginfo_init = 573 { 0, // total_length 574 3, // version_ 575 0, // abbrev_offset 576 4 // address_size 577 }; 578 579 DebugInfoHeader debuginfo; 580 581 // .debug_line 582 size_t linebuf_filetab_end; 583 584 struct DebugLineHeader 585 { 586 align (1): 587 uint total_length; 588 ushort version_; 589 uint prologue_length; 590 ubyte minimum_instruction_length; 591 ubyte default_is_stmt; 592 byte line_base; 593 ubyte line_range; 594 ubyte opcode_base; 595 ubyte[9] standard_opcode_lengths; 596 } 597 static assert(DebugLineHeader.sizeof == 24); 598 599 DebugLineHeader debugline_init = 600 { 0, // total_length 601 2, // version_ 602 0, // prologue_length 603 1, // minimum_instruction_length 604 true, // default_is_stmt 605 -5, // line_base 606 14, // line_range 607 10, // opcode_base 608 [ 0,1,1,1,1,0,0,0,1 ] 609 }; 610 611 DebugLineHeader debugline; 612 613 public uint[TYMAX] typidx_tab; 614 } 615 616 /***************************************** 617 * Append .debug_frame header to buf. 618 * Params: 619 * buf = write raw data here 620 */ 621 void writeDebugFrameHeader(Outbuffer *buf) 622 { 623 static struct DebugFrameHeader 624 { 625 align (1): 626 uint length; 627 uint CIE_id; 628 ubyte version_; 629 ubyte augmentation; 630 ubyte code_alignment_factor; 631 ubyte data_alignment_factor; 632 ubyte return_address_register; 633 ubyte[11] opcodes; 634 } 635 static assert(DebugFrameHeader.sizeof == 24); 636 637 __gshared DebugFrameHeader debugFrameHeader = 638 { 16, // length 639 0xFFFFFFFF, // CIE_id 640 1, // version_ 641 0, // augmentation 642 1, // code alignment factor 643 0x7C, // data alignment factor (-4) 644 8, // return address register 645 [ 646 DW_CFA_def_cfa, 4,4, // r4,4 [r7,8] 647 DW_CFA_offset +8,1, // r8,1 [r16,1] 648 DW_CFA_nop, DW_CFA_nop, 649 DW_CFA_nop, DW_CFA_nop, // 64 padding 650 DW_CFA_nop, DW_CFA_nop, // 64 padding 651 ] 652 }; 653 if (I64) 654 { debugFrameHeader.length = 20; 655 debugFrameHeader.data_alignment_factor = 0x78; // (-8) 656 debugFrameHeader.return_address_register = 16; 657 debugFrameHeader.opcodes[1] = 7; // RSP 658 debugFrameHeader.opcodes[2] = 8; 659 debugFrameHeader.opcodes[3] = DW_CFA_offset + 16; // RIP 660 } 661 assert(debugFrameHeader.data_alignment_factor == 0x80 - OFFSET_FAC); 662 663 buf.writen(&debugFrameHeader,debugFrameHeader.length + 4); 664 } 665 666 /***************************************** 667 * Append .eh_frame header to buf. 668 * Almost identical to .debug_frame 669 * Params: 670 * dfseg = SegData[] index for .eh_frame 671 * buf = write raw data here 672 * personality = "__dmd_personality_v0" 673 * ehunwind = will have EH unwind table 674 * Returns: 675 * offset of start of this header 676 * See_Also: 677 * https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html 678 */ 679 private uint writeEhFrameHeader(IDXSEC dfseg, Outbuffer *buf, Symbol *personality, bool ehunwind) 680 { 681 /* Augmentation string: 682 * z = first character, means Augmentation Data field is present 683 * eh = EH Data field is present 684 * P = Augmentation Data contains 2 args: 685 * 1. encoding of 2nd arg 686 * 2. address of personality routine 687 * L = Augmentation Data contains 1 arg: 688 * 1. the encoding used for Augmentation Data in FDE 689 * Augmentation Data in FDE: 690 * 1. address of LSDA (gcc_except_table) 691 * R = Augmentation Data contains 1 arg: 692 * 1. encoding of addresses in FDE 693 * Non-EH code: "zR" 694 * EH code: "zPLR" 695 */ 696 697 const uint startsize = cast(uint)buf.length(); 698 699 // Length of CIE, not including padding 700 const uint cielen = 4 + 4 + 1 + 701 (ehunwind ? 5 : 3) + 702 1 + 1 + 1 + 703 (ehunwind ? 8 : 2) + 704 5; 705 706 const uint pad = -cielen & (I64 ? 7 : 3); // pad to addressing unit size boundary 707 const uint length = cielen + pad - 4; 708 709 buf.reserve(length + 4); 710 buf.write32(length); // length of CIE, not including length and extended length fields 711 buf.write32(0); // CIE ID 712 buf.writeByten(1); // version_ 713 if (ehunwind) 714 buf.write("zPLR".ptr, 5); // Augmentation String 715 else 716 buf.writen("zR".ptr, 3); 717 // not present: EH Data: 4 bytes for I32, 8 bytes for I64 718 buf.writeByten(1); // code alignment factor 719 buf.writeByten(cast(ubyte)(0x80 - OFFSET_FAC)); // data alignment factor (I64 ? -8 : -4) 720 buf.writeByten(I64 ? 16 : 8); // return address register 721 if (ehunwind) 722 { 723 static if (ELFOBJ) 724 { 725 const ubyte personality_pointer_encoding = config.flags3 & CFG3pic 726 ? DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 727 : DW_EH_PE_absptr | DW_EH_PE_udata4; 728 const ubyte LSDA_pointer_encoding = config.flags3 & CFG3pic 729 ? DW_EH_PE_pcrel | DW_EH_PE_sdata4 730 : DW_EH_PE_absptr | DW_EH_PE_udata4; 731 const ubyte address_pointer_encoding = 732 DW_EH_PE_pcrel | DW_EH_PE_sdata4; 733 } 734 else static if (MACHOBJ) 735 { 736 const ubyte personality_pointer_encoding = 737 DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4; 738 const ubyte LSDA_pointer_encoding = 739 DW_EH_PE_pcrel | DW_EH_PE_ptr; 740 const ubyte address_pointer_encoding = 741 DW_EH_PE_pcrel | DW_EH_PE_ptr; 742 } 743 buf.writeByten(7); // Augmentation Length 744 buf.writeByten(personality_pointer_encoding); // P: personality routine address encoding 745 /* MACHOBJ 64: pcrel 1 length 2 extern 1 RELOC_GOT 746 * 32: [4] address x0013 pcrel 0 length 2 value xfc type 4 RELOC_LOCAL_SECTDIFF 747 * [5] address x0000 pcrel 0 length 2 value xc7 type 1 RELOC_PAIR 748 */ 749 dwarf_reftoident(dfseg, buf.length(), personality, 0); 750 buf.writeByten(LSDA_pointer_encoding); // L: address encoding for LSDA in FDE 751 buf.writeByten(address_pointer_encoding); // R: encoding of addresses in FDE 752 } 753 else 754 { 755 buf.writeByten(1); // Augmentation Length 756 757 static if (ELFOBJ) 758 buf.writeByten(DW_EH_PE_pcrel | DW_EH_PE_sdata4); // R: encoding of addresses in FDE 759 static if (MACHOBJ) 760 buf.writeByten(DW_EH_PE_pcrel | DW_EH_PE_ptr); // R: encoding of addresses in FDE 761 } 762 763 // Set CFA beginning state at function entry point 764 if (I64) 765 { 766 buf.writeByten(DW_CFA_def_cfa); // DEF_CFA r7,8 RSP is at offset 8 767 buf.writeByten(7); // r7 is RSP 768 buf.writeByten(8); 769 770 buf.writeByten(DW_CFA_offset + 16); // OFFSET r16,1 RIP is at -8*1[RSP] 771 buf.writeByten(1); 772 } 773 else 774 { 775 buf.writeByten(DW_CFA_def_cfa); // DEF_CFA ESP,4 776 buf.writeByten(cast(ubyte)dwarf_regno(SP)); 777 buf.writeByten(4); 778 779 buf.writeByten(DW_CFA_offset + 8); // OFFSET r8,1 780 buf.writeByten(1); 781 } 782 783 for (uint i = 0; i < pad; ++i) 784 buf.writeByten(DW_CFA_nop); 785 786 assert(startsize + length + 4 == buf.length()); 787 return startsize; 788 } 789 790 /********************************************* 791 * Generate function's Frame Description Entry into .debug_frame 792 * Params: 793 * dfseg = SegData[] index for .debug_frame 794 * sfunc = the function 795 */ 796 void writeDebugFrameFDE(IDXSEC dfseg, Symbol *sfunc) 797 { 798 if (I64) 799 { 800 static struct DebugFrameFDE64 801 { 802 align (1): 803 uint length; 804 uint CIE_pointer; 805 ulong initial_location; 806 ulong address_range; 807 } 808 static assert(DebugFrameFDE64.sizeof == 24); 809 810 __gshared DebugFrameFDE64 debugFrameFDE64 = 811 { 20, // length 812 0, // CIE_pointer 813 0, // initial_location 814 0, // address_range 815 }; 816 817 // Pad to 8 byte boundary 818 for (uint n = (-cfa_buf.length() & 7); n; n--) 819 cfa_buf.writeByte(DW_CFA_nop); 820 821 debugFrameFDE64.length = 20 + cast(uint)cfa_buf.length(); 822 debugFrameFDE64.address_range = sfunc.Ssize; 823 // Do we need this? 824 //debugFrameFDE64.initial_location = sfunc.Soffset; 825 826 Outbuffer *debug_frame_buf = SegData[dfseg].SDbuf; 827 uint debug_frame_buf_offset = cast(uint)debug_frame_buf.length(); 828 debug_frame_buf.reserve(1000); 829 debug_frame_buf.writen(&debugFrameFDE64,debugFrameFDE64.sizeof); 830 debug_frame_buf.write(cfa_buf[]); 831 832 static if (ELFOBJ) 833 // Absolute address for debug_frame, relative offset for eh_frame 834 dwarf_addrel(dfseg,debug_frame_buf_offset + 4,dfseg,0); 835 836 dwarf_addrel64(dfseg,debug_frame_buf_offset + 8,sfunc.Sseg,0); 837 } 838 else 839 { 840 static struct DebugFrameFDE32 841 { 842 align (1): 843 uint length; 844 uint CIE_pointer; 845 uint initial_location; 846 uint address_range; 847 } 848 static assert(DebugFrameFDE32.sizeof == 16); 849 850 __gshared DebugFrameFDE32 debugFrameFDE32 = 851 { 12, // length 852 0, // CIE_pointer 853 0, // initial_location 854 0, // address_range 855 }; 856 857 // Pad to 4 byte boundary 858 for (uint n = (-cfa_buf.length() & 3); n; n--) 859 cfa_buf.writeByte(DW_CFA_nop); 860 861 debugFrameFDE32.length = 12 + cast(uint)cfa_buf.length(); 862 debugFrameFDE32.address_range = cast(uint)sfunc.Ssize; 863 // Do we need this? 864 //debugFrameFDE32.initial_location = sfunc.Soffset; 865 866 Outbuffer *debug_frame_buf = SegData[dfseg].SDbuf; 867 uint debug_frame_buf_offset = cast(uint)debug_frame_buf.length(); 868 debug_frame_buf.reserve(1000); 869 debug_frame_buf.writen(&debugFrameFDE32,debugFrameFDE32.sizeof); 870 debug_frame_buf.write(cfa_buf[]); 871 872 static if (ELFOBJ) 873 // Absolute address for debug_frame, relative offset for eh_frame 874 dwarf_addrel(dfseg,debug_frame_buf_offset + 4,dfseg,0); 875 876 dwarf_addrel(dfseg,debug_frame_buf_offset + 8,sfunc.Sseg,0); 877 } 878 } 879 880 /********************************************* 881 * Append function's FDE (Frame Description Entry) to .eh_frame 882 * Params: 883 * dfseg = SegData[] index for .eh_frame 884 * sfunc = the function 885 * ehunwind = will have EH unwind table 886 * CIE_offset = offset of enclosing CIE 887 */ 888 void writeEhFrameFDE(IDXSEC dfseg, Symbol *sfunc, bool ehunwind, uint CIE_offset) 889 { 890 Outbuffer *buf = SegData[dfseg].SDbuf; 891 const uint startsize = cast(uint)buf.length(); 892 893 static if (MACHOBJ) 894 { 895 /* Create symbol named "funcname.eh" for the start of the FDE 896 */ 897 Symbol *fdesym; 898 { 899 const size_t len = strlen(sfunc.Sident.ptr); 900 char *name = cast(char *)malloc(len + 3 + 1); 901 if (!name) 902 err_nomem(); 903 memcpy(name, sfunc.Sident.ptr, len); 904 memcpy(name + len, ".eh".ptr, 3 + 1); 905 fdesym = symbol_name(name, SCglobal, tspvoid); 906 Obj.pubdef(dfseg, fdesym, startsize); 907 symbol_keep(fdesym); 908 } 909 } 910 911 if (sfunc.ty() & mTYnaked) 912 { 913 /* Do not have info on naked functions. Assume they are set up as: 914 * push RBP 915 * mov RSP,RSP 916 */ 917 int off = 2 * REGSIZE; 918 dwarf_CFA_set_loc(1); 919 dwarf_CFA_set_reg_offset(SP, off); 920 dwarf_CFA_offset(BP, -off); 921 dwarf_CFA_set_loc(I64 ? 4 : 3); 922 dwarf_CFA_set_reg_offset(BP, off); 923 } 924 925 // Length of FDE, not including padding 926 static if (ELFOBJ) 927 const uint fdelen = 4 + 4 928 + 4 + 4 929 + (ehunwind ? 5 : 1) + cast(uint)cfa_buf.length(); 930 else static if (MACHOBJ) 931 const uint fdelen = 4 + 4 932 + (I64 ? 8 + 8 : 4 + 4) // PC_Begin + PC_Range 933 + (ehunwind ? (I64 ? 9 : 5) : 1) + cast(uint)cfa_buf.length(); 934 935 const uint pad = -fdelen & (I64 ? 7 : 3); // pad to addressing unit size boundary 936 const uint length = fdelen + pad - 4; 937 938 buf.reserve(length + 4); 939 buf.write32(length); // Length (no Extended Length) 940 buf.write32((startsize + 4) - CIE_offset); // CIE Pointer 941 static if (ELFOBJ) 942 { 943 int fixup = I64 ? R_X86_64_PC32 : R_386_PC32; 944 buf.write32(cast(uint)(I64 ? 0 : sfunc.Soffset)); // address of function 945 Obj.addrel(dfseg, startsize + 8, fixup, MAP_SEG2SYMIDX(sfunc.Sseg), sfunc.Soffset); 946 //Obj.reftoident(dfseg, startsize + 8, sfunc, 0, CFpc32 | CFoff); // PC_begin 947 buf.write32(cast(uint)sfunc.Ssize); // PC Range 948 } 949 else static if (MACHOBJ) 950 { 951 dwarf_eh_frame_fixup(dfseg, buf.length(), sfunc, 0, fdesym); 952 953 if (I64) 954 buf.write64(sfunc.Ssize); // PC Range 955 else 956 buf.write32(cast(uint)sfunc.Ssize); // PC Range 957 } 958 else 959 assert(0); 960 961 if (ehunwind) 962 { 963 int etseg = dwarf_except_table_alloc(sfunc); 964 static if (ELFOBJ) 965 { 966 buf.writeByten(4); // Augmentation Data Length 967 buf.write32(I64 ? 0 : sfunc.Sfunc.LSDAoffset); // address of LSDA (".gcc_except_table") 968 if (config.flags3 & CFG3pic) 969 { 970 Obj.addrel(dfseg, buf.length() - 4, fixup, MAP_SEG2SYMIDX(etseg), sfunc.Sfunc.LSDAoffset); 971 } 972 else 973 dwarf_addrel(dfseg, buf.length() - 4, etseg, sfunc.Sfunc.LSDAoffset); // and the fixup 974 } 975 else static if (MACHOBJ) 976 { 977 buf.writeByten(I64 ? 8 : 4); // Augmentation Data Length 978 dwarf_eh_frame_fixup(dfseg, buf.length(), sfunc.Sfunc.LSDAsym, 0, fdesym); 979 } 980 } 981 else 982 buf.writeByten(0); // Augmentation Data Length 983 984 buf.write(cfa_buf[]); 985 986 for (uint i = 0; i < pad; ++i) 987 buf.writeByten(DW_CFA_nop); 988 989 assert(startsize + length + 4 == buf.length()); 990 } 991 992 void dwarf_initfile(const(char)* filename) 993 { 994 dwarf_initfile(filename ? filename[0 .. strlen(filename)] : null); 995 } 996 997 extern(D) void dwarf_initfile(const(char)[] filename) 998 { 999 if (config.ehmethod == EHmethod.EH_DWARF) 1000 { 1001 static if (MACHOBJ) 1002 { 1003 except_table_seg = 0; 1004 except_table_num = 0; 1005 eh_frame_seg = 0; 1006 eh_frame_sym = null; 1007 } 1008 CIE_offset_unwind = ~0; 1009 CIE_offset_no_unwind = ~0; 1010 //dwarf_except_table_alloc(); 1011 dwarf_eh_frame_alloc(); 1012 } 1013 if (!config.fulltypes) 1014 return; 1015 if (config.ehmethod == EHmethod.EH_DM) 1016 { 1017 static if (MACHOBJ) 1018 int flags = S_ATTR_DEBUG; 1019 else static if (ELFOBJ) 1020 int flags = SHT_PROGBITS; 1021 1022 int seg = dwarf_getsegment(debug_frame_name, 1, flags); 1023 Outbuffer *buf = SegData[seg].SDbuf; 1024 buf.reserve(1000); 1025 writeDebugFrameHeader(buf); 1026 } 1027 1028 /* ======================================== */ 1029 1030 if (reset_symbuf) 1031 { 1032 Symbol **p = cast(Symbol **)reset_symbuf.buf; 1033 const size_t n = reset_symbuf.length() / (Symbol *).sizeof; 1034 for (size_t i = 0; i < n; ++i) 1035 symbol_reset(p[i]); 1036 reset_symbuf.reset(); 1037 } 1038 else 1039 { 1040 reset_symbuf = cast(Outbuffer*) calloc(1, Outbuffer.sizeof); 1041 assert(reset_symbuf); 1042 reset_symbuf.reserve(50 * (Symbol *).sizeof); 1043 } 1044 1045 /* ======================================== */ 1046 1047 debug_str.initialize(); 1048 //Outbuffer *debug_str_buf = debug_str.buf; 1049 1050 /* ======================================== */ 1051 1052 debug_ranges.initialize(); 1053 1054 /* ======================================== */ 1055 1056 debug_loc.initialize(); 1057 1058 /* ======================================== */ 1059 1060 if (infoFileName_table) 1061 { 1062 AAchars.destroy(infoFileName_table); 1063 infoFileName_table = null; 1064 } 1065 1066 debug_line.initialize(); 1067 1068 debugline = debugline_init; 1069 1070 debug_line.buf.write(&debugline, debugline.sizeof); 1071 1072 // include_directories 1073 version (SCPP) 1074 for (size_t i = 0; i < pathlist.length(); ++i) 1075 { 1076 debug_line.buf.writeString(pathlist[i]); 1077 debug_line.buf.writeByte(0); 1078 } 1079 1080 version (MARS) version (none) 1081 for (int i = 0; i < global.params.imppath.dim; i++) 1082 { 1083 debug_line.buf.writeString((*global.params.imppath)[i]); 1084 debug_line.buf.writeByte(0); 1085 } 1086 1087 debug_line.buf.writeByte(0); // terminated with 0 byte 1088 1089 /* ======================================== */ 1090 1091 debug_abbrev.initialize(); 1092 abbrevcode = 1; 1093 1094 // Free only if starting another file. Waste of time otherwise. 1095 if (abbrev_table) 1096 { 1097 AApair.destroy(abbrev_table); 1098 abbrev_table = null; 1099 } 1100 1101 static immutable ubyte[21] abbrevHeader = 1102 [ 1103 1, // abbreviation code 1104 DW_TAG_compile_unit, 1105 1, 1106 DW_AT_producer, DW_FORM_string, 1107 DW_AT_language, DW_FORM_data1, 1108 DW_AT_name, DW_FORM_string, 1109 DW_AT_comp_dir, DW_FORM_string, 1110 DW_AT_low_pc, DW_FORM_addr, 1111 DW_AT_entry_pc, DW_FORM_addr, 1112 DW_AT_ranges, DW_FORM_data4, 1113 DW_AT_stmt_list, DW_FORM_data4, 1114 0, 0, 1115 ]; 1116 1117 debug_abbrev.buf.write(abbrevHeader.ptr,abbrevHeader.sizeof); 1118 1119 /* ======================================== */ 1120 1121 debug_info.initialize(); 1122 1123 debuginfo = debuginfo_init; 1124 if (I64) 1125 debuginfo.address_size = 8; 1126 1127 // Workaround https://issues.dlang.org/show_bug.cgi?id=16563 1128 // Struct alignment is ignored due to 2.072 regression. 1129 static if (debuginfo.alignof == 1) 1130 debug_info.buf.write(&debuginfo, debuginfo.sizeof); 1131 else 1132 { 1133 debug_info.buf.write(&debuginfo.total_length, 4); 1134 debug_info.buf.write(&debuginfo.version_, 2); 1135 debug_info.buf.write(&debuginfo.abbrev_offset, 4); 1136 debug_info.buf.write(&debuginfo.address_size, 1); 1137 } 1138 static if (ELFOBJ) 1139 dwarf_addrel(debug_info.seg,6,debug_abbrev.seg); 1140 1141 debug_info.buf.writeuLEB128(1); // abbreviation code 1142 1143 version (MARS) 1144 { 1145 debug_info.buf.write("Digital Mars D "); 1146 debug_info.buf.write(config._version); // DW_AT_producer 1147 // DW_AT_language 1148 debug_info.buf.writeByte((config.fulltypes == CVDWARF_D) ? DW_LANG_D : DW_LANG_C89); 1149 } 1150 else version (SCPP) 1151 { 1152 debug_info.buf.write("Digital Mars C "); 1153 debug_info.buf.writeString(global._version); // DW_AT_producer 1154 debug_info.buf.writeByte(DW_LANG_C89); // DW_AT_language 1155 } 1156 else 1157 static assert(0); 1158 1159 debug_info.buf.writeString(filename); // DW_AT_name 1160 1161 static if (0) 1162 { 1163 // This relies on an extension to POSIX.1 not always implemented 1164 char *cwd = getcwd(null, 0); 1165 } 1166 else 1167 { 1168 char *cwd; 1169 size_t sz = 80; 1170 while (1) 1171 { 1172 errno = 0; 1173 cwd = cast(char *)malloc(sz + 1); 1174 if (!cwd) 1175 err_nomem(); 1176 char *buf = getcwd(cwd, sz); 1177 if (buf) 1178 { cwd[sz] = 0; // man page doesn't say if always 0 terminated 1179 break; 1180 } 1181 if (errno == ERANGE) 1182 { 1183 sz += 80; 1184 free(cwd); 1185 continue; 1186 } 1187 cwd[0] = 0; 1188 break; 1189 } 1190 } 1191 //debug_info.buf.write32(Obj.addstr(debug_str_buf, cwd)); // DW_AT_comp_dir as DW_FORM_strp, doesn't work on some systems 1192 debug_info.buf.writeString(cwd); // DW_AT_comp_dir as DW_FORM_string 1193 free(cwd); 1194 1195 append_addr(debug_info.buf, 0); // DW_AT_low_pc 1196 append_addr(debug_info.buf, 0); // DW_AT_entry_pc 1197 1198 static if (ELFOBJ) 1199 dwarf_addrel(debug_info.seg,debug_info.buf.length(),debug_ranges.seg); 1200 1201 debug_info.buf.write32(0); // DW_AT_ranges 1202 1203 static if (ELFOBJ) 1204 dwarf_addrel(debug_info.seg,debug_info.buf.length(),debug_line.seg); 1205 1206 debug_info.buf.write32(0); // DW_AT_stmt_list 1207 1208 memset(typidx_tab.ptr, 0, typidx_tab.sizeof); 1209 1210 /* ======================================== */ 1211 1212 debug_pubnames.initialize(); 1213 int seg = debug_pubnames.seg; 1214 1215 debug_pubnames.buf.write32(0); // unit_length 1216 debug_pubnames.buf.write16(2); // version_ 1217 1218 static if (ELFOBJ) 1219 dwarf_addrel(seg,debug_pubnames.buf.length(),debug_info.seg); 1220 1221 debug_pubnames.buf.write32(0); // debug_info_offset 1222 debug_pubnames.buf.write32(0); // debug_info_length 1223 1224 /* ======================================== */ 1225 1226 debug_aranges.initialize(); 1227 1228 debug_aranges.buf.write32(0); // unit_length 1229 debug_aranges.buf.write16(2); // version_ 1230 1231 static if (ELFOBJ) 1232 dwarf_addrel(debug_aranges.seg,debug_aranges.buf.length(),debug_info.seg); 1233 1234 debug_aranges.buf.write32(0); // debug_info_offset 1235 debug_aranges.buf.writeByte(I64 ? 8 : 4); // address_size 1236 debug_aranges.buf.writeByte(0); // segment_size 1237 debug_aranges.buf.write32(0); // pad to 16 1238 } 1239 1240 1241 /************************************* 1242 * Add a file to the .debug_line header 1243 */ 1244 int dwarf_line_addfile(const(char)* filename) 1245 { 1246 return dwarf_line_addfile(filename ? filename[0 .. strlen(filename)] : null); 1247 } 1248 1249 /// Ditto 1250 extern(D) int dwarf_line_addfile(const(char)[] filename) 1251 { 1252 if (!infoFileName_table) { 1253 infoFileName_table = AAchars.create(); 1254 linebuf_filetab_end = debug_line.buf.length(); 1255 } 1256 1257 uint *pidx = infoFileName_table.get(filename); 1258 if (!*pidx) // if no idx assigned yet 1259 { 1260 *pidx = infoFileName_table.length(); // assign newly computed idx 1261 1262 size_t before = debug_line.buf.length(); 1263 debug_line.buf.writeString(filename); 1264 debug_line.buf.writeByte(0); // directory table index 1265 debug_line.buf.writeByte(0); // mtime 1266 debug_line.buf.writeByte(0); // length 1267 linebuf_filetab_end += debug_line.buf.length() - before; 1268 } 1269 1270 return *pidx; 1271 } 1272 1273 void dwarf_initmodule(const(char)* filename, const(char)* modname) 1274 { 1275 dwarf_initmodule(filename ? filename[0 .. strlen(filename)] : null, 1276 modname ? modname[0 .. strlen(modname)] : null); 1277 } 1278 1279 extern(D) void dwarf_initmodule(const(char)[] filename, const(char)[] modname) 1280 { 1281 if (modname) 1282 { 1283 static immutable ubyte[6] abbrevModule = 1284 [ 1285 DW_TAG_module, 1286 //1, // one children 1287 0, // no children 1288 DW_AT_name, DW_FORM_string, // module name 1289 0, 0, 1290 ]; 1291 abbrevcode++; 1292 debug_abbrev.buf.writeuLEB128(abbrevcode); 1293 debug_abbrev.buf.write(abbrevModule.ptr, abbrevModule.sizeof); 1294 debug_info.buf.writeuLEB128(abbrevcode); // abbreviation code 1295 debug_info.buf.writeString(modname); // DW_AT_name 1296 //hasModname = 1; 1297 } 1298 else 1299 hasModname = 0; 1300 1301 dwarf_line_addfile(filename); 1302 } 1303 1304 void dwarf_termmodule() 1305 { 1306 if (hasModname) 1307 debug_info.buf.writeByte(0); // end of DW_TAG_module's children 1308 } 1309 1310 /************************************* 1311 * Finish writing Dwarf debug info to object file. 1312 */ 1313 1314 void dwarf_termfile() 1315 { 1316 //printf("dwarf_termfile()\n"); 1317 1318 /* ======================================== */ 1319 1320 // Put out line number info 1321 1322 // file_names 1323 uint last_filenumber = 0; 1324 const(char)* last_filename = null; 1325 for (uint seg = 1; seg <= seg_count; seg++) 1326 { 1327 for (uint i = 0; i < SegData[seg].SDlinnum_count; i++) 1328 { 1329 linnum_data *ld = &SegData[seg].SDlinnum_data[i]; 1330 const(char)* filename; 1331 version (MARS) 1332 filename = ld.filename; 1333 else 1334 { 1335 Sfile *sf = ld.filptr; 1336 if (sf) 1337 filename = sf.SFname; 1338 else 1339 filename = .filename; 1340 } 1341 if (last_filename == filename) 1342 { 1343 ld.filenumber = last_filenumber; 1344 } 1345 else 1346 { 1347 ld.filenumber = dwarf_line_addfile(filename); 1348 1349 last_filenumber = ld.filenumber; 1350 last_filename = filename; 1351 } 1352 } 1353 } 1354 // assert we haven't emitted anything but file table entries 1355 assert(debug_line.buf.length() == linebuf_filetab_end); 1356 debug_line.buf.writeByte(0); // end of file_names 1357 1358 debugline.prologue_length = cast(uint)debug_line.buf.length() - 10; 1359 1360 for (uint seg = 1; seg <= seg_count; seg++) 1361 { 1362 seg_data *sd = SegData[seg]; 1363 uint addressmax = 0; 1364 uint linestart = ~0; 1365 1366 if (!sd.SDlinnum_count) 1367 continue; 1368 1369 static if (ELFOBJ) 1370 if (!sd.SDsym) // gdb ignores line number data without a DW_AT_name 1371 continue; 1372 1373 //printf("sd = %x, SDlinnum_count = %d\n", sd, sd.SDlinnum_count); 1374 for (int i = 0; i < sd.SDlinnum_count; i++) 1375 { linnum_data *ld = &sd.SDlinnum_data[i]; 1376 1377 // Set address to start of segment with DW_LNE_set_address 1378 debug_line.buf.writeByte(0); 1379 debug_line.buf.writeByte(_tysize[TYnptr] + 1); 1380 debug_line.buf.writeByte(DW_LNE_set_address); 1381 1382 dwarf_appreladdr(debug_line.seg,debug_line.buf,seg,0); 1383 1384 // Dwarf2 6.2.2 State machine registers 1385 uint address = 0; // instruction address 1386 uint file = ld.filenumber; 1387 uint line = 1; // line numbers beginning with 1 1388 1389 debug_line.buf.writeByte(DW_LNS_set_file); 1390 debug_line.buf.writeuLEB128(file); 1391 1392 for (int j = 0; j < ld.linoff_count; j++) 1393 { int lininc = ld.linoff[j][0] - line; 1394 int addinc = ld.linoff[j][1] - address; 1395 1396 //printf("\tld[%d] line = %d offset = x%x lininc = %d addinc = %d\n", j, ld.linoff[j][0], ld.linoff[j][1], lininc, addinc); 1397 1398 //assert(addinc >= 0); 1399 if (addinc < 0) 1400 continue; 1401 if (j && lininc == 0 && !(addinc && j + 1 == ld.linoff_count)) 1402 continue; 1403 line += lininc; 1404 if (line < linestart) 1405 linestart = line; 1406 address += addinc; 1407 if (address >= addressmax) 1408 addressmax = address + 1; 1409 if (lininc >= debugline.line_base && lininc < debugline.line_base + debugline.line_range) 1410 { uint opcode = lininc - debugline.line_base + 1411 debugline.line_range * addinc + 1412 debugline.opcode_base; 1413 1414 if (opcode <= 255) 1415 { debug_line.buf.writeByte(opcode); 1416 continue; 1417 } 1418 } 1419 if (lininc) 1420 { 1421 debug_line.buf.writeByte(DW_LNS_advance_line); 1422 debug_line.buf.writesLEB128(cast(int)lininc); 1423 } 1424 if (addinc) 1425 { 1426 debug_line.buf.writeByte(DW_LNS_advance_pc); 1427 debug_line.buf.writeuLEB128(cast(uint)addinc); 1428 } 1429 if (lininc || addinc) 1430 debug_line.buf.writeByte(DW_LNS_copy); 1431 } 1432 1433 // Write DW_LNS_advance_pc to cover the function prologue 1434 debug_line.buf.writeByte(DW_LNS_advance_pc); 1435 debug_line.buf.writeuLEB128(cast(uint)(sd.SDbuf.length() - address)); 1436 1437 // Write DW_LNE_end_sequence 1438 debug_line.buf.writeByte(0); 1439 debug_line.buf.writeByte(1); 1440 debug_line.buf.writeByte(1); 1441 1442 // reset linnum_data 1443 ld.linoff_count = 0; 1444 } 1445 } 1446 1447 debugline.total_length = cast(uint)debug_line.buf.length() - 4; 1448 memcpy(debug_line.buf.buf, &debugline, debugline.sizeof); 1449 1450 // Bugzilla 3502, workaround OSX's ld64-77 bug. 1451 // Don't emit the the debug_line section if nothing has been written to the line table. 1452 if (debugline.prologue_length + 10 == debugline.total_length + 4) 1453 debug_line.buf.reset(); 1454 1455 /* ================================================= */ 1456 1457 debug_abbrev.buf.writeByte(0); 1458 1459 /* ================================================= */ 1460 1461 debug_info.buf.writeByte(0); // ending abbreviation code 1462 1463 debuginfo.total_length = cast(uint)debug_info.buf.length() - 4; 1464 // Workaround https://issues.dlang.org/show_bug.cgi?id=16563 1465 // Struct alignment is ignored due to 2.072 regression. 1466 static if (debuginfo.alignof == 1) 1467 memcpy(debug_info.buf.buf, &debuginfo, debuginfo.sizeof); 1468 else 1469 { 1470 memcpy(debug_info.buf.buf, &debuginfo.total_length, 4); 1471 memcpy(debug_info.buf.buf+4, &debuginfo.version_, 2); 1472 memcpy(debug_info.buf.buf+6, &debuginfo.abbrev_offset, 4); 1473 memcpy(debug_info.buf.buf+10, &debuginfo.address_size, 1); 1474 } 1475 1476 /* ================================================= */ 1477 1478 // Terminate by offset field containing 0 1479 debug_pubnames.buf.write32(0); 1480 1481 // Plug final sizes into header 1482 *cast(uint *)debug_pubnames.buf.buf = cast(uint)debug_pubnames.buf.length() - 4; 1483 *cast(uint *)(debug_pubnames.buf.buf + 10) = cast(uint)debug_info.buf.length(); 1484 1485 /* ================================================= */ 1486 1487 // Terminate by address/length fields containing 0 1488 append_addr(debug_aranges.buf, 0); 1489 append_addr(debug_aranges.buf, 0); 1490 1491 // Plug final sizes into header 1492 *cast(uint *)debug_aranges.buf.buf = cast(uint)debug_aranges.buf.length() - 4; 1493 1494 /* ================================================= */ 1495 1496 // Terminate by beg address/end address fields containing 0 1497 append_addr(debug_ranges.buf, 0); 1498 append_addr(debug_ranges.buf, 0); 1499 1500 /* ================================================= */ 1501 1502 // Free only if starting another file. Waste of time otherwise. 1503 if (type_table) 1504 { 1505 AApair.destroy(type_table); 1506 type_table = null; 1507 } 1508 if (functype_table) 1509 { 1510 AApair.destroy(functype_table); 1511 functype_table = null; 1512 } 1513 if (functypebuf) 1514 functypebuf.reset(); 1515 } 1516 1517 /***************************************** 1518 * Start of code gen for function. 1519 */ 1520 void dwarf_func_start(Symbol *sfunc) 1521 { 1522 //printf("dwarf_func_start(%s)\n", sfunc.Sident.ptr); 1523 if (I16 || I32) 1524 CFA_state_current = CFA_state_init_32; 1525 else if (I64) 1526 CFA_state_current = CFA_state_init_64; 1527 else 1528 assert(0); 1529 CFA_state_current.reg = dwarf_regno(SP); 1530 assert(CFA_state_current.offset == OFFSET_FAC); 1531 cfa_buf.reset(); 1532 } 1533 1534 /***************************************** 1535 * End of code gen for function. 1536 */ 1537 void dwarf_func_term(Symbol *sfunc) 1538 { 1539 //printf("dwarf_func_term(sfunc = '%s')\n", sfunc.Sident.ptr); 1540 1541 if (config.ehmethod == EHmethod.EH_DWARF) 1542 { 1543 bool ehunwind = doUnwindEhFrame(); 1544 1545 IDXSEC dfseg = dwarf_eh_frame_alloc(); 1546 1547 Outbuffer *buf = SegData[dfseg].SDbuf; 1548 buf.reserve(1000); 1549 1550 uint *poffset = ehunwind ? &CIE_offset_unwind : &CIE_offset_no_unwind; 1551 if (*poffset == ~0) 1552 *poffset = writeEhFrameHeader(dfseg, buf, getRtlsymPersonality(), ehunwind); 1553 1554 writeEhFrameFDE(dfseg, sfunc, ehunwind, *poffset); 1555 } 1556 if (!config.fulltypes) 1557 return; 1558 1559 version (MARS) 1560 { 1561 if (sfunc.Sflags & SFLnodebug) 1562 return; 1563 const(char)* filename = sfunc.Sfunc.Fstartline.Sfilename; 1564 if (!filename) 1565 return; 1566 } 1567 1568 uint funcabbrevcode; 1569 1570 if (ehmethod(sfunc) == EHmethod.EH_DM) 1571 { 1572 static if (MACHOBJ) 1573 int flags = S_ATTR_DEBUG; 1574 else static if (ELFOBJ) 1575 int flags = SHT_PROGBITS; 1576 1577 IDXSEC dfseg = dwarf_getsegment(debug_frame_name, 1, flags); 1578 writeDebugFrameFDE(dfseg, sfunc); 1579 } 1580 1581 IDXSEC seg = sfunc.Sseg; 1582 seg_data *sd = SegData[seg]; 1583 1584 version (MARS) 1585 int filenum = dwarf_line_addfile(filename); 1586 else 1587 int filenum = 1; 1588 1589 uint ret_type = dwarf_typidx(sfunc.Stype.Tnext); 1590 if (tybasic(sfunc.Stype.Tnext.Tty) == TYvoid) 1591 ret_type = 0; 1592 1593 // See if there are any parameters 1594 int haveparameters = 0; 1595 uint formalcode = 0; 1596 uint autocode = 0; 1597 for (SYMIDX si = 0; si < globsym.top; si++) 1598 { 1599 Symbol *sa = globsym.tab[si]; 1600 1601 version (MARS) 1602 if (sa.Sflags & SFLnodebug) continue; 1603 1604 __gshared ubyte[12] formal = 1605 [ 1606 DW_TAG_formal_parameter, 1607 0, 1608 DW_AT_name, DW_FORM_string, 1609 DW_AT_type, DW_FORM_ref4, 1610 DW_AT_artificial, DW_FORM_flag, 1611 DW_AT_location, DW_FORM_block1, 1612 0, 0, 1613 ]; 1614 1615 switch (sa.Sclass) 1616 { 1617 case SCparameter: 1618 case SCregpar: 1619 case SCfastpar: 1620 dwarf_typidx(sa.Stype); 1621 formal[0] = DW_TAG_formal_parameter; 1622 if (!formalcode) 1623 formalcode = dwarf_abbrev_code(formal.ptr, formal.sizeof); 1624 haveparameters = 1; 1625 break; 1626 1627 case SCauto: 1628 case SCbprel: 1629 case SCregister: 1630 case SCpseudo: 1631 dwarf_typidx(sa.Stype); 1632 formal[0] = DW_TAG_variable; 1633 if (!autocode) 1634 autocode = dwarf_abbrev_code(formal.ptr, formal.sizeof); 1635 haveparameters = 1; 1636 break; 1637 1638 default: 1639 break; 1640 } 1641 } 1642 1643 Outbuffer abuf; 1644 abuf.writeByte(DW_TAG_subprogram); 1645 abuf.writeByte(haveparameters); // have children? 1646 if (haveparameters) 1647 { 1648 abuf.writeByte(DW_AT_sibling); abuf.writeByte(DW_FORM_ref4); 1649 } 1650 abuf.writeByte(DW_AT_name); abuf.writeByte(DW_FORM_string); 1651 1652 static if (DWARF_VERSION >= 4) 1653 { 1654 abuf.writeuLEB128(DW_AT_linkage_name); abuf.writeByte(DW_FORM_string); 1655 } 1656 else 1657 { 1658 abuf.writeuLEB128(DW_AT_MIPS_linkage_name); abuf.writeByte(DW_FORM_string); 1659 } 1660 1661 abuf.writeByte(DW_AT_decl_file); abuf.writeByte(DW_FORM_data1); 1662 abuf.writeByte(DW_AT_decl_line); abuf.writeByte(DW_FORM_data2); 1663 if (ret_type) 1664 { 1665 abuf.writeByte(DW_AT_type); abuf.writeByte(DW_FORM_ref4); 1666 } 1667 if (sfunc.Sclass == SCglobal) 1668 { 1669 abuf.writeByte(DW_AT_external); abuf.writeByte(DW_FORM_flag); 1670 } 1671 abuf.writeByte(DW_AT_low_pc); abuf.writeByte(DW_FORM_addr); 1672 abuf.writeByte(DW_AT_high_pc); abuf.writeByte(DW_FORM_addr); 1673 abuf.writeByte(DW_AT_frame_base); abuf.writeByte(DW_FORM_data4); 1674 abuf.writeByte(0); abuf.writeByte(0); 1675 1676 funcabbrevcode = dwarf_abbrev_code(abuf.buf, abuf.length()); 1677 1678 uint idxsibling = 0; 1679 uint siblingoffset; 1680 1681 uint infobuf_offset = cast(uint)debug_info.buf.length(); 1682 debug_info.buf.writeuLEB128(funcabbrevcode); // abbreviation code 1683 if (haveparameters) 1684 { 1685 siblingoffset = cast(uint)debug_info.buf.length(); 1686 debug_info.buf.write32(idxsibling); // DW_AT_sibling 1687 } 1688 1689 const(char)* name; 1690 1691 version (MARS) 1692 name = sfunc.prettyIdent ? sfunc.prettyIdent : sfunc.Sident.ptr; 1693 else 1694 name = sfunc.Sident.ptr; 1695 1696 debug_info.buf.writeString(name); // DW_AT_name 1697 debug_info.buf.writeString(sfunc.Sident.ptr); // DW_AT_MIPS_linkage_name 1698 debug_info.buf.writeByte(filenum); // DW_AT_decl_file 1699 debug_info.buf.write16(sfunc.Sfunc.Fstartline.Slinnum); // DW_AT_decl_line 1700 if (ret_type) 1701 debug_info.buf.write32(ret_type); // DW_AT_type 1702 1703 if (sfunc.Sclass == SCglobal) 1704 debug_info.buf.writeByte(1); // DW_AT_external 1705 1706 // DW_AT_low_pc and DW_AT_high_pc 1707 dwarf_appreladdr(debug_info.seg, debug_info.buf, seg, funcoffset); 1708 dwarf_appreladdr(debug_info.seg, debug_info.buf, seg, funcoffset + sfunc.Ssize); 1709 1710 // DW_AT_frame_base 1711 static if (ELFOBJ) 1712 dwarf_apprel32(debug_info.seg, debug_info.buf, debug_loc.seg, debug_loc.buf.length()); 1713 else 1714 // 64-bit DWARF relocations don't work for OSX64 codegen 1715 debug_info.buf.write32(cast(uint)debug_loc.buf.length()); 1716 1717 if (haveparameters) 1718 { 1719 for (SYMIDX si = 0; si < globsym.top; si++) 1720 { 1721 Symbol *sa = globsym.tab[si]; 1722 1723 version (MARS) 1724 if (sa.Sflags & SFLnodebug) continue; 1725 1726 uint vcode; 1727 1728 switch (sa.Sclass) 1729 { 1730 case SCparameter: 1731 case SCregpar: 1732 case SCfastpar: 1733 vcode = formalcode; 1734 goto L1; 1735 case SCauto: 1736 case SCregister: 1737 case SCpseudo: 1738 case SCbprel: 1739 vcode = autocode; 1740 L1: 1741 { 1742 uint soffset; 1743 uint tidx = dwarf_typidx(sa.Stype); 1744 1745 debug_info.buf.writeuLEB128(vcode); // abbreviation code 1746 debug_info.buf.writeString(sa.Sident.ptr); // DW_AT_name 1747 debug_info.buf.write32(tidx); // DW_AT_type 1748 debug_info.buf.writeByte(sa.Sflags & SFLartifical ? 1 : 0); // DW_FORM_tag 1749 soffset = cast(uint)debug_info.buf.length(); 1750 debug_info.buf.writeByte(2); // DW_FORM_block1 1751 if (sa.Sfl == FLreg || sa.Sclass == SCpseudo) 1752 { // BUG: register pairs not supported in Dwarf? 1753 debug_info.buf.writeByte(DW_OP_reg0 + sa.Sreglsw); 1754 } 1755 else if (sa.Sscope && vcode == autocode) 1756 { 1757 assert(sa.Sscope.Stype.Tnext && sa.Sscope.Stype.Tnext.Tty == TYstruct); 1758 1759 /* find member offset in closure */ 1760 targ_size_t memb_off = 0; 1761 struct_t *st = sa.Sscope.Stype.Tnext.Ttag.Sstruct; // Sscope is __closptr 1762 foreach (sl; ListRange(st.Sfldlst)) 1763 { 1764 Symbol *sf = list_symbol(sl); 1765 if (sf.Sclass == SCmember) 1766 { 1767 if(strcmp(sa.Sident.ptr, sf.Sident.ptr) == 0) 1768 { 1769 memb_off = sf.Smemoff; 1770 goto L2; 1771 } 1772 } 1773 } 1774 L2: 1775 targ_size_t closptr_off = sa.Sscope.Soffset; // __closptr offset 1776 //printf("dwarf closure: sym: %s, closptr: %s, ptr_off: %lli, memb_off: %lli\n", 1777 // sa.Sident.ptr, sa.Sscope.Sident.ptr, closptr_off, memb_off); 1778 1779 debug_info.buf.writeByte(DW_OP_fbreg); 1780 debug_info.buf.writesLEB128(cast(uint)(Auto.size + BPoff - Para.size + closptr_off)); // closure pointer offset from frame base 1781 debug_info.buf.writeByte(DW_OP_deref); 1782 debug_info.buf.writeByte(DW_OP_plus_uconst); 1783 debug_info.buf.writeuLEB128(cast(uint)memb_off); // closure variable offset 1784 } 1785 else 1786 { 1787 debug_info.buf.writeByte(DW_OP_fbreg); 1788 if (sa.Sclass == SCregpar || 1789 sa.Sclass == SCparameter) 1790 debug_info.buf.writesLEB128(cast(int)sa.Soffset); 1791 else if (sa.Sclass == SCfastpar) 1792 debug_info.buf.writesLEB128(cast(int)(Fast.size + BPoff - Para.size + sa.Soffset)); 1793 else if (sa.Sclass == SCbprel) 1794 debug_info.buf.writesLEB128(cast(int)(-Para.size + sa.Soffset)); 1795 else 1796 debug_info.buf.writesLEB128(cast(int)(Auto.size + BPoff - Para.size + sa.Soffset)); 1797 } 1798 debug_info.buf.buf[soffset] = cast(ubyte)(debug_info.buf.length() - soffset - 1); 1799 break; 1800 } 1801 1802 default: 1803 break; 1804 } 1805 } 1806 debug_info.buf.writeByte(0); // end of parameter children 1807 1808 idxsibling = cast(uint)debug_info.buf.length(); 1809 *cast(uint *)(debug_info.buf.buf + siblingoffset) = idxsibling; 1810 } 1811 1812 /* ============= debug_pubnames =========================== */ 1813 1814 debug_pubnames.buf.write32(infobuf_offset); 1815 // Should be the fully qualified name, not the simple DW_AT_name 1816 debug_pubnames.buf.writeString(sfunc.Sident.ptr); 1817 1818 /* ============= debug_aranges =========================== */ 1819 1820 if (sd.SDaranges_offset) 1821 // Extend existing entry size 1822 *cast(ulong *)(debug_aranges.buf.buf + sd.SDaranges_offset + _tysize[TYnptr]) = funcoffset + sfunc.Ssize; 1823 else 1824 { // Add entry 1825 sd.SDaranges_offset = cast(uint)debug_aranges.buf.length(); 1826 // address of start of .text segment 1827 dwarf_appreladdr(debug_aranges.seg, debug_aranges.buf, seg, 0); 1828 // size of .text segment 1829 append_addr(debug_aranges.buf, funcoffset + sfunc.Ssize); 1830 } 1831 1832 /* ============= debug_ranges =========================== */ 1833 1834 /* Each function gets written into its own segment, 1835 * indicate this by adding to the debug_ranges 1836 */ 1837 // start of function and end of function 1838 dwarf_appreladdr(debug_ranges.seg, debug_ranges.buf, seg, funcoffset); 1839 dwarf_appreladdr(debug_ranges.seg, debug_ranges.buf, seg, funcoffset + sfunc.Ssize); 1840 1841 /* ============= debug_loc =========================== */ 1842 1843 assert(Para.size >= 2 * REGSIZE); 1844 assert(Para.size < 63); // avoid sLEB128 encoding 1845 ushort op_size = 0x0002; 1846 ushort loc_op; 1847 1848 // set the entry for this function in .debug_loc segment 1849 // after call 1850 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + 0); 1851 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + 1); 1852 1853 loc_op = cast(ushort)(((Para.size - REGSIZE) << 8) | (DW_OP_breg0 + dwarf_regno(SP))); 1854 debug_loc.buf.write32(loc_op << 16 | op_size); 1855 1856 // after push EBP 1857 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + 1); 1858 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + 3); 1859 1860 loc_op = cast(ushort)(((Para.size) << 8) | (DW_OP_breg0 + dwarf_regno(SP))); 1861 debug_loc.buf.write32(loc_op << 16 | op_size); 1862 1863 // after mov EBP, ESP 1864 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + 3); 1865 dwarf_appreladdr(debug_loc.seg, debug_loc.buf, seg, funcoffset + sfunc.Ssize); 1866 1867 loc_op = cast(ushort)(((Para.size) << 8) | (DW_OP_breg0 + dwarf_regno(BP))); 1868 debug_loc.buf.write32(loc_op << 16 | op_size); 1869 1870 // 2 zero addresses to end loc_list 1871 append_addr(debug_loc.buf, 0); 1872 append_addr(debug_loc.buf, 0); 1873 } 1874 1875 1876 /****************************************** 1877 * Write out symbol table for current function. 1878 */ 1879 1880 void cv_outsym(Symbol *s) 1881 { 1882 //printf("cv_outsym('%s')\n",s.Sident.ptr); 1883 //symbol_print(s); 1884 1885 symbol_debug(s); 1886 1887 version (MARS) 1888 { 1889 if (s.Sflags & SFLnodebug) 1890 return; 1891 } 1892 type *t = s.Stype; 1893 type_debug(t); 1894 tym_t tym = tybasic(t.Tty); 1895 if (tyfunc(tym) && s.Sclass != SCtypedef) 1896 return; 1897 1898 Outbuffer abuf; 1899 uint code; 1900 uint typidx; 1901 uint soffset; 1902 switch (s.Sclass) 1903 { 1904 case SCglobal: 1905 typidx = dwarf_typidx(t); 1906 1907 abuf.writeByte(DW_TAG_variable); 1908 abuf.writeByte(0); // no children 1909 abuf.writeByte(DW_AT_name); abuf.writeByte(DW_FORM_string); 1910 abuf.writeByte(DW_AT_type); abuf.writeByte(DW_FORM_ref4); 1911 abuf.writeByte(DW_AT_external); abuf.writeByte(DW_FORM_flag); 1912 abuf.writeByte(DW_AT_location); abuf.writeByte(DW_FORM_block1); 1913 abuf.writeByte(0); abuf.writeByte(0); 1914 code = dwarf_abbrev_code(abuf.buf, abuf.length()); 1915 1916 debug_info.buf.writeuLEB128(code); // abbreviation code 1917 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 1918 debug_info.buf.write32(typidx); // DW_AT_type 1919 debug_info.buf.writeByte(1); // DW_AT_external 1920 1921 soffset = cast(uint)debug_info.buf.length(); 1922 debug_info.buf.writeByte(2); // DW_FORM_block1 1923 1924 static if (ELFOBJ) 1925 { 1926 // debug info for TLS variables 1927 assert(s.Sxtrnnum); 1928 if (s.Sfl == FLtlsdata) 1929 { 1930 if (I64) 1931 { 1932 debug_info.buf.writeByte(DW_OP_const8u); 1933 Obj.addrel(debug_info.seg, debug_info.buf.length(), R_X86_64_DTPOFF32, s.Sxtrnnum, 0); 1934 debug_info.buf.write64(0); 1935 } 1936 else 1937 { 1938 debug_info.buf.writeByte(DW_OP_const4u); 1939 Obj.addrel(debug_info.seg, debug_info.buf.length(), R_386_TLS_LDO_32, s.Sxtrnnum, 0); 1940 debug_info.buf.write32(0); 1941 } 1942 debug_info.buf.writeByte(DW_OP_GNU_push_tls_address); 1943 } 1944 else 1945 { 1946 debug_info.buf.writeByte(DW_OP_addr); 1947 dwarf_appreladdr(debug_info.seg, debug_info.buf, s.Sseg, s.Soffset); // address of global 1948 } 1949 } 1950 else 1951 { 1952 debug_info.buf.writeByte(DW_OP_addr); 1953 dwarf_appreladdr(debug_info.seg, debug_info.buf, s.Sseg, s.Soffset); // address of global 1954 } 1955 1956 debug_info.buf.buf[soffset] = cast(ubyte)(debug_info.buf.length() - soffset - 1); 1957 break; 1958 1959 default: 1960 break; 1961 } 1962 } 1963 1964 1965 /****************************************** 1966 * Write out any deferred symbols. 1967 */ 1968 1969 void cv_outlist() 1970 { 1971 } 1972 1973 1974 /****************************************** 1975 * Write out symbol table for current function. 1976 */ 1977 1978 void cv_func(Funcsym *s) 1979 { 1980 } 1981 1982 /* =================== Cached Types in debug_info ================= */ 1983 1984 ubyte dwarf_classify_struct(uint sflags) 1985 { 1986 if (sflags & STRclass) 1987 return DW_TAG_class_type; 1988 1989 if (sflags & STRunion) 1990 return DW_TAG_union_type; 1991 1992 return DW_TAG_structure_type; 1993 } 1994 1995 /* ======================= Type Index ============================== */ 1996 1997 uint dwarf_typidx(type *t) 1998 { uint idx = 0; 1999 uint nextidx; 2000 uint keyidx; 2001 uint pvoididx; 2002 uint code; 2003 type *tnext; 2004 type *tbase; 2005 const(char)* p; 2006 2007 static immutable ubyte[10] abbrevTypeBasic = 2008 [ 2009 DW_TAG_base_type, 2010 0, // no children 2011 DW_AT_name, DW_FORM_string, 2012 DW_AT_byte_size, DW_FORM_data1, 2013 DW_AT_encoding, DW_FORM_data1, 2014 0, 0, 2015 ]; 2016 static immutable ubyte[12] abbrevWchar = 2017 [ 2018 DW_TAG_typedef, 2019 0, // no children 2020 DW_AT_name, DW_FORM_string, 2021 DW_AT_type, DW_FORM_ref4, 2022 DW_AT_decl_file, DW_FORM_data1, 2023 DW_AT_decl_line, DW_FORM_data2, 2024 0, 0, 2025 ]; 2026 static immutable ubyte[6] abbrevTypePointer = 2027 [ 2028 DW_TAG_pointer_type, 2029 0, // no children 2030 DW_AT_type, DW_FORM_ref4, 2031 0, 0, 2032 ]; 2033 static immutable ubyte[4] abbrevTypePointerVoid = 2034 [ 2035 DW_TAG_pointer_type, 2036 0, // no children 2037 0, 0, 2038 ]; 2039 static immutable ubyte[6] abbrevTypeRef = 2040 [ 2041 DW_TAG_reference_type, 2042 0, // no children 2043 DW_AT_type, DW_FORM_ref4, 2044 0, 0, 2045 ]; 2046 static immutable ubyte[6] abbrevTypeConst = 2047 [ 2048 DW_TAG_const_type, 2049 0, // no children 2050 DW_AT_type, DW_FORM_ref4, 2051 0, 0, 2052 ]; 2053 static immutable ubyte[4] abbrevTypeConstVoid = 2054 [ 2055 DW_TAG_const_type, 2056 0, // no children 2057 0, 0, 2058 ]; 2059 static immutable ubyte[6] abbrevTypeVolatile = 2060 [ 2061 DW_TAG_volatile_type, 2062 0, // no children 2063 DW_AT_type, DW_FORM_ref4, 2064 0, 0, 2065 ]; 2066 static immutable ubyte[4] abbrevTypeVolatileVoid = 2067 [ 2068 DW_TAG_volatile_type, 2069 0, // no children 2070 0, 0, 2071 ]; 2072 2073 if (!t) 2074 return 0; 2075 2076 if (t.Tty & mTYconst) 2077 { // We make a copy of the type to strip off the const qualifier and 2078 // recurse, and then add the const abbrev code. To avoid ending in a 2079 // loop if the type references the const version of itself somehow, 2080 // we need to set TFforward here, because setting TFforward during 2081 // member generation of dwarf_typidx(tnext) has no effect on t itself. 2082 ushort old_flags = t.Tflags; 2083 t.Tflags |= TFforward; 2084 2085 tnext = type_copy(t); 2086 tnext.Tcount++; 2087 tnext.Tty &= ~mTYconst; 2088 nextidx = dwarf_typidx(tnext); 2089 2090 t.Tflags = old_flags; 2091 2092 code = nextidx 2093 ? dwarf_abbrev_code(abbrevTypeConst.ptr, (abbrevTypeConst).sizeof) 2094 : dwarf_abbrev_code(abbrevTypeConstVoid.ptr, (abbrevTypeConstVoid).sizeof); 2095 goto Lcv; 2096 } 2097 2098 if (t.Tty & mTYvolatile) 2099 { tnext = type_copy(t); 2100 tnext.Tcount++; 2101 tnext.Tty &= ~mTYvolatile; 2102 nextidx = dwarf_typidx(tnext); 2103 code = nextidx 2104 ? dwarf_abbrev_code(abbrevTypeVolatile.ptr, (abbrevTypeVolatile).sizeof) 2105 : dwarf_abbrev_code(abbrevTypeVolatileVoid.ptr, (abbrevTypeVolatileVoid).sizeof); 2106 Lcv: 2107 idx = cast(uint)debug_info.buf.length(); 2108 debug_info.buf.writeuLEB128(code); // abbreviation code 2109 if (nextidx) 2110 debug_info.buf.write32(nextidx); // DW_AT_type 2111 goto Lret; 2112 } 2113 2114 tym_t ty; 2115 ty = tybasic(t.Tty); 2116 if (!(t.Tnext && (ty == TYdarray || ty == TYdelegate))) 2117 { // use cached basic type if it's not TYdarray or TYdelegate 2118 idx = typidx_tab[ty]; 2119 if (idx) 2120 return idx; 2121 } 2122 2123 ubyte ate; 2124 ate = tyuns(t.Tty) ? DW_ATE_unsigned : DW_ATE_signed; 2125 2126 static immutable ubyte[8] abbrevTypeStruct = 2127 [ 2128 DW_TAG_structure_type, 2129 1, // children 2130 DW_AT_name, DW_FORM_string, 2131 DW_AT_byte_size, DW_FORM_data1, 2132 0, 0, 2133 ]; 2134 2135 static immutable ubyte[10] abbrevTypeMember = 2136 [ 2137 DW_TAG_member, 2138 0, // no children 2139 DW_AT_name, DW_FORM_string, 2140 DW_AT_type, DW_FORM_ref4, 2141 DW_AT_data_member_location, DW_FORM_block1, 2142 0, 0, 2143 ]; 2144 2145 switch (tybasic(t.Tty)) 2146 { 2147 Lnptr: 2148 nextidx = dwarf_typidx(t.Tnext); 2149 code = nextidx 2150 ? dwarf_abbrev_code(abbrevTypePointer.ptr, (abbrevTypePointer).sizeof) 2151 : dwarf_abbrev_code(abbrevTypePointerVoid.ptr, (abbrevTypePointerVoid).sizeof); 2152 idx = cast(uint)debug_info.buf.length(); 2153 debug_info.buf.writeuLEB128(code); // abbreviation code 2154 if (nextidx) 2155 debug_info.buf.write32(nextidx); // DW_AT_type 2156 break; 2157 2158 case TYullong: 2159 case TYucent: 2160 if (!t.Tnext) 2161 { p = (tybasic(t.Tty) == TYullong) ? "uint long long" : "ucent"; 2162 goto Lsigned; 2163 } 2164 2165 /* It's really TYdarray, and Tnext is the 2166 * element type 2167 */ 2168 { 2169 uint lenidx = I64 ? dwarf_typidx(tstypes[TYulong]) : dwarf_typidx(tstypes[TYuint]); 2170 2171 { 2172 type *tdata = type_alloc(TYnptr); 2173 tdata.Tnext = t.Tnext; 2174 t.Tnext.Tcount++; 2175 tdata.Tcount++; 2176 nextidx = dwarf_typidx(tdata); 2177 type_free(tdata); 2178 } 2179 2180 code = dwarf_abbrev_code(abbrevTypeStruct.ptr, (abbrevTypeStruct).sizeof); 2181 idx = cast(uint)debug_info.buf.length(); 2182 debug_info.buf.writeuLEB128(code); // abbreviation code 2183 debug_info.buf.write("_Array_".ptr, 7); // DW_AT_name 2184 if (tybasic(t.Tnext.Tty)) 2185 debug_info.buf.writeString(tystring[tybasic(t.Tnext.Tty)]); 2186 else 2187 debug_info.buf.writeByte(0); 2188 debug_info.buf.writeByte(tysize(t.Tty)); // DW_AT_byte_size 2189 2190 // length 2191 code = dwarf_abbrev_code(abbrevTypeMember.ptr, (abbrevTypeMember).sizeof); 2192 debug_info.buf.writeuLEB128(code); // abbreviation code 2193 debug_info.buf.writeString("length"); // DW_AT_name 2194 debug_info.buf.write32(lenidx); // DW_AT_type 2195 2196 debug_info.buf.writeByte(2); // DW_AT_data_member_location 2197 debug_info.buf.writeByte(DW_OP_plus_uconst); 2198 debug_info.buf.writeByte(0); 2199 2200 // ptr 2201 debug_info.buf.writeuLEB128(code); // abbreviation code 2202 debug_info.buf.writeString("ptr"); // DW_AT_name 2203 debug_info.buf.write32(nextidx); // DW_AT_type 2204 2205 debug_info.buf.writeByte(2); // DW_AT_data_member_location 2206 debug_info.buf.writeByte(DW_OP_plus_uconst); 2207 debug_info.buf.writeByte(I64 ? 8 : 4); 2208 2209 debug_info.buf.writeByte(0); // no more children 2210 } 2211 break; 2212 2213 case TYllong: 2214 case TYcent: 2215 if (!t.Tnext) 2216 { p = (tybasic(t.Tty) == TYllong) ? "long long" : "cent"; 2217 goto Lsigned; 2218 } 2219 /* It's really TYdelegate, and Tnext is the 2220 * function type 2221 */ 2222 { 2223 type *tp = type_fake(TYnptr); 2224 tp.Tcount++; 2225 pvoididx = dwarf_typidx(tp); // void* 2226 2227 tp.Tnext = t.Tnext; // fptr* 2228 tp.Tnext.Tcount++; 2229 nextidx = dwarf_typidx(tp); 2230 type_free(tp); 2231 } 2232 2233 code = dwarf_abbrev_code(abbrevTypeStruct.ptr, (abbrevTypeStruct).sizeof); 2234 idx = cast(uint)debug_info.buf.length(); 2235 debug_info.buf.writeuLEB128(code); // abbreviation code 2236 debug_info.buf.writeString("_Delegate"); // DW_AT_name 2237 debug_info.buf.writeByte(tysize(t.Tty)); // DW_AT_byte_size 2238 2239 // ctxptr 2240 code = dwarf_abbrev_code(abbrevTypeMember.ptr, (abbrevTypeMember).sizeof); 2241 debug_info.buf.writeuLEB128(code); // abbreviation code 2242 debug_info.buf.writeString("ctxptr"); // DW_AT_name 2243 debug_info.buf.write32(pvoididx); // DW_AT_type 2244 2245 debug_info.buf.writeByte(2); // DW_AT_data_member_location 2246 debug_info.buf.writeByte(DW_OP_plus_uconst); 2247 debug_info.buf.writeByte(0); 2248 2249 // funcptr 2250 debug_info.buf.writeuLEB128(code); // abbreviation code 2251 debug_info.buf.writeString("funcptr"); // DW_AT_name 2252 debug_info.buf.write32(nextidx); // DW_AT_type 2253 2254 debug_info.buf.writeByte(2); // DW_AT_data_member_location 2255 debug_info.buf.writeByte(DW_OP_plus_uconst); 2256 debug_info.buf.writeByte(I64 ? 8 : 4); 2257 2258 debug_info.buf.writeByte(0); // no more children 2259 break; 2260 2261 case TYnref: 2262 case TYref: 2263 nextidx = dwarf_typidx(t.Tnext); 2264 assert(nextidx); 2265 code = dwarf_abbrev_code(abbrevTypeRef.ptr, (abbrevTypeRef).sizeof); 2266 idx = cast(uint)cast(uint)debug_info.buf.length(); 2267 debug_info.buf.writeuLEB128(code); // abbreviation code 2268 debug_info.buf.write32(nextidx); // DW_AT_type 2269 break; 2270 2271 case TYnptr: 2272 if (!t.Tkey) 2273 goto Lnptr; 2274 2275 /* It's really TYaarray, and Tnext is the 2276 * element type, Tkey is the key type 2277 */ 2278 { 2279 type *tp = type_fake(TYnptr); 2280 tp.Tcount++; 2281 pvoididx = dwarf_typidx(tp); // void* 2282 } 2283 2284 code = dwarf_abbrev_code(abbrevTypeStruct.ptr, (abbrevTypeStruct).sizeof); 2285 idx = cast(uint)debug_info.buf.length(); 2286 debug_info.buf.writeuLEB128(code); // abbreviation code 2287 debug_info.buf.write("_AArray_".ptr, 8); // DW_AT_name 2288 if (tybasic(t.Tkey.Tty)) 2289 p = tystring[tybasic(t.Tkey.Tty)]; 2290 else 2291 p = "key"; 2292 debug_info.buf.write(p, cast(uint)strlen(p)); 2293 2294 debug_info.buf.writeByte('_'); 2295 if (tybasic(t.Tnext.Tty)) 2296 p = tystring[tybasic(t.Tnext.Tty)]; 2297 else 2298 p = "value"; 2299 debug_info.buf.writeString(p); 2300 2301 debug_info.buf.writeByte(tysize(t.Tty)); // DW_AT_byte_size 2302 2303 // ptr 2304 code = dwarf_abbrev_code(abbrevTypeMember.ptr, (abbrevTypeMember).sizeof); 2305 debug_info.buf.writeuLEB128(code); // abbreviation code 2306 debug_info.buf.writeString("ptr"); // DW_AT_name 2307 debug_info.buf.write32(pvoididx); // DW_AT_type 2308 2309 debug_info.buf.writeByte(2); // DW_AT_data_member_location 2310 debug_info.buf.writeByte(DW_OP_plus_uconst); 2311 debug_info.buf.writeByte(0); 2312 2313 debug_info.buf.writeByte(0); // no more children 2314 break; 2315 2316 case TYvoid: return 0; 2317 case TYbool: p = "_Bool"; ate = DW_ATE_boolean; goto Lsigned; 2318 case TYchar: p = "char"; ate = (config.flags & CFGuchar) ? DW_ATE_unsigned_char : DW_ATE_signed_char; goto Lsigned; 2319 case TYschar: p = "signed char"; ate = DW_ATE_signed_char; goto Lsigned; 2320 case TYuchar: p = "ubyte"; ate = DW_ATE_unsigned_char; goto Lsigned; 2321 case TYshort: p = "short"; goto Lsigned; 2322 case TYushort: p = "ushort"; goto Lsigned; 2323 case TYint: p = "int"; goto Lsigned; 2324 case TYuint: p = "uint"; goto Lsigned; 2325 case TYlong: p = "long"; goto Lsigned; 2326 case TYulong: p = "uint long"; goto Lsigned; 2327 case TYdchar: p = "dchar"; goto Lsigned; 2328 case TYfloat: p = "float"; ate = DW_ATE_float; goto Lsigned; 2329 case TYdouble_alias: 2330 case TYdouble: p = "double"; ate = DW_ATE_float; goto Lsigned; 2331 case TYldouble: p = "long double"; ate = DW_ATE_float; goto Lsigned; 2332 case TYifloat: p = "imaginary float"; ate = DW_ATE_imaginary_float; goto Lsigned; 2333 case TYidouble: p = "imaginary double"; ate = DW_ATE_imaginary_float; goto Lsigned; 2334 case TYildouble: p = "imaginary long double"; ate = DW_ATE_imaginary_float; goto Lsigned; 2335 case TYcfloat: p = "complex float"; ate = DW_ATE_complex_float; goto Lsigned; 2336 case TYcdouble: p = "complex double"; ate = DW_ATE_complex_float; goto Lsigned; 2337 case TYcldouble: p = "complex long double"; ate = DW_ATE_complex_float; goto Lsigned; 2338 Lsigned: 2339 code = dwarf_abbrev_code(abbrevTypeBasic.ptr, (abbrevTypeBasic).sizeof); 2340 idx = cast(uint)debug_info.buf.length(); 2341 debug_info.buf.writeuLEB128(code); // abbreviation code 2342 debug_info.buf.writeString(p); // DW_AT_name 2343 debug_info.buf.writeByte(tysize(t.Tty)); // DW_AT_byte_size 2344 debug_info.buf.writeByte(ate); // DW_AT_encoding 2345 typidx_tab[ty] = idx; 2346 return idx; 2347 2348 case TYnsfunc: 2349 case TYnpfunc: 2350 case TYjfunc: 2351 2352 case TYnfunc: 2353 { 2354 /* The dwarf typidx for the function type is completely determined by 2355 * the return type typidx and the parameter typidx's. Thus, by 2356 * caching these, we can cache the function typidx. 2357 * Cache them in functypebuf[] 2358 */ 2359 Outbuffer tmpbuf; 2360 nextidx = dwarf_typidx(t.Tnext); // function return type 2361 tmpbuf.write32(nextidx); 2362 uint params = 0; 2363 for (param_t *p2 = t.Tparamtypes; p2; p2 = p2.Pnext) 2364 { params = 1; 2365 uint paramidx = dwarf_typidx(p2.Ptype); 2366 //printf("1: paramidx = %d\n", paramidx); 2367 2368 debug 2369 if (!paramidx) type_print(p2.Ptype); 2370 2371 assert(paramidx); 2372 tmpbuf.write32(paramidx); 2373 } 2374 2375 if (!functypebuf) 2376 { 2377 functypebuf = cast(Outbuffer*) calloc(1, Outbuffer.sizeof); 2378 assert(functypebuf); 2379 } 2380 uint functypebufidx = cast(uint)functypebuf.length(); 2381 functypebuf.write(tmpbuf.buf, cast(uint)tmpbuf.length()); 2382 /* If it's in the cache already, return the existing typidx 2383 */ 2384 if (!functype_table) 2385 functype_table = AApair.create(&functypebuf.buf); 2386 uint *pidx = cast(uint *)functype_table.get(functypebufidx, cast(uint)functypebuf.length()); 2387 if (*pidx) 2388 { // Reuse existing typidx 2389 functypebuf.setsize(functypebufidx); 2390 return *pidx; 2391 } 2392 2393 /* Not in the cache, create a new typidx 2394 */ 2395 Outbuffer abuf; // for abbrev 2396 abuf.writeByte(DW_TAG_subroutine_type); 2397 if (params) 2398 abuf.writeByte(1); // children 2399 else 2400 abuf.writeByte(0); // no children 2401 abuf.writeByte(DW_AT_prototyped); abuf.writeByte(DW_FORM_flag); 2402 if (nextidx != 0) // Don't write DW_AT_type for void 2403 { abuf.writeByte(DW_AT_type); abuf.writeByte(DW_FORM_ref4); 2404 } 2405 2406 abuf.writeByte(0); abuf.writeByte(0); 2407 code = dwarf_abbrev_code(abuf.buf, abuf.length()); 2408 2409 uint paramcode; 2410 if (params) 2411 { abuf.reset(); 2412 abuf.writeByte(DW_TAG_formal_parameter); 2413 abuf.writeByte(0); 2414 abuf.writeByte(DW_AT_type); abuf.writeByte(DW_FORM_ref4); 2415 abuf.writeByte(0); abuf.writeByte(0); 2416 paramcode = dwarf_abbrev_code(abuf.buf, abuf.length()); 2417 } 2418 2419 idx = cast(uint)debug_info.buf.length(); 2420 debug_info.buf.writeuLEB128(code); 2421 debug_info.buf.writeByte(1); // DW_AT_prototyped 2422 if (nextidx) // if return type is not void 2423 debug_info.buf.write32(nextidx); // DW_AT_type 2424 2425 if (params) 2426 { uint *pparamidx = cast(uint *)(functypebuf.buf + functypebufidx); 2427 //printf("2: functypebufidx = %x, pparamidx = %p, size = %x\n", functypebufidx, pparamidx, functypebuf.length()); 2428 for (param_t *p2 = t.Tparamtypes; p2; p2 = p2.Pnext) 2429 { debug_info.buf.writeuLEB128(paramcode); 2430 //uint x = dwarf_typidx(p2.Ptype); 2431 uint paramidx = *++pparamidx; 2432 //printf("paramidx = %d\n", paramidx); 2433 assert(paramidx); 2434 debug_info.buf.write32(paramidx); // DW_AT_type 2435 } 2436 debug_info.buf.writeByte(0); // end parameter list 2437 } 2438 2439 *pidx = idx; // remember it in the functype_table[] cache 2440 break; 2441 } 2442 2443 case TYarray: 2444 { 2445 static immutable ubyte[6] abbrevTypeArray = 2446 [ 2447 DW_TAG_array_type, 2448 1, // child (the subrange type) 2449 DW_AT_type, DW_FORM_ref4, 2450 0, 0, 2451 ]; 2452 static immutable ubyte[4] abbrevTypeArrayVoid = 2453 [ 2454 DW_TAG_array_type, 2455 1, // child (the subrange type) 2456 0, 0, 2457 ]; 2458 static immutable ubyte[8] abbrevTypeSubrange = 2459 [ 2460 DW_TAG_subrange_type, 2461 0, // no children 2462 DW_AT_type, DW_FORM_ref4, 2463 DW_AT_upper_bound, DW_FORM_data4, 2464 0, 0, 2465 ]; 2466 static immutable ubyte[6] abbrevTypeSubrange2 = 2467 [ 2468 DW_TAG_subrange_type, 2469 0, // no children 2470 DW_AT_type, DW_FORM_ref4, 2471 0, 0, 2472 ]; 2473 uint code2 = (t.Tflags & TFsizeunknown) 2474 ? dwarf_abbrev_code(abbrevTypeSubrange2.ptr, (abbrevTypeSubrange2).sizeof) 2475 : dwarf_abbrev_code(abbrevTypeSubrange.ptr, (abbrevTypeSubrange).sizeof); 2476 uint idxbase = dwarf_typidx(tssize); 2477 nextidx = dwarf_typidx(t.Tnext); 2478 uint code1 = nextidx ? dwarf_abbrev_code(abbrevTypeArray.ptr, (abbrevTypeArray).sizeof) 2479 : dwarf_abbrev_code(abbrevTypeArrayVoid.ptr, (abbrevTypeArrayVoid).sizeof); 2480 idx = cast(uint)debug_info.buf.length(); 2481 2482 debug_info.buf.writeuLEB128(code1); // DW_TAG_array_type 2483 if (nextidx) 2484 debug_info.buf.write32(nextidx); // DW_AT_type 2485 2486 debug_info.buf.writeuLEB128(code2); // DW_TAG_subrange_type 2487 debug_info.buf.write32(idxbase); // DW_AT_type 2488 if (!(t.Tflags & TFsizeunknown)) 2489 debug_info.buf.write32(t.Tdim ? cast(uint)t.Tdim - 1 : 0); // DW_AT_upper_bound 2490 2491 debug_info.buf.writeByte(0); // no more children 2492 break; 2493 } 2494 2495 // SIMD vector types 2496 case TYfloat16: 2497 case TYfloat8: 2498 case TYfloat4: tbase = tstypes[TYfloat]; goto Lvector; 2499 case TYdouble8: 2500 case TYdouble4: 2501 case TYdouble2: tbase = tstypes[TYdouble]; goto Lvector; 2502 case TYschar64: 2503 case TYschar32: 2504 case TYschar16: tbase = tstypes[TYschar]; goto Lvector; 2505 case TYuchar64: 2506 case TYuchar32: 2507 case TYuchar16: tbase = tstypes[TYuchar]; goto Lvector; 2508 case TYshort32: 2509 case TYshort16: 2510 case TYshort8: tbase = tstypes[TYshort]; goto Lvector; 2511 case TYushort32: 2512 case TYushort16: 2513 case TYushort8: tbase = tstypes[TYushort]; goto Lvector; 2514 case TYlong16: 2515 case TYlong8: 2516 case TYlong4: tbase = tstypes[TYlong]; goto Lvector; 2517 case TYulong16: 2518 case TYulong8: 2519 case TYulong4: tbase = tstypes[TYulong]; goto Lvector; 2520 case TYllong8: 2521 case TYllong4: 2522 case TYllong2: tbase = tstypes[TYllong]; goto Lvector; 2523 case TYullong8: 2524 case TYullong4: 2525 case TYullong2: tbase = tstypes[TYullong]; goto Lvector; 2526 Lvector: 2527 { 2528 static immutable ubyte[9] abbrevTypeArray2 = 2529 [ 2530 DW_TAG_array_type, 2531 1, // child (the subrange type) 2532 (DW_AT_GNU_vector & 0x7F) | 0x80, DW_AT_GNU_vector >> 7, DW_FORM_flag, 2533 DW_AT_type, DW_FORM_ref4, 2534 0, 0, 2535 ]; 2536 static immutable ubyte[6] abbrevSubRange = 2537 [ 2538 DW_TAG_subrange_type, 2539 0, // no children 2540 DW_AT_upper_bound, DW_FORM_data1, // length of vector 2541 0, 0, 2542 ]; 2543 2544 uint code2 = dwarf_abbrev_code(abbrevTypeArray2.ptr, (abbrevTypeArray2).sizeof); 2545 uint idxbase = dwarf_typidx(tbase); 2546 2547 idx = cast(uint)debug_info.buf.length(); 2548 2549 debug_info.buf.writeuLEB128(code2); // DW_TAG_array_type 2550 debug_info.buf.writeByte(1); // DW_AT_GNU_vector 2551 debug_info.buf.write32(idxbase); // DW_AT_type 2552 2553 // vector length stored as subrange type 2554 code2 = dwarf_abbrev_code(abbrevSubRange.ptr, (abbrevSubRange).sizeof); 2555 debug_info.buf.writeuLEB128(code2); // DW_TAG_subrange_type 2556 ubyte dim = cast(ubyte)(tysize(t.Tty) / tysize(tbase.Tty)); 2557 debug_info.buf.writeByte(dim - 1); // DW_AT_upper_bound 2558 2559 debug_info.buf.writeByte(0); // no more children 2560 break; 2561 } 2562 2563 case TYwchar_t: 2564 { 2565 uint code3 = dwarf_abbrev_code(abbrevWchar.ptr, (abbrevWchar).sizeof); 2566 uint typebase = dwarf_typidx(tstypes[TYint]); 2567 idx = cast(uint)debug_info.buf.length(); 2568 debug_info.buf.writeuLEB128(code3); // abbreviation code 2569 debug_info.buf.writeString("wchar_t"); // DW_AT_name 2570 debug_info.buf.write32(typebase); // DW_AT_type 2571 debug_info.buf.writeByte(1); // DW_AT_decl_file 2572 debug_info.buf.write16(1); // DW_AT_decl_line 2573 typidx_tab[ty] = idx; 2574 break; 2575 } 2576 2577 2578 case TYstruct: 2579 { 2580 Classsym *s = t.Ttag; 2581 struct_t *st = s.Sstruct; 2582 2583 if (s.Stypidx) 2584 return s.Stypidx; 2585 2586 __gshared ubyte[8] abbrevTypeStruct0 = 2587 [ 2588 DW_TAG_structure_type, 2589 0, // no children 2590 DW_AT_name, DW_FORM_string, 2591 DW_AT_byte_size, DW_FORM_data1, 2592 0, 0, 2593 ]; 2594 __gshared ubyte[8] abbrevTypeStruct1 = 2595 [ 2596 DW_TAG_structure_type, 2597 0, // no children 2598 DW_AT_name, DW_FORM_string, 2599 DW_AT_declaration, DW_FORM_flag, 2600 0, 0, 2601 ]; 2602 2603 if (t.Tflags & (TFsizeunknown | TFforward)) 2604 { 2605 abbrevTypeStruct1[0] = dwarf_classify_struct(st.Sflags); 2606 code = dwarf_abbrev_code(abbrevTypeStruct1.ptr, (abbrevTypeStruct1).sizeof); 2607 idx = cast(uint)debug_info.buf.length(); 2608 debug_info.buf.writeuLEB128(code); 2609 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 2610 debug_info.buf.writeByte(1); // DW_AT_declaration 2611 break; // don't set Stypidx 2612 } 2613 2614 Outbuffer fieldidx; 2615 2616 // Count number of fields 2617 uint nfields = 0; 2618 t.Tflags |= TFforward; 2619 foreach (sl; ListRange(st.Sfldlst)) 2620 { 2621 Symbol *sf = list_symbol(sl); 2622 switch (sf.Sclass) 2623 { 2624 case SCmember: 2625 fieldidx.write32(dwarf_typidx(sf.Stype)); 2626 nfields++; 2627 break; 2628 2629 default: 2630 break; 2631 } 2632 } 2633 t.Tflags &= ~TFforward; 2634 if (nfields == 0) 2635 { 2636 abbrevTypeStruct0[0] = dwarf_classify_struct(st.Sflags); 2637 abbrevTypeStruct0[1] = 0; // no children 2638 abbrevTypeStruct0[5] = DW_FORM_data1; // DW_AT_byte_size 2639 code = dwarf_abbrev_code(abbrevTypeStruct0.ptr, (abbrevTypeStruct0).sizeof); 2640 idx = cast(uint)debug_info.buf.length(); 2641 debug_info.buf.writeuLEB128(code); 2642 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 2643 debug_info.buf.writeByte(0); // DW_AT_byte_size 2644 } 2645 else 2646 { 2647 Outbuffer abuf; // for abbrev 2648 abuf.writeByte(dwarf_classify_struct(st.Sflags)); 2649 abuf.writeByte(1); // children 2650 abuf.writeByte(DW_AT_name); abuf.writeByte(DW_FORM_string); 2651 abuf.writeByte(DW_AT_byte_size); 2652 2653 size_t sz = cast(uint)st.Sstructsize; 2654 if (sz <= 0xFF) 2655 abuf.writeByte(DW_FORM_data1); // DW_AT_byte_size 2656 else if (sz <= 0xFFFF) 2657 abuf.writeByte(DW_FORM_data2); // DW_AT_byte_size 2658 else 2659 abuf.writeByte(DW_FORM_data4); // DW_AT_byte_size 2660 abuf.writeByte(0); abuf.writeByte(0); 2661 2662 code = dwarf_abbrev_code(abuf.buf, abuf.length()); 2663 2664 uint membercode; 2665 abuf.reset(); 2666 abuf.writeByte(DW_TAG_member); 2667 abuf.writeByte(0); // no children 2668 abuf.writeByte(DW_AT_name); 2669 abuf.writeByte(DW_FORM_string); 2670 abuf.writeByte(DW_AT_type); 2671 abuf.writeByte(DW_FORM_ref4); 2672 abuf.writeByte(DW_AT_data_member_location); 2673 abuf.writeByte(DW_FORM_block1); 2674 abuf.writeByte(0); 2675 abuf.writeByte(0); 2676 membercode = dwarf_abbrev_code(abuf.buf, abuf.length()); 2677 2678 idx = cast(uint)debug_info.buf.length(); 2679 debug_info.buf.writeuLEB128(code); 2680 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 2681 if (sz <= 0xFF) 2682 debug_info.buf.writeByte(cast(uint)sz); // DW_AT_byte_size 2683 else if (sz <= 0xFFFF) 2684 debug_info.buf.write16(cast(uint)sz); // DW_AT_byte_size 2685 else 2686 debug_info.buf.write32(cast(uint)sz); // DW_AT_byte_size 2687 2688 s.Stypidx = idx; 2689 uint n = 0; 2690 foreach (sl; ListRange(st.Sfldlst)) 2691 { 2692 Symbol *sf = list_symbol(sl); 2693 size_t soffset; 2694 2695 switch (sf.Sclass) 2696 { 2697 case SCmember: 2698 debug_info.buf.writeuLEB128(membercode); 2699 debug_info.buf.writeString(sf.Sident.ptr); 2700 //debug_info.buf.write32(dwarf_typidx(sf.Stype)); 2701 uint fi = (cast(uint *)fieldidx.buf)[n]; 2702 debug_info.buf.write32(fi); 2703 n++; 2704 soffset = debug_info.buf.length(); 2705 debug_info.buf.writeByte(2); 2706 debug_info.buf.writeByte(DW_OP_plus_uconst); 2707 debug_info.buf.writeuLEB128(cast(uint)sf.Smemoff); 2708 debug_info.buf.buf[soffset] = cast(ubyte)(debug_info.buf.length() - soffset - 1); 2709 break; 2710 2711 default: 2712 break; 2713 } 2714 } 2715 2716 debug_info.buf.writeByte(0); // no more children 2717 } 2718 s.Stypidx = idx; 2719 reset_symbuf.write(&s, (s).sizeof); 2720 return idx; // no need to cache it 2721 } 2722 2723 case TYenum: 2724 { static immutable ubyte[8] abbrevTypeEnum = 2725 [ 2726 DW_TAG_enumeration_type, 2727 1, // child (the subrange type) 2728 DW_AT_name, DW_FORM_string, 2729 DW_AT_byte_size, DW_FORM_data1, 2730 0, 0, 2731 ]; 2732 static immutable ubyte[8] abbrevTypeEnumMember = 2733 [ 2734 DW_TAG_enumerator, 2735 0, // no children 2736 DW_AT_name, DW_FORM_string, 2737 DW_AT_const_value, DW_FORM_data1, 2738 0, 0, 2739 ]; 2740 2741 Symbol *s = t.Ttag; 2742 enum_t *se = s.Senum; 2743 type *tbase2 = s.Stype.Tnext; 2744 uint sz = cast(uint)type_size(tbase2); 2745 symlist_t sl; 2746 2747 if (s.Stypidx) 2748 return s.Stypidx; 2749 2750 if (se.SEflags & SENforward) 2751 { 2752 static immutable ubyte[8] abbrevTypeEnumForward = 2753 [ 2754 DW_TAG_enumeration_type, 2755 0, // no children 2756 DW_AT_name, DW_FORM_string, 2757 DW_AT_declaration, DW_FORM_flag, 2758 0, 0, 2759 ]; 2760 code = dwarf_abbrev_code(abbrevTypeEnumForward.ptr, abbrevTypeEnumForward.sizeof); 2761 idx = cast(uint)debug_info.buf.length(); 2762 debug_info.buf.writeuLEB128(code); 2763 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 2764 debug_info.buf.writeByte(1); // DW_AT_declaration 2765 break; // don't set Stypidx 2766 } 2767 2768 Outbuffer abuf; // for abbrev 2769 abuf.write(abbrevTypeEnum.ptr, abbrevTypeEnum.sizeof); 2770 code = dwarf_abbrev_code(abuf.buf, abuf.length()); 2771 2772 uint membercode; 2773 abuf.reset(); 2774 abuf.writeByte(DW_TAG_enumerator); 2775 abuf.writeByte(0); 2776 abuf.writeByte(DW_AT_name); 2777 abuf.writeByte(DW_FORM_string); 2778 abuf.writeByte(DW_AT_const_value); 2779 if (tyuns(tbase2.Tty)) 2780 abuf.writeByte(DW_FORM_udata); 2781 else 2782 abuf.writeByte(DW_FORM_sdata); 2783 abuf.writeByte(0); 2784 abuf.writeByte(0); 2785 membercode = dwarf_abbrev_code(abuf.buf, abuf.length()); 2786 2787 idx = cast(uint)debug_info.buf.length(); 2788 debug_info.buf.writeuLEB128(code); 2789 debug_info.buf.writeString(s.Sident.ptr); // DW_AT_name 2790 debug_info.buf.writeByte(sz); // DW_AT_byte_size 2791 2792 foreach (sl2; ListRange(s.Senum.SEenumlist)) 2793 { 2794 Symbol *sf = cast(Symbol *)list_ptr(sl2); 2795 const value = cast(uint)el_tolongt(sf.Svalue); 2796 2797 debug_info.buf.writeuLEB128(membercode); 2798 debug_info.buf.writeString(sf.Sident.ptr); 2799 if (tyuns(tbase2.Tty)) 2800 debug_info.buf.writeuLEB128(value); 2801 else 2802 debug_info.buf.writesLEB128(value); 2803 } 2804 2805 debug_info.buf.writeByte(0); // no more children 2806 2807 s.Stypidx = idx; 2808 reset_symbuf.write(&s, s.sizeof); 2809 return idx; // no need to cache it 2810 } 2811 2812 default: 2813 return 0; 2814 } 2815 Lret: 2816 /* If debug_info.buf.buf[idx .. length()] is already in debug_info.buf, 2817 * discard this one and use the previous one. 2818 */ 2819 if (!type_table) 2820 /* uint[Adata] type_table; 2821 * where the table values are the type indices 2822 */ 2823 type_table = AApair.create(&debug_info.buf.buf); 2824 2825 uint *pidx = type_table.get(idx, cast(uint)debug_info.buf.length()); 2826 if (!*pidx) // if no idx assigned yet 2827 { 2828 *pidx = idx; // assign newly computed idx 2829 } 2830 else 2831 { // Reuse existing code 2832 debug_info.buf.setsize(idx); // discard current 2833 idx = *pidx; 2834 } 2835 return idx; 2836 } 2837 2838 /* ======================= Abbreviation Codes ====================== */ 2839 2840 2841 uint dwarf_abbrev_code(const(ubyte)* data, size_t nbytes) 2842 { 2843 if (!abbrev_table) 2844 /* uint[Adata] abbrev_table; 2845 * where the table values are the abbreviation codes. 2846 */ 2847 abbrev_table = AApair.create(&debug_abbrev.buf.buf); 2848 2849 /* Write new entry into debug_abbrev.buf 2850 */ 2851 2852 uint idx = cast(uint)debug_abbrev.buf.length(); 2853 abbrevcode++; 2854 debug_abbrev.buf.writeuLEB128(abbrevcode); 2855 size_t start = debug_abbrev.buf.length(); 2856 debug_abbrev.buf.write(data, cast(uint)nbytes); 2857 size_t end = debug_abbrev.buf.length(); 2858 2859 /* If debug_abbrev.buf.buf[idx .. length()] is already in debug_abbrev.buf, 2860 * discard this one and use the previous one. 2861 */ 2862 2863 uint *pcode = abbrev_table.get(cast(uint)start, cast(uint)end); 2864 if (!*pcode) // if no code assigned yet 2865 { 2866 *pcode = abbrevcode; // assign newly computed code 2867 } 2868 else 2869 { // Reuse existing code 2870 debug_abbrev.buf.setsize(idx); // discard current 2871 abbrevcode--; 2872 } 2873 return *pcode; 2874 } 2875 2876 /***************************************************** 2877 * Write Dwarf-style exception tables. 2878 * Params: 2879 * sfunc = function to generate tables for 2880 * startoffset = size of function prolog 2881 * retoffset = offset from start of function to epilog 2882 */ 2883 void dwarf_except_gentables(Funcsym *sfunc, uint startoffset, uint retoffset) 2884 { 2885 if (!doUnwindEhFrame()) 2886 return; 2887 2888 int seg = dwarf_except_table_alloc(sfunc); 2889 Outbuffer *buf = SegData[seg].SDbuf; 2890 buf.reserve(100); 2891 2892 static if (ELFOBJ) 2893 sfunc.Sfunc.LSDAoffset = cast(uint)buf.length(); 2894 2895 static if (MACHOBJ) 2896 { 2897 char[16 + (except_table_num).sizeof * 3 + 1] name = void; 2898 sprintf(name.ptr, "GCC_except_table%d", ++except_table_num); 2899 type *t = tspvoid; 2900 t.Tcount++; 2901 type_setmangle(&t, mTYman_sys); // no leading '_' for mangled name 2902 Symbol *s = symbol_name(name.ptr, SCstatic, t); 2903 Obj.pubdef(seg, s, cast(uint)buf.length()); 2904 symbol_keep(s); 2905 2906 sfunc.Sfunc.LSDAsym = s; 2907 } 2908 genDwarfEh(sfunc, seg, buf, (usednteh & EHcleanup) != 0, startoffset, retoffset); 2909 } 2910 2911 } 2912 else 2913 { 2914 extern (C++): 2915 2916 void dwarf_CFA_set_loc(uint location) { } 2917 void dwarf_CFA_set_reg_offset(int reg, int offset) { } 2918 void dwarf_CFA_offset(int reg, int offset) { } 2919 void dwarf_except_gentables(Funcsym *sfunc, uint startoffset, uint retoffset) { } 2920 } 2921 2922 }