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