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