//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "DWARFLocationExpression.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamBuffer.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/Support/Endian.h" #include "PdbUtil.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::npdb; using namespace llvm::codeview; using namespace llvm::pdb; static const uint32_t g_code_view_to_lldb_registers_x86[] = { LLDB_INVALID_REGNUM, // NONE lldb_al_i386, // AL lldb_cl_i386, // CL lldb_dl_i386, // DL lldb_bl_i386, // BL lldb_ah_i386, // AH lldb_ch_i386, // CH lldb_dh_i386, // DH lldb_bh_i386, // BH lldb_ax_i386, // AX lldb_cx_i386, // CX lldb_dx_i386, // DX lldb_bx_i386, // BX lldb_sp_i386, // SP lldb_bp_i386, // BP lldb_si_i386, // SI lldb_di_i386, // DI lldb_eax_i386, // EAX lldb_ecx_i386, // ECX lldb_edx_i386, // EDX lldb_ebx_i386, // EBX lldb_esp_i386, // ESP lldb_ebp_i386, // EBP lldb_esi_i386, // ESI lldb_edi_i386, // EDI lldb_es_i386, // ES lldb_cs_i386, // CS lldb_ss_i386, // SS lldb_ds_i386, // DS lldb_fs_i386, // FS lldb_gs_i386, // GS LLDB_INVALID_REGNUM, // IP LLDB_INVALID_REGNUM, // FLAGS lldb_eip_i386, // EIP lldb_eflags_i386, // EFLAGS LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // TEMP LLDB_INVALID_REGNUM, // TEMPH LLDB_INVALID_REGNUM, // QUOTE LLDB_INVALID_REGNUM, // PCDR3 LLDB_INVALID_REGNUM, // PCDR4 LLDB_INVALID_REGNUM, // PCDR5 LLDB_INVALID_REGNUM, // PCDR6 LLDB_INVALID_REGNUM, // PCDR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // CR0 LLDB_INVALID_REGNUM, // CR1 LLDB_INVALID_REGNUM, // CR2 LLDB_INVALID_REGNUM, // CR3 LLDB_INVALID_REGNUM, // CR4 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_dr0_i386, // DR0 lldb_dr1_i386, // DR1 lldb_dr2_i386, // DR2 lldb_dr3_i386, // DR3 lldb_dr4_i386, // DR4 lldb_dr5_i386, // DR5 lldb_dr6_i386, // DR6 lldb_dr7_i386, // DR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // GDTR LLDB_INVALID_REGNUM, // GDTL LLDB_INVALID_REGNUM, // IDTR LLDB_INVALID_REGNUM, // IDTL LLDB_INVALID_REGNUM, // LDTR LLDB_INVALID_REGNUM, // TR LLDB_INVALID_REGNUM, // PSEUDO1 LLDB_INVALID_REGNUM, // PSEUDO2 LLDB_INVALID_REGNUM, // PSEUDO3 LLDB_INVALID_REGNUM, // PSEUDO4 LLDB_INVALID_REGNUM, // PSEUDO5 LLDB_INVALID_REGNUM, // PSEUDO6 LLDB_INVALID_REGNUM, // PSEUDO7 LLDB_INVALID_REGNUM, // PSEUDO8 LLDB_INVALID_REGNUM, // PSEUDO9 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st0_i386, // ST0 lldb_st1_i386, // ST1 lldb_st2_i386, // ST2 lldb_st3_i386, // ST3 lldb_st4_i386, // ST4 lldb_st5_i386, // ST5 lldb_st6_i386, // ST6 lldb_st7_i386, // ST7 LLDB_INVALID_REGNUM, // CTRL LLDB_INVALID_REGNUM, // STAT LLDB_INVALID_REGNUM, // TAG LLDB_INVALID_REGNUM, // FPIP LLDB_INVALID_REGNUM, // FPCS LLDB_INVALID_REGNUM, // FPDO LLDB_INVALID_REGNUM, // FPDS LLDB_INVALID_REGNUM, // ISEM LLDB_INVALID_REGNUM, // FPEIP LLDB_INVALID_REGNUM, // FPEDO lldb_mm0_i386, // MM0 lldb_mm1_i386, // MM1 lldb_mm2_i386, // MM2 lldb_mm3_i386, // MM3 lldb_mm4_i386, // MM4 lldb_mm5_i386, // MM5 lldb_mm6_i386, // MM6 lldb_mm7_i386, // MM7 lldb_xmm0_i386, // XMM0 lldb_xmm1_i386, // XMM1 lldb_xmm2_i386, // XMM2 lldb_xmm3_i386, // XMM3 lldb_xmm4_i386, // XMM4 lldb_xmm5_i386, // XMM5 lldb_xmm6_i386, // XMM6 lldb_xmm7_i386 // XMM7 }; static const uint32_t g_code_view_to_lldb_registers_x86_64[] = { LLDB_INVALID_REGNUM, // NONE lldb_al_x86_64, // AL lldb_cl_x86_64, // CL lldb_dl_x86_64, // DL lldb_bl_x86_64, // BL lldb_ah_x86_64, // AH lldb_ch_x86_64, // CH lldb_dh_x86_64, // DH lldb_bh_x86_64, // BH lldb_ax_x86_64, // AX lldb_cx_x86_64, // CX lldb_dx_x86_64, // DX lldb_bx_x86_64, // BX lldb_sp_x86_64, // SP lldb_bp_x86_64, // BP lldb_si_x86_64, // SI lldb_di_x86_64, // DI lldb_eax_x86_64, // EAX lldb_ecx_x86_64, // ECX lldb_edx_x86_64, // EDX lldb_ebx_x86_64, // EBX lldb_esp_x86_64, // ESP lldb_ebp_x86_64, // EBP lldb_esi_x86_64, // ESI lldb_edi_x86_64, // EDI lldb_es_x86_64, // ES lldb_cs_x86_64, // CS lldb_ss_x86_64, // SS lldb_ds_x86_64, // DS lldb_fs_x86_64, // FS lldb_gs_x86_64, // GS LLDB_INVALID_REGNUM, // IP LLDB_INVALID_REGNUM, // FLAGS LLDB_INVALID_REGNUM, // EIP LLDB_INVALID_REGNUM, // EFLAGS LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // TEMP LLDB_INVALID_REGNUM, // TEMPH LLDB_INVALID_REGNUM, // QUOTE LLDB_INVALID_REGNUM, // PCDR3 LLDB_INVALID_REGNUM, // PCDR4 LLDB_INVALID_REGNUM, // PCDR5 LLDB_INVALID_REGNUM, // PCDR6 LLDB_INVALID_REGNUM, // PCDR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // CR0 LLDB_INVALID_REGNUM, // CR1 LLDB_INVALID_REGNUM, // CR2 LLDB_INVALID_REGNUM, // CR3 LLDB_INVALID_REGNUM, // CR4 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_dr0_x86_64, // DR0 lldb_dr1_x86_64, // DR1 lldb_dr2_x86_64, // DR2 lldb_dr3_x86_64, // DR3 lldb_dr4_x86_64, // DR4 lldb_dr5_x86_64, // DR5 lldb_dr6_x86_64, // DR6 lldb_dr7_x86_64, // DR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // GDTR LLDB_INVALID_REGNUM, // GDTL LLDB_INVALID_REGNUM, // IDTR LLDB_INVALID_REGNUM, // IDTL LLDB_INVALID_REGNUM, // LDTR LLDB_INVALID_REGNUM, // TR LLDB_INVALID_REGNUM, // PSEUDO1 LLDB_INVALID_REGNUM, // PSEUDO2 LLDB_INVALID_REGNUM, // PSEUDO3 LLDB_INVALID_REGNUM, // PSEUDO4 LLDB_INVALID_REGNUM, // PSEUDO5 LLDB_INVALID_REGNUM, // PSEUDO6 LLDB_INVALID_REGNUM, // PSEUDO7 LLDB_INVALID_REGNUM, // PSEUDO8 LLDB_INVALID_REGNUM, // PSEUDO9 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st0_x86_64, // ST0 lldb_st1_x86_64, // ST1 lldb_st2_x86_64, // ST2 lldb_st3_x86_64, // ST3 lldb_st4_x86_64, // ST4 lldb_st5_x86_64, // ST5 lldb_st6_x86_64, // ST6 lldb_st7_x86_64, // ST7 LLDB_INVALID_REGNUM, // CTRL LLDB_INVALID_REGNUM, // STAT LLDB_INVALID_REGNUM, // TAG LLDB_INVALID_REGNUM, // FPIP LLDB_INVALID_REGNUM, // FPCS LLDB_INVALID_REGNUM, // FPDO LLDB_INVALID_REGNUM, // FPDS LLDB_INVALID_REGNUM, // ISEM LLDB_INVALID_REGNUM, // FPEIP LLDB_INVALID_REGNUM, // FPEDO lldb_mm0_x86_64, // MM0 lldb_mm1_x86_64, // MM1 lldb_mm2_x86_64, // MM2 lldb_mm3_x86_64, // MM3 lldb_mm4_x86_64, // MM4 lldb_mm5_x86_64, // MM5 lldb_mm6_x86_64, // MM6 lldb_mm7_x86_64, // MM7 lldb_xmm0_x86_64, // XMM0 lldb_xmm1_x86_64, // XMM1 lldb_xmm2_x86_64, // XMM2 lldb_xmm3_x86_64, // XMM3 lldb_xmm4_x86_64, // XMM4 lldb_xmm5_x86_64, // XMM5 lldb_xmm6_x86_64, // XMM6 lldb_xmm7_x86_64, // XMM7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mxcsr_x86_64, // MXCSR LLDB_INVALID_REGNUM, // EDXEAX LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, // EMM0L LLDB_INVALID_REGNUM, // EMM1L LLDB_INVALID_REGNUM, // EMM2L LLDB_INVALID_REGNUM, // EMM3L LLDB_INVALID_REGNUM, // EMM4L LLDB_INVALID_REGNUM, // EMM5L LLDB_INVALID_REGNUM, // EMM6L LLDB_INVALID_REGNUM, // EMM7L LLDB_INVALID_REGNUM, // EMM0H LLDB_INVALID_REGNUM, // EMM1H LLDB_INVALID_REGNUM, // EMM2H LLDB_INVALID_REGNUM, // EMM3H LLDB_INVALID_REGNUM, // EMM4H LLDB_INVALID_REGNUM, // EMM5H LLDB_INVALID_REGNUM, // EMM6H LLDB_INVALID_REGNUM, // EMM7H LLDB_INVALID_REGNUM, // MM00 LLDB_INVALID_REGNUM, // MM01 LLDB_INVALID_REGNUM, // MM10 LLDB_INVALID_REGNUM, // MM11 LLDB_INVALID_REGNUM, // MM20 LLDB_INVALID_REGNUM, // MM21 LLDB_INVALID_REGNUM, // MM30 LLDB_INVALID_REGNUM, // MM31 LLDB_INVALID_REGNUM, // MM40 LLDB_INVALID_REGNUM, // MM41 LLDB_INVALID_REGNUM, // MM50 LLDB_INVALID_REGNUM, // MM51 LLDB_INVALID_REGNUM, // MM60 LLDB_INVALID_REGNUM, // MM61 LLDB_INVALID_REGNUM, // MM70 LLDB_INVALID_REGNUM, // MM71 lldb_xmm8_x86_64, // XMM8 lldb_xmm9_x86_64, // XMM9 lldb_xmm10_x86_64, // XMM10 lldb_xmm11_x86_64, // XMM11 lldb_xmm12_x86_64, // XMM12 lldb_xmm13_x86_64, // XMM13 lldb_xmm14_x86_64, // XMM14 lldb_xmm15_x86_64, // XMM15 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_sil_x86_64, // SIL lldb_dil_x86_64, // DIL lldb_bpl_x86_64, // BPL lldb_spl_x86_64, // SPL lldb_rax_x86_64, // RAX lldb_rbx_x86_64, // RBX lldb_rcx_x86_64, // RCX lldb_rdx_x86_64, // RDX lldb_rsi_x86_64, // RSI lldb_rdi_x86_64, // RDI lldb_rbp_x86_64, // RBP lldb_rsp_x86_64, // RSP lldb_r8_x86_64, // R8 lldb_r9_x86_64, // R9 lldb_r10_x86_64, // R10 lldb_r11_x86_64, // R11 lldb_r12_x86_64, // R12 lldb_r13_x86_64, // R13 lldb_r14_x86_64, // R14 lldb_r15_x86_64, // R15 lldb_r8l_x86_64, // R8B lldb_r9l_x86_64, // R9B lldb_r10l_x86_64, // R10B lldb_r11l_x86_64, // R11B lldb_r12l_x86_64, // R12B lldb_r13l_x86_64, // R13B lldb_r14l_x86_64, // R14B lldb_r15l_x86_64, // R15B lldb_r8w_x86_64, // R8W lldb_r9w_x86_64, // R9W lldb_r10w_x86_64, // R10W lldb_r11w_x86_64, // R11W lldb_r12w_x86_64, // R12W lldb_r13w_x86_64, // R13W lldb_r14w_x86_64, // R14W lldb_r15w_x86_64, // R15W lldb_r8d_x86_64, // R8D lldb_r9d_x86_64, // R9D lldb_r10d_x86_64, // R10D lldb_r11d_x86_64, // R11D lldb_r12d_x86_64, // R12D lldb_r13d_x86_64, // R13D lldb_r14d_x86_64, // R14D lldb_r15d_x86_64, // R15D lldb_ymm0_x86_64, // AMD64_YMM0 lldb_ymm1_x86_64, // AMD64_YMM1 lldb_ymm2_x86_64, // AMD64_YMM2 lldb_ymm3_x86_64, // AMD64_YMM3 lldb_ymm4_x86_64, // AMD64_YMM4 lldb_ymm5_x86_64, // AMD64_YMM5 lldb_ymm6_x86_64, // AMD64_YMM6 lldb_ymm7_x86_64, // AMD64_YMM7 lldb_ymm8_x86_64, // AMD64_YMM8 lldb_ymm9_x86_64, // AMD64_YMM9 lldb_ymm10_x86_64, // AMD64_YMM10 lldb_ymm11_x86_64, // AMD64_YMM11 lldb_ymm12_x86_64, // AMD64_YMM12 lldb_ymm13_x86_64, // AMD64_YMM13 lldb_ymm14_x86_64, // AMD64_YMM14 lldb_ymm15_x86_64, // AMD64_YMM15 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_bnd0_x86_64, // BND0 lldb_bnd1_x86_64, // BND1 lldb_bnd2_x86_64 // BND2 }; uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id) { switch (arch_type) { case llvm::Triple::x86: if (static_cast(register_id) < sizeof(g_code_view_to_lldb_registers_x86) / sizeof(g_code_view_to_lldb_registers_x86[0])) return g_code_view_to_lldb_registers_x86[static_cast( register_id)]; switch (register_id) { case llvm::codeview::RegisterId::MXCSR: return lldb_mxcsr_i386; case llvm::codeview::RegisterId::BND0: return lldb_bnd0_i386; case llvm::codeview::RegisterId::BND1: return lldb_bnd1_i386; case llvm::codeview::RegisterId::BND2: return lldb_bnd2_i386; default: return LLDB_INVALID_REGNUM; } case llvm::Triple::x86_64: if (static_cast(register_id) < sizeof(g_code_view_to_lldb_registers_x86_64) / sizeof(g_code_view_to_lldb_registers_x86_64[0])) return g_code_view_to_lldb_registers_x86_64[static_cast( register_id)]; return LLDB_INVALID_REGNUM; default: return LLDB_INVALID_REGNUM; } } uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) { if (register_id == llvm::codeview::RegisterId::VFRAME) return LLDB_REGNUM_GENERIC_FP; return LLDB_INVALID_REGNUM; } static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id, RegisterKind ®ister_kind) { register_kind = eRegisterKindLLDB; uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id); if (reg_num != LLDB_INVALID_REGNUM) return reg_num; register_kind = eRegisterKindGeneric; return GetGenericRegisterNumber(register_id); } static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) { switch (kind) { case SimpleTypeKind::Int128: case SimpleTypeKind::Int64: case SimpleTypeKind::Int64Quad: case SimpleTypeKind::Int32: case SimpleTypeKind::Int32Long: case SimpleTypeKind::Int16: case SimpleTypeKind::Int16Short: case SimpleTypeKind::Float128: case SimpleTypeKind::Float80: case SimpleTypeKind::Float64: case SimpleTypeKind::Float32: case SimpleTypeKind::Float16: case SimpleTypeKind::NarrowCharacter: case SimpleTypeKind::SignedCharacter: case SimpleTypeKind::SByte: return true; default: return false; } } static std::pair GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi) { if (ti.isSimple()) { SimpleTypeKind stk = ti.getSimpleKind(); return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)}; } CVType cvt = tpi.getType(ti); switch (cvt.kind()) { case LF_MODIFIER: { ModifierRecord mfr; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, mfr)); return GetIntegralTypeInfo(mfr.ModifiedType, tpi); } case LF_POINTER: { PointerRecord pr; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); return GetIntegralTypeInfo(pr.ReferentType, tpi); } case LF_ENUM: { EnumRecord er; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); return GetIntegralTypeInfo(er.UnderlyingType, tpi); } default: assert(false && "Type is not integral!"); return {0, false}; } } template static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module, StreamWriter &&writer) { const ArchSpec &architecture = module->GetArchitecture(); ByteOrder byte_order = architecture.GetByteOrder(); uint32_t address_size = architecture.GetAddressByteSize(); uint32_t byte_size = architecture.GetDataByteSize(); if (byte_order == eByteOrderInvalid || address_size == 0) return DWARFExpression(nullptr); RegisterKind register_kind = eRegisterKindDWARF; StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); if (!writer(stream, register_kind)) return DWARFExpression(nullptr); DataBufferSP buffer = std::make_shared(stream.GetData(), stream.GetSize()); DataExtractor extractor(buffer, byte_order, address_size, byte_size); DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize()); result.SetRegisterKind(register_kind); return result; } static DWARFExpression MakeRegisterBasedLocationExpressionInternal( llvm::codeview::RegisterId reg, llvm::Optional relative_offset, lldb::ModuleSP module) { return MakeLocationExpressionInternal( module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { uint32_t reg_num = GetRegisterNumber( module->GetArchitecture().GetMachine(), reg, register_kind); if (reg_num == LLDB_INVALID_REGNUM) return false; if (reg_num > 31) { llvm::dwarf::LocationAtom base = relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx; stream.PutHex8(base); stream.PutULEB128(reg_num); } else { llvm::dwarf::LocationAtom base = relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0; stream.PutHex8(base + reg_num); } if (relative_offset) stream.PutSLEB128(*relative_offset); return true; }); } DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpression( llvm::codeview::RegisterId reg, lldb::ModuleSP module) { return MakeRegisterBasedLocationExpressionInternal(reg, llvm::None, module); } DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression( llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module) { return MakeRegisterBasedLocationExpressionInternal(reg, offset, module); } DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression( uint16_t section, uint32_t offset, ModuleSP module) { assert(section > 0); assert(module); return MakeLocationExpressionInternal( module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { stream.PutHex8(llvm::dwarf::DW_OP_addr); SectionList *section_list = module->GetSectionList(); assert(section_list); // Section indices in PDB are 1-based, but in DWARF they are 0-based, so // we need to subtract 1. uint32_t section_idx = section - 1; if (section_idx >= section_list->GetSize()) return false; auto section_ptr = section_list->GetSectionAtIndex(section_idx); if (!section_ptr) return false; stream.PutMaxHex64(section_ptr->GetFileAddress() + offset, stream.GetAddressByteSize(), stream.GetByteOrder()); return true; }); } DWARFExpression lldb_private::npdb::MakeConstantLocationExpression( TypeIndex underlying_ti, TpiStream &tpi, const llvm::APSInt &constant, ModuleSP module) { const ArchSpec &architecture = module->GetArchitecture(); uint32_t address_size = architecture.GetAddressByteSize(); size_t size = 0; bool is_signed = false; std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi); union { llvm::support::little64_t I; llvm::support::ulittle64_t U; } Value; std::shared_ptr buffer = std::make_shared(); buffer->SetByteSize(size); llvm::ArrayRef bytes; if (is_signed) { Value.I = constant.getSExtValue(); } else { Value.U = constant.getZExtValue(); } bytes = llvm::makeArrayRef(reinterpret_cast(&Value), 8) .take_front(size); buffer->CopyData(bytes.data(), size); DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size); DWARFExpression result(nullptr, extractor, nullptr, 0, size); return result; }