1 //===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DWARFLocationExpression.h"
10 
11 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/Section.h"
14 #include "lldb/Core/StreamBuffer.h"
15 #include "lldb/Expression/DWARFExpression.h"
16 #include "lldb/Utility/ArchSpec.h"
17 #include "lldb/Utility/DataBufferHeap.h"
18 
19 #include "llvm/BinaryFormat/Dwarf.h"
20 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
21 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
22 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
23 #include "llvm/Support/Endian.h"
24 
25 #include "PdbUtil.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 using namespace lldb_private::npdb;
30 using namespace llvm::codeview;
31 using namespace llvm::pdb;
32 
33 static const uint32_t g_code_view_to_lldb_registers_x86[] = {
34     LLDB_INVALID_REGNUM, // NONE
35     lldb_al_i386,        // AL
36     lldb_cl_i386,        // CL
37     lldb_dl_i386,        // DL
38     lldb_bl_i386,        // BL
39     lldb_ah_i386,        // AH
40     lldb_ch_i386,        // CH
41     lldb_dh_i386,        // DH
42     lldb_bh_i386,        // BH
43     lldb_ax_i386,        // AX
44     lldb_cx_i386,        // CX
45     lldb_dx_i386,        // DX
46     lldb_bx_i386,        // BX
47     lldb_sp_i386,        // SP
48     lldb_bp_i386,        // BP
49     lldb_si_i386,        // SI
50     lldb_di_i386,        // DI
51     lldb_eax_i386,       // EAX
52     lldb_ecx_i386,       // ECX
53     lldb_edx_i386,       // EDX
54     lldb_ebx_i386,       // EBX
55     lldb_esp_i386,       // ESP
56     lldb_ebp_i386,       // EBP
57     lldb_esi_i386,       // ESI
58     lldb_edi_i386,       // EDI
59     lldb_es_i386,        // ES
60     lldb_cs_i386,        // CS
61     lldb_ss_i386,        // SS
62     lldb_ds_i386,        // DS
63     lldb_fs_i386,        // FS
64     lldb_gs_i386,        // GS
65     LLDB_INVALID_REGNUM, // IP
66     LLDB_INVALID_REGNUM, // FLAGS
67     lldb_eip_i386,       // EIP
68     lldb_eflags_i386,    // EFLAGS
69     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
70     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
71     LLDB_INVALID_REGNUM, // TEMP
72     LLDB_INVALID_REGNUM, // TEMPH
73     LLDB_INVALID_REGNUM, // QUOTE
74     LLDB_INVALID_REGNUM, // PCDR3
75     LLDB_INVALID_REGNUM, // PCDR4
76     LLDB_INVALID_REGNUM, // PCDR5
77     LLDB_INVALID_REGNUM, // PCDR6
78     LLDB_INVALID_REGNUM, // PCDR7
79     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
80     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
81     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
82     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
83     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
84     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
85     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
86     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
87     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
88     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
89     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
90     LLDB_INVALID_REGNUM, // CR0
91     LLDB_INVALID_REGNUM, // CR1
92     LLDB_INVALID_REGNUM, // CR2
93     LLDB_INVALID_REGNUM, // CR3
94     LLDB_INVALID_REGNUM, // CR4
95     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
96     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
97     lldb_dr0_i386, // DR0
98     lldb_dr1_i386, // DR1
99     lldb_dr2_i386, // DR2
100     lldb_dr3_i386, // DR3
101     lldb_dr4_i386, // DR4
102     lldb_dr5_i386, // DR5
103     lldb_dr6_i386, // DR6
104     lldb_dr7_i386, // DR7
105     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
106     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
107     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
108     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
109     LLDB_INVALID_REGNUM, // GDTR
110     LLDB_INVALID_REGNUM, // GDTL
111     LLDB_INVALID_REGNUM, // IDTR
112     LLDB_INVALID_REGNUM, // IDTL
113     LLDB_INVALID_REGNUM, // LDTR
114     LLDB_INVALID_REGNUM, // TR
115     LLDB_INVALID_REGNUM, // PSEUDO1
116     LLDB_INVALID_REGNUM, // PSEUDO2
117     LLDB_INVALID_REGNUM, // PSEUDO3
118     LLDB_INVALID_REGNUM, // PSEUDO4
119     LLDB_INVALID_REGNUM, // PSEUDO5
120     LLDB_INVALID_REGNUM, // PSEUDO6
121     LLDB_INVALID_REGNUM, // PSEUDO7
122     LLDB_INVALID_REGNUM, // PSEUDO8
123     LLDB_INVALID_REGNUM, // PSEUDO9
124     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
125     lldb_st0_i386,       // ST0
126     lldb_st1_i386,       // ST1
127     lldb_st2_i386,       // ST2
128     lldb_st3_i386,       // ST3
129     lldb_st4_i386,       // ST4
130     lldb_st5_i386,       // ST5
131     lldb_st6_i386,       // ST6
132     lldb_st7_i386,       // ST7
133     LLDB_INVALID_REGNUM, // CTRL
134     LLDB_INVALID_REGNUM, // STAT
135     LLDB_INVALID_REGNUM, // TAG
136     LLDB_INVALID_REGNUM, // FPIP
137     LLDB_INVALID_REGNUM, // FPCS
138     LLDB_INVALID_REGNUM, // FPDO
139     LLDB_INVALID_REGNUM, // FPDS
140     LLDB_INVALID_REGNUM, // ISEM
141     LLDB_INVALID_REGNUM, // FPEIP
142     LLDB_INVALID_REGNUM, // FPEDO
143     lldb_mm0_i386,       // MM0
144     lldb_mm1_i386,       // MM1
145     lldb_mm2_i386,       // MM2
146     lldb_mm3_i386,       // MM3
147     lldb_mm4_i386,       // MM4
148     lldb_mm5_i386,       // MM5
149     lldb_mm6_i386,       // MM6
150     lldb_mm7_i386,       // MM7
151     lldb_xmm0_i386,      // XMM0
152     lldb_xmm1_i386,      // XMM1
153     lldb_xmm2_i386,      // XMM2
154     lldb_xmm3_i386,      // XMM3
155     lldb_xmm4_i386,      // XMM4
156     lldb_xmm5_i386,      // XMM5
157     lldb_xmm6_i386,      // XMM6
158     lldb_xmm7_i386       // XMM7
159 };
160 
161 static const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
162     LLDB_INVALID_REGNUM, // NONE
163     lldb_al_x86_64,      // AL
164     lldb_cl_x86_64,      // CL
165     lldb_dl_x86_64,      // DL
166     lldb_bl_x86_64,      // BL
167     lldb_ah_x86_64,      // AH
168     lldb_ch_x86_64,      // CH
169     lldb_dh_x86_64,      // DH
170     lldb_bh_x86_64,      // BH
171     lldb_ax_x86_64,      // AX
172     lldb_cx_x86_64,      // CX
173     lldb_dx_x86_64,      // DX
174     lldb_bx_x86_64,      // BX
175     lldb_sp_x86_64,      // SP
176     lldb_bp_x86_64,      // BP
177     lldb_si_x86_64,      // SI
178     lldb_di_x86_64,      // DI
179     lldb_eax_x86_64,     // EAX
180     lldb_ecx_x86_64,     // ECX
181     lldb_edx_x86_64,     // EDX
182     lldb_ebx_x86_64,     // EBX
183     lldb_esp_x86_64,     // ESP
184     lldb_ebp_x86_64,     // EBP
185     lldb_esi_x86_64,     // ESI
186     lldb_edi_x86_64,     // EDI
187     lldb_es_x86_64,      // ES
188     lldb_cs_x86_64,      // CS
189     lldb_ss_x86_64,      // SS
190     lldb_ds_x86_64,      // DS
191     lldb_fs_x86_64,      // FS
192     lldb_gs_x86_64,      // GS
193     LLDB_INVALID_REGNUM, // IP
194     LLDB_INVALID_REGNUM, // FLAGS
195     LLDB_INVALID_REGNUM, // EIP
196     LLDB_INVALID_REGNUM, // EFLAGS
197     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
198     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199     LLDB_INVALID_REGNUM, // TEMP
200     LLDB_INVALID_REGNUM, // TEMPH
201     LLDB_INVALID_REGNUM, // QUOTE
202     LLDB_INVALID_REGNUM, // PCDR3
203     LLDB_INVALID_REGNUM, // PCDR4
204     LLDB_INVALID_REGNUM, // PCDR5
205     LLDB_INVALID_REGNUM, // PCDR6
206     LLDB_INVALID_REGNUM, // PCDR7
207     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
208     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
209     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
210     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
211     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
212     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
213     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
214     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
215     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
216     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
217     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
218     LLDB_INVALID_REGNUM, // CR0
219     LLDB_INVALID_REGNUM, // CR1
220     LLDB_INVALID_REGNUM, // CR2
221     LLDB_INVALID_REGNUM, // CR3
222     LLDB_INVALID_REGNUM, // CR4
223     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
224     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
225     lldb_dr0_x86_64, // DR0
226     lldb_dr1_x86_64, // DR1
227     lldb_dr2_x86_64, // DR2
228     lldb_dr3_x86_64, // DR3
229     lldb_dr4_x86_64, // DR4
230     lldb_dr5_x86_64, // DR5
231     lldb_dr6_x86_64, // DR6
232     lldb_dr7_x86_64, // DR7
233     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
234     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
235     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
236     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
237     LLDB_INVALID_REGNUM, // GDTR
238     LLDB_INVALID_REGNUM, // GDTL
239     LLDB_INVALID_REGNUM, // IDTR
240     LLDB_INVALID_REGNUM, // IDTL
241     LLDB_INVALID_REGNUM, // LDTR
242     LLDB_INVALID_REGNUM, // TR
243     LLDB_INVALID_REGNUM, // PSEUDO1
244     LLDB_INVALID_REGNUM, // PSEUDO2
245     LLDB_INVALID_REGNUM, // PSEUDO3
246     LLDB_INVALID_REGNUM, // PSEUDO4
247     LLDB_INVALID_REGNUM, // PSEUDO5
248     LLDB_INVALID_REGNUM, // PSEUDO6
249     LLDB_INVALID_REGNUM, // PSEUDO7
250     LLDB_INVALID_REGNUM, // PSEUDO8
251     LLDB_INVALID_REGNUM, // PSEUDO9
252     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
253     lldb_st0_x86_64,     // ST0
254     lldb_st1_x86_64,     // ST1
255     lldb_st2_x86_64,     // ST2
256     lldb_st3_x86_64,     // ST3
257     lldb_st4_x86_64,     // ST4
258     lldb_st5_x86_64,     // ST5
259     lldb_st6_x86_64,     // ST6
260     lldb_st7_x86_64,     // ST7
261     LLDB_INVALID_REGNUM, // CTRL
262     LLDB_INVALID_REGNUM, // STAT
263     LLDB_INVALID_REGNUM, // TAG
264     LLDB_INVALID_REGNUM, // FPIP
265     LLDB_INVALID_REGNUM, // FPCS
266     LLDB_INVALID_REGNUM, // FPDO
267     LLDB_INVALID_REGNUM, // FPDS
268     LLDB_INVALID_REGNUM, // ISEM
269     LLDB_INVALID_REGNUM, // FPEIP
270     LLDB_INVALID_REGNUM, // FPEDO
271     lldb_mm0_x86_64,     // MM0
272     lldb_mm1_x86_64,     // MM1
273     lldb_mm2_x86_64,     // MM2
274     lldb_mm3_x86_64,     // MM3
275     lldb_mm4_x86_64,     // MM4
276     lldb_mm5_x86_64,     // MM5
277     lldb_mm6_x86_64,     // MM6
278     lldb_mm7_x86_64,     // MM7
279     lldb_xmm0_x86_64,    // XMM0
280     lldb_xmm1_x86_64,    // XMM1
281     lldb_xmm2_x86_64,    // XMM2
282     lldb_xmm3_x86_64,    // XMM3
283     lldb_xmm4_x86_64,    // XMM4
284     lldb_xmm5_x86_64,    // XMM5
285     lldb_xmm6_x86_64,    // XMM6
286     lldb_xmm7_x86_64,    // XMM7
287     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
288     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
289     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
290     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
291     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
292     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
293     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
294     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
295     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
296     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
297     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
298     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
299     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
300     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
301     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
303     LLDB_INVALID_REGNUM,
304     lldb_mxcsr_x86_64,   // MXCSR
305     LLDB_INVALID_REGNUM, // EDXEAX
306     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308     LLDB_INVALID_REGNUM,
309     LLDB_INVALID_REGNUM, // EMM0L
310     LLDB_INVALID_REGNUM, // EMM1L
311     LLDB_INVALID_REGNUM, // EMM2L
312     LLDB_INVALID_REGNUM, // EMM3L
313     LLDB_INVALID_REGNUM, // EMM4L
314     LLDB_INVALID_REGNUM, // EMM5L
315     LLDB_INVALID_REGNUM, // EMM6L
316     LLDB_INVALID_REGNUM, // EMM7L
317     LLDB_INVALID_REGNUM, // EMM0H
318     LLDB_INVALID_REGNUM, // EMM1H
319     LLDB_INVALID_REGNUM, // EMM2H
320     LLDB_INVALID_REGNUM, // EMM3H
321     LLDB_INVALID_REGNUM, // EMM4H
322     LLDB_INVALID_REGNUM, // EMM5H
323     LLDB_INVALID_REGNUM, // EMM6H
324     LLDB_INVALID_REGNUM, // EMM7H
325     LLDB_INVALID_REGNUM, // MM00
326     LLDB_INVALID_REGNUM, // MM01
327     LLDB_INVALID_REGNUM, // MM10
328     LLDB_INVALID_REGNUM, // MM11
329     LLDB_INVALID_REGNUM, // MM20
330     LLDB_INVALID_REGNUM, // MM21
331     LLDB_INVALID_REGNUM, // MM30
332     LLDB_INVALID_REGNUM, // MM31
333     LLDB_INVALID_REGNUM, // MM40
334     LLDB_INVALID_REGNUM, // MM41
335     LLDB_INVALID_REGNUM, // MM50
336     LLDB_INVALID_REGNUM, // MM51
337     LLDB_INVALID_REGNUM, // MM60
338     LLDB_INVALID_REGNUM, // MM61
339     LLDB_INVALID_REGNUM, // MM70
340     LLDB_INVALID_REGNUM, // MM71
341     lldb_xmm8_x86_64,    // XMM8
342     lldb_xmm9_x86_64,    // XMM9
343     lldb_xmm10_x86_64,   // XMM10
344     lldb_xmm11_x86_64,   // XMM11
345     lldb_xmm12_x86_64,   // XMM12
346     lldb_xmm13_x86_64,   // XMM13
347     lldb_xmm14_x86_64,   // XMM14
348     lldb_xmm15_x86_64,   // XMM15
349     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
350     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
351     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
352     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
353     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
354     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
356     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
357     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
358     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
359     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
360     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
361     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
362     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
363     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
364     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
365     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
366     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
367     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
368     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
369     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
370     LLDB_INVALID_REGNUM,
371     lldb_sil_x86_64,   // SIL
372     lldb_dil_x86_64,   // DIL
373     lldb_bpl_x86_64,   // BPL
374     lldb_spl_x86_64,   // SPL
375     lldb_rax_x86_64,   // RAX
376     lldb_rbx_x86_64,   // RBX
377     lldb_rcx_x86_64,   // RCX
378     lldb_rdx_x86_64,   // RDX
379     lldb_rsi_x86_64,   // RSI
380     lldb_rdi_x86_64,   // RDI
381     lldb_rbp_x86_64,   // RBP
382     lldb_rsp_x86_64,   // RSP
383     lldb_r8_x86_64,    // R8
384     lldb_r9_x86_64,    // R9
385     lldb_r10_x86_64,   // R10
386     lldb_r11_x86_64,   // R11
387     lldb_r12_x86_64,   // R12
388     lldb_r13_x86_64,   // R13
389     lldb_r14_x86_64,   // R14
390     lldb_r15_x86_64,   // R15
391     lldb_r8l_x86_64,   // R8B
392     lldb_r9l_x86_64,   // R9B
393     lldb_r10l_x86_64,  // R10B
394     lldb_r11l_x86_64,  // R11B
395     lldb_r12l_x86_64,  // R12B
396     lldb_r13l_x86_64,  // R13B
397     lldb_r14l_x86_64,  // R14B
398     lldb_r15l_x86_64,  // R15B
399     lldb_r8w_x86_64,   // R8W
400     lldb_r9w_x86_64,   // R9W
401     lldb_r10w_x86_64,  // R10W
402     lldb_r11w_x86_64,  // R11W
403     lldb_r12w_x86_64,  // R12W
404     lldb_r13w_x86_64,  // R13W
405     lldb_r14w_x86_64,  // R14W
406     lldb_r15w_x86_64,  // R15W
407     lldb_r8d_x86_64,   // R8D
408     lldb_r9d_x86_64,   // R9D
409     lldb_r10d_x86_64,  // R10D
410     lldb_r11d_x86_64,  // R11D
411     lldb_r12d_x86_64,  // R12D
412     lldb_r13d_x86_64,  // R13D
413     lldb_r14d_x86_64,  // R14D
414     lldb_r15d_x86_64,  // R15D
415     lldb_ymm0_x86_64,  // AMD64_YMM0
416     lldb_ymm1_x86_64,  // AMD64_YMM1
417     lldb_ymm2_x86_64,  // AMD64_YMM2
418     lldb_ymm3_x86_64,  // AMD64_YMM3
419     lldb_ymm4_x86_64,  // AMD64_YMM4
420     lldb_ymm5_x86_64,  // AMD64_YMM5
421     lldb_ymm6_x86_64,  // AMD64_YMM6
422     lldb_ymm7_x86_64,  // AMD64_YMM7
423     lldb_ymm8_x86_64,  // AMD64_YMM8
424     lldb_ymm9_x86_64,  // AMD64_YMM9
425     lldb_ymm10_x86_64, // AMD64_YMM10
426     lldb_ymm11_x86_64, // AMD64_YMM11
427     lldb_ymm12_x86_64, // AMD64_YMM12
428     lldb_ymm13_x86_64, // AMD64_YMM13
429     lldb_ymm14_x86_64, // AMD64_YMM14
430     lldb_ymm15_x86_64, // AMD64_YMM15
431     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
432     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
433     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
434     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
435     lldb_bnd0_x86_64, // BND0
436     lldb_bnd1_x86_64, // BND1
437     lldb_bnd2_x86_64  // BND2
438 };
439 
440 uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
441                                llvm::codeview::RegisterId register_id) {
442   switch (arch_type) {
443   case llvm::Triple::x86:
444     if (static_cast<uint16_t>(register_id) <
445         sizeof(g_code_view_to_lldb_registers_x86) /
446             sizeof(g_code_view_to_lldb_registers_x86[0]))
447       return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
448           register_id)];
449 
450     switch (register_id) {
451     case llvm::codeview::RegisterId::MXCSR:
452       return lldb_mxcsr_i386;
453     case llvm::codeview::RegisterId::BND0:
454       return lldb_bnd0_i386;
455     case llvm::codeview::RegisterId::BND1:
456       return lldb_bnd1_i386;
457     case llvm::codeview::RegisterId::BND2:
458       return lldb_bnd2_i386;
459     default:
460       return LLDB_INVALID_REGNUM;
461     }
462   case llvm::Triple::x86_64:
463     if (static_cast<uint16_t>(register_id) <
464         sizeof(g_code_view_to_lldb_registers_x86_64) /
465             sizeof(g_code_view_to_lldb_registers_x86_64[0]))
466       return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
467           register_id)];
468 
469     return LLDB_INVALID_REGNUM;
470   default:
471     return LLDB_INVALID_REGNUM;
472   }
473 }
474 
475 uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
476   if (register_id == llvm::codeview::RegisterId::VFRAME)
477     return LLDB_REGNUM_GENERIC_FP;
478 
479   return LLDB_INVALID_REGNUM;
480 }
481 
482 static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type,
483                                   llvm::codeview::RegisterId register_id,
484                                   RegisterKind &register_kind) {
485   register_kind = eRegisterKindLLDB;
486   uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id);
487   if (reg_num != LLDB_INVALID_REGNUM)
488     return reg_num;
489 
490   register_kind = eRegisterKindGeneric;
491   return GetGenericRegisterNumber(register_id);
492 }
493 
494 static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) {
495   switch (kind) {
496   case SimpleTypeKind::Int128:
497   case SimpleTypeKind::Int64:
498   case SimpleTypeKind::Int64Quad:
499   case SimpleTypeKind::Int32:
500   case SimpleTypeKind::Int32Long:
501   case SimpleTypeKind::Int16:
502   case SimpleTypeKind::Int16Short:
503   case SimpleTypeKind::Float128:
504   case SimpleTypeKind::Float80:
505   case SimpleTypeKind::Float64:
506   case SimpleTypeKind::Float32:
507   case SimpleTypeKind::Float16:
508   case SimpleTypeKind::NarrowCharacter:
509   case SimpleTypeKind::SignedCharacter:
510   case SimpleTypeKind::SByte:
511     return true;
512   default:
513     return false;
514   }
515 }
516 
517 static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti,
518                                                    TpiStream &tpi) {
519   if (ti.isSimple()) {
520     SimpleTypeKind stk = ti.getSimpleKind();
521     return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)};
522   }
523 
524   CVType cvt = tpi.getType(ti);
525   switch (cvt.kind()) {
526   case LF_MODIFIER: {
527     ModifierRecord mfr;
528     llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
529     return GetIntegralTypeInfo(mfr.ModifiedType, tpi);
530   }
531   case LF_POINTER: {
532     PointerRecord pr;
533     llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
534     return GetIntegralTypeInfo(pr.ReferentType, tpi);
535   }
536   case LF_ENUM: {
537     EnumRecord er;
538     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
539     return GetIntegralTypeInfo(er.UnderlyingType, tpi);
540   }
541   default:
542     assert(false && "Type is not integral!");
543     return {0, false};
544   }
545 }
546 
547 template <typename StreamWriter>
548 static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
549                                                       StreamWriter &&writer) {
550   const ArchSpec &architecture = module->GetArchitecture();
551   ByteOrder byte_order = architecture.GetByteOrder();
552   uint32_t address_size = architecture.GetAddressByteSize();
553   uint32_t byte_size = architecture.GetDataByteSize();
554   if (byte_order == eByteOrderInvalid || address_size == 0)
555     return DWARFExpression(nullptr);
556 
557   RegisterKind register_kind = eRegisterKindDWARF;
558   StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
559 
560   if (!writer(stream, register_kind))
561     return DWARFExpression(nullptr);
562 
563   DataBufferSP buffer =
564       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
565   DataExtractor extractor(buffer, byte_order, address_size, byte_size);
566   DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
567   result.SetRegisterKind(register_kind);
568 
569   return result;
570 }
571 
572 static DWARFExpression MakeRegisterBasedLocationExpressionInternal(
573     llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset,
574     lldb::ModuleSP module) {
575   return MakeLocationExpressionInternal(
576       module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
577         uint32_t reg_num = GetRegisterNumber(
578             module->GetArchitecture().GetMachine(), reg, register_kind);
579         if (reg_num == LLDB_INVALID_REGNUM)
580           return false;
581 
582         if (reg_num > 31) {
583           llvm::dwarf::LocationAtom base = relative_offset
584                                                ? llvm::dwarf::DW_OP_bregx
585                                                : llvm::dwarf::DW_OP_regx;
586           stream.PutHex8(base);
587           stream.PutULEB128(reg_num);
588         } else {
589           llvm::dwarf::LocationAtom base = relative_offset
590                                                ? llvm::dwarf::DW_OP_breg0
591                                                : llvm::dwarf::DW_OP_reg0;
592           stream.PutHex8(base + reg_num);
593         }
594 
595         if (relative_offset)
596           stream.PutSLEB128(*relative_offset);
597 
598         return true;
599       });
600 }
601 
602 DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpression(
603     llvm::codeview::RegisterId reg, lldb::ModuleSP module) {
604   return MakeRegisterBasedLocationExpressionInternal(reg, llvm::None, module);
605 }
606 
607 DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression(
608     llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module) {
609   return MakeRegisterBasedLocationExpressionInternal(reg, offset, module);
610 }
611 
612 DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
613     uint16_t section, uint32_t offset, ModuleSP module) {
614   assert(section > 0);
615   assert(module);
616 
617   return MakeLocationExpressionInternal(
618       module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
619         stream.PutHex8(llvm::dwarf::DW_OP_addr);
620 
621         SectionList *section_list = module->GetSectionList();
622         assert(section_list);
623 
624         // Section indices in PDB are 1-based, but in DWARF they are 0-based, so
625         // we need to subtract 1.
626         uint32_t section_idx = section - 1;
627         if (section_idx >= section_list->GetSize())
628           return false;
629 
630         auto section_ptr = section_list->GetSectionAtIndex(section_idx);
631         if (!section_ptr)
632           return false;
633 
634         stream.PutMaxHex64(section_ptr->GetFileAddress() + offset,
635                            stream.GetAddressByteSize(), stream.GetByteOrder());
636 
637         return true;
638       });
639 }
640 
641 DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
642     TypeIndex underlying_ti, TpiStream &tpi, const llvm::APSInt &constant,
643     ModuleSP module) {
644   const ArchSpec &architecture = module->GetArchitecture();
645   uint32_t address_size = architecture.GetAddressByteSize();
646 
647   size_t size = 0;
648   bool is_signed = false;
649   std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi);
650 
651   union {
652     llvm::support::little64_t I;
653     llvm::support::ulittle64_t U;
654   } Value;
655 
656   std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
657   buffer->SetByteSize(size);
658 
659   llvm::ArrayRef<uint8_t> bytes;
660   if (is_signed) {
661     Value.I = constant.getSExtValue();
662   } else {
663     Value.U = constant.getZExtValue();
664   }
665 
666   bytes = llvm::makeArrayRef(reinterpret_cast<const uint8_t *>(&Value), 8)
667               .take_front(size);
668   buffer->CopyData(bytes.data(), size);
669   DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
670   DWARFExpression result(nullptr, extractor, nullptr, 0, size);
671   return result;
672 }
673