diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
| commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
| tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Plugins/SymbolFile/NativePDB | |
| parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/SymbolFile/NativePDB')
20 files changed, 1021 insertions, 582 deletions
diff --git a/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp new file mode 100644 index 000000000000..3834165c71c0 --- /dev/null +++ b/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp @@ -0,0 +1,457 @@ +//===-- CodeViewRegisterMapping.cpp -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CodeViewRegisterMapping.h" + +#include "lldb/lldb-defines.h" + +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" + +using namespace lldb_private; + +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 lldb_private::npdb::GetLLDBRegisterNumber( + llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id) { + switch (arch_type) { + case llvm::Triple::x86: + if (static_cast<uint16_t>(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<uint16_t>( + 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<uint16_t>(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<uint16_t>( + register_id)]; + + return LLDB_INVALID_REGNUM; + default: + return LLDB_INVALID_REGNUM; + } +} diff --git a/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h new file mode 100644 index 000000000000..b1c31e0c1785 --- /dev/null +++ b/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h @@ -0,0 +1,24 @@ +//===-- CodeViewRegisterMapping.h -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ +#define lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ + +#include "llvm/ADT/Triple.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" + +namespace lldb_private { +namespace npdb { + +uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, + llvm::codeview::RegisterId register_id); + +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index 67ea05767fde..1838204e4ca6 100644 --- a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -1,9 +1,8 @@ //===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -125,11 +124,20 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { uint16_t stream = descriptor.getModuleStreamIndex(); std::unique_ptr<llvm::msf::MappedBlockStream> stream_data = m_index.pdb().createIndexedStream(stream); + + + std::unique_ptr<CompilandIndexItem>& cci = result.first->second; + + if (!stream_data) { + llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, nullptr); + cci = llvm::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor)); + return *cci; + } + llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, std::move(stream_data)); - cantFail(debug_stream.reload()); - std::unique_ptr<CompilandIndexItem> &cci = result.first->second; + cantFail(debug_stream.reload()); cci = llvm::make_unique<CompilandIndexItem>( PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor)); diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index c965870da44b..44a1c8cdd9c2 100644 --- a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -1,9 +1,8 @@ //===-- CompileUnitIndex.h --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp index 7b62530e4680..3d8bfb058721 100644 --- a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp +++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -1,15 +1,13 @@ //===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #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" @@ -24,6 +22,8 @@ #include "llvm/Support/Endian.h" #include "PdbUtil.h" +#include "CodeViewRegisterMapping.h" +#include "PdbFPOProgramToDWARFExpression.h" using namespace lldb; using namespace lldb_private; @@ -31,448 +31,6 @@ 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<uint16_t>(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<uint16_t>( - 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<uint16_t>(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<uint16_t>( - 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; @@ -553,13 +111,13 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module, uint32_t address_size = architecture.GetAddressByteSize(); uint32_t byte_size = architecture.GetDataByteSize(); if (byte_order == eByteOrderInvalid || address_size == 0) - return DWARFExpression(nullptr); + return DWARFExpression(); RegisterKind register_kind = eRegisterKindDWARF; StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); if (!writer(stream, register_kind)) - return DWARFExpression(nullptr); + return DWARFExpression(); DataBufferSP buffer = std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize()); @@ -610,6 +168,33 @@ DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression( return MakeRegisterBasedLocationExpressionInternal(reg, offset, module); } +static bool EmitVFrameEvaluationDWARFExpression( + llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) { + // VFrame value always stored in $TO pseudo-register + return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type, + stream); +} + +DWARFExpression lldb_private::npdb::MakeVFrameRelLocationExpression( + llvm::StringRef fpo_program, int32_t offset, lldb::ModuleSP module) { + return MakeLocationExpressionInternal( + module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { + const ArchSpec &architecture = module->GetArchitecture(); + + if (!EmitVFrameEvaluationDWARFExpression(fpo_program, architecture.GetMachine(), + stream)) + return false; + + stream.PutHex8(llvm::dwarf::DW_OP_consts); + stream.PutSLEB128(offset); + stream.PutHex8(llvm::dwarf::DW_OP_plus); + + register_kind = eRegisterKindLLDB; + + return true; + }); +} + DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression( uint16_t section, uint32_t offset, ModuleSP module) { assert(section > 0); @@ -622,13 +207,7 @@ DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression( 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); + auto section_ptr = section_list->FindSectionByID(section); if (!section_ptr) return false; diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h index 670e95ee8e3c..c37d715babdc 100644 --- a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h +++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -1,9 +1,8 @@ //===-- DWARFLocationExpression.h -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -31,6 +30,9 @@ MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg, DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module); +DWARFExpression MakeVFrameRelLocationExpression(llvm::StringRef fpo_program, + int32_t offset, + lldb::ModuleSP module); DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, lldb::ModuleSP module); DWARFExpression MakeConstantLocationExpression( diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 8917fd092385..4991be8e70ce 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -205,13 +205,17 @@ GetNestedTagDefinition(const NestedTypeRecord &Record, return std::move(child); } +static bool IsAnonymousNamespaceName(llvm::StringRef name) { + return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; +} + PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index) : m_index(index), m_clang(GetClangASTContext(obj)) { BuildParentMap(); } -clang::DeclContext &PdbAstBuilder::GetTranslationUnitDecl() { - return *m_clang.GetTranslationUnitDecl(); +lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() { + return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl()); } std::pair<clang::DeclContext *, std::string> @@ -256,7 +260,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { for (llvm::ms_demangle::Node *scope : scopes) { auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope); std::string str = nii->toString(); - context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context); + context = GetOrCreateNamespaceDecl(str.c_str(), *context); } return {context, uname}; } @@ -488,7 +492,7 @@ clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) { clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) { if (uid.kind() == PdbSymUidKind::CompilandSym) { if (uid.asCompilandSym().offset == 0) - return &GetTranslationUnitDecl(); + return FromCompilerDeclContext(GetTranslationUnitDecl()); } clang::Decl *decl = GetOrCreateDeclForUid(uid); @@ -503,7 +507,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { MSVCUndecoratedNameParser parser(name); llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); - clang::DeclContext *context = &GetTranslationUnitDecl(); + auto context = FromCompilerDeclContext(GetTranslationUnitDecl()); llvm::StringRef uname = specs.back().GetBaseName(); specs = specs.drop_back(); @@ -525,7 +529,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { // If that fails, treat it as a series of namespaces. for (const MSVCUndecoratedNameSpecifier &spec : specs) { std::string ns_name = spec.GetBaseName().str(); - context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context); + context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context); } return {context, uname}; } @@ -544,7 +548,7 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) { StringView name{pub->Name.begin(), pub->Name.size()}; llvm::ms_demangle::SymbolNode *node = demangler.parse(name); if (!node) - return &GetTranslationUnitDecl(); + return FromCompilerDeclContext(GetTranslationUnitDecl()); llvm::ArrayRef<llvm::ms_demangle::Node *> name_components{ node->Name->Components->Nodes, node->Name->Components->Count - 1}; @@ -565,10 +569,10 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) { } // It's not a type. It must be a series of namespaces. - clang::DeclContext *context = &GetTranslationUnitDecl(); + auto context = FromCompilerDeclContext(GetTranslationUnitDecl()); while (!name_components.empty()) { std::string ns = name_components.front()->toString(); - context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context); + context = GetOrCreateNamespaceDecl(ns.c_str(), *context); name_components = name_components.drop_front(); } return context; @@ -593,7 +597,7 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { PdbTypeSymId type_id = uid.asTypeSym(); auto iter = m_parent_types.find(type_id.index); if (iter == m_parent_types.end()) - return &GetTranslationUnitDecl(); + return FromCompilerDeclContext(GetTranslationUnitDecl()); return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second)); } case PdbSymUidKind::FieldListMember: @@ -631,7 +635,7 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { default: break; } - return &GetTranslationUnitDecl(); + return FromCompilerDeclContext(GetTranslationUnitDecl()); } bool PdbAstBuilder::CompleteType(clang::QualType qt) { @@ -805,9 +809,10 @@ clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const { } clang::NamespaceDecl * -PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name, +PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context) { - return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context); + return m_clang.GetUniqueNamespaceDeclaration( + IsAnonymousNamespaceName(name) ? nullptr : name, &context); } clang::BlockDecl * @@ -861,7 +866,8 @@ clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) { return llvm::dyn_cast<clang::VarDecl>(decl); CVSymbol sym = m_index.ReadSymbolRecord(var_id); - return CreateVariableDecl(PdbSymUid(var_id), sym, GetTranslationUnitDecl()); + auto context = FromCompilerDeclContext(GetTranslationUnitDecl()); + return CreateVariableDecl(PdbSymUid(var_id), sym, *context); } clang::TypedefNameDecl * @@ -933,7 +939,14 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { if (cvt.kind() == LF_PROCEDURE) { ProcedureRecord pr; llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); - return CreateProcedureType(pr); + return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv); + } + + if (cvt.kind() == LF_MFUNCTION) { + MemberFunctionRecord mfr; + llvm::cantFail( + TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); + return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv); } return {}; @@ -1117,10 +1130,11 @@ clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType()); } -clang::QualType -PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) { +clang::QualType PdbAstBuilder::CreateFunctionType( + TypeIndex args_type_idx, TypeIndex return_type_idx, + llvm::codeview::CallingConvention calling_convention) { TpiStream &stream = m_index.tpi(); - CVType args_cvt = stream.getType(proc.ArgumentList); + CVType args_cvt = stream.getType(args_type_idx); ArgListRecord args; llvm::cantFail( TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args)); @@ -1138,10 +1152,10 @@ PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) { arg_types.push_back(ToCompilerType(arg_type)); } - clang::QualType return_type = GetOrCreateType(proc.ReturnType); + clang::QualType return_type = GetOrCreateType(return_type_idx); llvm::Optional<clang::CallingConv> cc = - TranslateCallingConvention(proc.CallConv); + TranslateCallingConvention(calling_convention); if (!cc) return {}; @@ -1340,6 +1354,10 @@ PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { return {&m_clang, &context}; } +clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) { + return static_cast<clang::Decl *>(decl.GetOpaqueDecl()); +} + clang::DeclContext * PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) { return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext()); diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index e3c0346f935e..67d024741e0d 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -1,9 +1,8 @@ //===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -51,19 +50,15 @@ struct DeclStatus { class PdbAstBuilder { public: - //------------------------------------------------------------------ // Constructors and Destructors - //------------------------------------------------------------------ PdbAstBuilder(ObjectFile &obj, PdbIndex &index); - clang::DeclContext &GetTranslationUnitDecl(); + lldb_private::CompilerDeclContext GetTranslationUnitDecl(); clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid); clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid); clang::DeclContext *GetParentDeclContext(PdbSymUid uid); - clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name, - clang::DeclContext &context); clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id); clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id); clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id, @@ -81,6 +76,7 @@ public: CompilerDecl ToCompilerDecl(clang::Decl &decl); CompilerType ToCompilerType(clang::QualType qt); CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context); + clang::Decl * FromCompilerDecl(CompilerDecl decl); clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context); ClangASTContext &clang() { return m_clang; } @@ -103,7 +99,8 @@ private: clang::QualType CreateEnumType(PdbTypeSymId id, const llvm::codeview::EnumRecord &record); clang::QualType - CreateProcedureType(const llvm::codeview::ProcedureRecord &proc); + CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx, + llvm::codeview::CallingConvention calling_convention); clang::QualType CreateType(PdbTypeSymId type); void CreateFunctionParameters(PdbCompilandSymId func_id, @@ -116,6 +113,9 @@ private: clang::DeclContext * GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym); + clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name, + clang::DeclContext &context); + void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent); void ParseDeclsForSimpleContext(clang::DeclContext &context); void ParseBlockChildren(PdbCompilandSymId block_id); diff --git a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp new file mode 100644 index 000000000000..79dd010ff311 --- /dev/null +++ b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -0,0 +1,137 @@ +//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "PdbFPOProgramToDWARFExpression.h" +#include "CodeViewRegisterMapping.h" + +#include "lldb/Core/StreamBuffer.h" +#include "lldb/Symbol/PostfixExpression.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Stream.h" +#include "llvm/ADT/DenseMap.h" + +#include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/EnumTables.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::postfix; + +static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) { + // lookup register name to get lldb register number + llvm::codeview::CPUType cpu_type; + switch (arch_type) { + case llvm::Triple::ArchType::aarch64: + cpu_type = llvm::codeview::CPUType::ARM64; + break; + + default: + cpu_type = llvm::codeview::CPUType::X64; + break; + } + + llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names = + llvm::codeview::getRegisterNames(cpu_type); + auto it = llvm::find_if( + register_names, + [®_name](const llvm::EnumEntry<uint16_t> ®ister_entry) { + return reg_name.compare_lower(register_entry.Name) == 0; + }); + + if (it == register_names.end()) + return LLDB_INVALID_REGNUM; + + auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value); + return npdb::GetLLDBRegisterNumber(arch_type, reg_id); +} + +static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program, + llvm::BumpPtrAllocator &alloc, + llvm::StringRef ®ister_name, + Node *&ast) { + // lvalue of assignment is always first token + // rvalue program goes next + std::tie(register_name, program) = getToken(program); + if (register_name.empty()) + return false; + + ast = Parse(program, alloc); + return ast != nullptr; +} + +static Node *ParseFPOProgram(llvm::StringRef program, + llvm::StringRef register_name, + llvm::Triple::ArchType arch_type, + llvm::BumpPtrAllocator &alloc) { + llvm::DenseMap<llvm::StringRef, Node *> dependent_programs; + + size_t cur = 0; + while (true) { + size_t assign_index = program.find('=', cur); + if (assign_index == llvm::StringRef::npos) { + llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos); + if (!tail.trim().empty()) { + // missing assign operator + return nullptr; + } + break; + } + llvm::StringRef assignment_program = program.slice(cur, assign_index); + + llvm::StringRef lvalue_name; + Node *rvalue_ast = nullptr; + if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name, + rvalue_ast)) { + return nullptr; + } + + lldbassert(rvalue_ast); + + // Emplace valid dependent subtrees to make target assignment independent + // from predecessors. Resolve all other SymbolNodes as registers. + bool success = + ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * { + if (Node *node = dependent_programs.lookup(symbol.GetName())) + return node; + uint32_t reg_num = + ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type); + + if (reg_num == LLDB_INVALID_REGNUM) + return nullptr; + + return MakeNode<RegisterNode>(alloc, reg_num); + }); + if (!success) + return nullptr; + + if (lvalue_name == register_name) { + // found target assignment program - no need to parse further + return rvalue_ast; + } + + dependent_programs[lvalue_name] = rvalue_ast; + cur = assign_index + 1; + } + + return nullptr; +} + +bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression( + llvm::StringRef program, llvm::StringRef register_name, + llvm::Triple::ArchType arch_type, Stream &stream) { + llvm::BumpPtrAllocator node_alloc; + Node *target_program = + ParseFPOProgram(program, register_name, arch_type, node_alloc); + if (target_program == nullptr) { + return false; + } + + ToDWARF(*target_program, stream); + return true; +} diff --git a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h new file mode 100644 index 000000000000..107e26fb04cb --- /dev/null +++ b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h @@ -0,0 +1,28 @@ +//===-- PdbFPOProgramToDWARFExpression.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ +#define lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" + +namespace lldb_private { +class Stream; + +namespace npdb { + +bool TranslateFPOProgramToDWARFExpression(llvm::StringRef program, + llvm::StringRef register_name, + llvm::Triple::ArchType arch_type, + lldb_private::Stream &stream); + +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index 9f5dab6c2e84..ba9a95b16e18 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -1,9 +1,8 @@ //===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -133,9 +132,8 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { PdbCompilandSymId cu_sym_id(modi, iter.offset()); - // If the debug info is incorrect, we could have multiple symbols with the - // same address. So use try_emplace instead of insert, and the first one - // will win. + // It's rare, but we could have multiple symbols with the same address + // because of identical comdat folding. Right now, the first one will win. cci.m_symbols_by_va.insert(std::make_pair(va, PdbSymUid(cu_sym_id))); } } @@ -187,8 +185,6 @@ std::vector<SymbolAndUid> PdbIndex::FindSymbolsByVa(lldb::addr_t va) { } CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const { - // We need to subtract 4 here to adjust for the codeview debug magic - // at the beginning of the debug info stream. const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi); auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset); lldbassert(iter != cci->m_debug_stream.getSymbolArray().end()); diff --git a/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index 839d4e6606e4..b30e7870bbdb 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -1,9 +1,8 @@ //===-- PdbIndex.h ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -115,6 +114,7 @@ public: create(std::unique_ptr<llvm::pdb::PDBFile>); void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } + lldb::addr_t GetLoadAddress() const { return m_load_address; } void ParseSectionContribs(); llvm::pdb::PDBFile &pdb() { return *m_file; } diff --git a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp index e5424568da47..e5ad23f813eb 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp +++ b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp @@ -1,9 +1,8 @@ //===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h index 1166bee4e327..7252d63c1ab4 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h +++ b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h @@ -1,9 +1,8 @@ //===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // A unique identification scheme for Pdb records. diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index 317725dd250e..1f5c97da81cf 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -1,9 +1,8 @@ //===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,9 +14,11 @@ #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "lldb/Symbol/Block.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/lldb-enumerations.h" @@ -43,7 +44,7 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, gaps = gaps.drop_front(); } - result.Append(start, end); + result.Append(start, end - start); return result; } @@ -507,8 +508,78 @@ VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { return {}; } +static llvm::FixedStreamArray<FrameData>::Iterator +GetCorrespondingFrameData(lldb::addr_t load_addr, + const DebugFrameDataSubsectionRef &fpo_data, + const Variable::RangeList &ranges) { + lldbassert(!ranges.IsEmpty()); + + // assume that all variable ranges correspond to one frame data + using RangeListEntry = Variable::RangeList::Entry; + const RangeListEntry &range = ranges.GetEntryRef(0); + + auto it = fpo_data.begin(); + + // start by searching first frame data range containing variable range + for (; it != fpo_data.end(); ++it) { + RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); + + if (fd_range.Contains(range)) { + break; + } + } + + // then first most nested entry that still contains variable range + auto found = it; + for (; it != fpo_data.end(); ++it) { + RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); + + if (!fd_range.Contains(range)) { + break; + } + found = it; + } + + return found; +} + +static bool GetFrameDataProgram(PdbIndex &index, + const Variable::RangeList &ranges, + llvm::StringRef &out_program) { + const DebugFrameDataSubsectionRef &new_fpo_data = + index.dbi().getNewFpoRecords(); + + auto frame_data_it = + GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges); + if (frame_data_it == new_fpo_data.end()) + return false; + + PDBStringTable &strings = cantFail(index.pdb().getStringTable()); + out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); + return true; +} + +static RegisterId GetBaseFrameRegister(PdbIndex &index, + PdbCompilandSymId frame_proc_id, + bool is_parameter) { + CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); + lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC); + + FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); + cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, + frame_proc)); + + CPUType cpu_type = index.compilands() + .GetCompiland(frame_proc_id.modi) + ->m_compile_opts->Machine; + + return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type) + : frame_proc.getLocalFramePtrReg(cpu_type); +} + VariableInfo lldb_private::npdb::GetVariableLocationInfo( - PdbIndex &index, PdbCompilandSymId var_id, lldb::ModuleSP module) { + PdbIndex &index, PdbCompilandSymId var_id, Block &block, + lldb::ModuleSP module) { CVSymbol sym = index.ReadSymbolRecord(var_id); @@ -543,13 +614,69 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( SymbolRecordKind::DefRangeFramePointerRelSym); cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( loc_specifier_cvs, loc)); - // FIXME: The register needs to come from the S_FRAMEPROC symbol. - result.location = - MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module); - result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); - } else { - // FIXME: Handle other kinds + + Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); + + // TODO: may be better to pass function scope and not lookup it every + // time? find nearest parent function block + Block *cur = █ + while (cur->GetParent()) { + cur = cur->GetParent(); + } + PdbCompilandSymId func_scope_id = + PdbSymUid(cur->GetID()).asCompilandSym(); + CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id); + lldbassert(func_block_cvs.kind() == S_GPROC32 || + func_block_cvs.kind() == S_LPROC32); + + PdbCompilandSymId frame_proc_id( + func_scope_id.modi, func_scope_id.offset + func_block_cvs.length()); + + bool is_parameter = + ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); + RegisterId base_reg = + GetBaseFrameRegister(index, frame_proc_id, is_parameter); + + if (base_reg == RegisterId::VFRAME) { + llvm::StringRef program; + if (GetFrameDataProgram(index, ranges, program)) { + result.location = + MakeVFrameRelLocationExpression(program, loc.Offset, module); + result.ranges = std::move(ranges); + } else { + // invalid variable + } + } else { + result.location = + MakeRegRelLocationExpression(base_reg, loc.Offset, module); + result.ranges = std::move(ranges); + } + } else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) { + DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); + cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( + loc_specifier_cvs, loc)); + + Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); + + RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; + + if (base_reg == RegisterId::VFRAME) { + llvm::StringRef program; + if (GetFrameDataProgram(index, ranges, program)) { + result.location = MakeVFrameRelLocationExpression( + program, loc.Hdr.BasePointerOffset, module); + result.ranges = std::move(ranges); + } else { + // invalid variable + } + } else { + result.location = MakeRegRelLocationExpression( + base_reg, loc.Hdr.BasePointerOffset, module); + result.ranges = std::move(ranges); + } } + + // FIXME: Handle other kinds return result; } llvm_unreachable("Symbol is not a local variable!"); diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 570c300b6a2b..6f675b56dca4 100644 --- a/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -1,9 +1,8 @@ //===-- PdbUtil.h -----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -142,7 +141,7 @@ LookThroughModifierRecord(llvm::codeview::CVType modifier); llvm::StringRef DropNameScope(llvm::StringRef name); VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); -VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, +VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block& block, lldb::ModuleSP module); size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 7e97e2b37724..e27d4699ae2f 100644 --- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1,9 +1,8 @@ //===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -74,6 +73,8 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeC_plus_plus; case PDB_Lang::C: return lldb::LanguageType::eLanguageTypeC; + case PDB_Lang::Swift: + return lldb::LanguageType::eLanguageTypeSwift; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -316,7 +317,7 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() { } void SymbolFileNativePDB::InitializeObject() { - m_obj_load_address = m_obj_file->GetFileOffset(); + m_obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress(); m_index->SetLoadAddress(m_obj_load_address); m_index->ParseSectionContribs(); @@ -594,6 +595,17 @@ TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, return array_sp; } + +TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id, + const MemberFunctionRecord &mfr, + CompilerType ct) { + Declaration decl; + return std::make_shared<lldb_private::Type>( + toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, ct, + lldb_private::Type::eResolveStateFull); +} + TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, const ProcedureRecord &pr, CompilerType ct) { @@ -654,6 +666,11 @@ TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); return CreateProcedureType(type_id, pr, ct); } + if (cvt.kind() == LF_MFUNCTION) { + MemberFunctionRecord mfr; + llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); + return CreateFunctionType(type_id, mfr, ct); + } return nullptr; } @@ -1137,7 +1154,7 @@ bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, } bool SymbolFileNativePDB::ParseImportedModules( - const SymbolContext &sc, std::vector<ConstString> &imported_modules) { + const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { // PDB does not yet support module debug info return false; } @@ -1151,7 +1168,7 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } uint32_t SymbolFileNativePDB::FindGlobalVariables( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables) { using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; @@ -1178,7 +1195,7 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables( } uint32_t SymbolFileNativePDB::FindFunctions( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { // For now we only support lookup by method name. @@ -1219,7 +1236,7 @@ uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, } uint32_t SymbolFileNativePDB::FindTypes( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) { if (!append) @@ -1316,7 +1333,9 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { ModuleSP module = GetObjectFile()->GetModule(); - VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module); + Block &block = GetOrCreateBlock(scope_id); + VariableInfo var_info = + GetVariableLocationInfo(*m_index, var_id, block, module); if (!var_info.location || !var_info.ranges) return nullptr; @@ -1549,7 +1568,7 @@ size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, } CompilerDeclContext -SymbolFileNativePDB::FindNamespace(const ConstString &name, +SymbolFileNativePDB::FindNamespace(ConstString name, const CompilerDeclContext *parent_decl_ctx) { return {}; } diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index dcf3fe365ef1..20daff219a0a 100644 --- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -1,9 +1,8 @@ //===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -45,9 +44,7 @@ class SymbolFileNativePDB : public SymbolFile { friend class UdtRecordCompleter; public: - //------------------------------------------------------------------ // Static Functions - //------------------------------------------------------------------ static void Initialize(); static void Terminate(); @@ -60,9 +57,7 @@ public: static SymbolFile *CreateInstance(ObjectFile *obj_file); - //------------------------------------------------------------------ // Constructors and Destructors - //------------------------------------------------------------------ SymbolFileNativePDB(ObjectFile *ofile); ~SymbolFileNativePDB() override; @@ -71,9 +66,7 @@ public: void InitializeObject() override; - //------------------------------------------------------------------ // Compile Unit function calls - //------------------------------------------------------------------ uint32_t GetNumCompileUnits() override; @@ -95,13 +88,13 @@ public: FileSpecList &support_files) override; size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; - bool - ParseImportedModules(const SymbolContext &sc, - std::vector<ConstString> &imported_modules) override; + bool ParseImportedModules( + const SymbolContext &sc, + std::vector<lldb_private::SourceModule> &imported_modules) override; size_t ParseBlocksRecursive(Function &func) override; - uint32_t FindGlobalVariables(const ConstString &name, + uint32_t FindGlobalVariables(ConstString name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables) override; @@ -130,7 +123,7 @@ public: size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override; - uint32_t FindFunctions(const ConstString &name, + uint32_t FindFunctions(ConstString name, const CompilerDeclContext *parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, bool append, @@ -139,7 +132,7 @@ public: uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, bool append, SymbolContextList &sc_list) override; - uint32_t FindTypes(const ConstString &name, + uint32_t FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, @@ -151,7 +144,7 @@ public: TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override; CompilerDeclContext - FindNamespace(const ConstString &name, + FindNamespace(ConstString name, const CompilerDeclContext *parent_decl_ctx) override; ConstString GetPluginName() override; @@ -187,6 +180,9 @@ private: lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, const llvm::codeview::ArrayRecord &ar, CompilerType ct); + lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id, + const llvm::codeview::MemberFunctionRecord &pr, + CompilerType ct); lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, const llvm::codeview::ProcedureRecord &pr, CompilerType ct); diff --git a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 239dfbee625d..3c494dc83986 100644 --- a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -50,7 +50,8 @@ UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, } clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( - llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access) { + llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access, + llvm::Optional<uint64_t> vtable_idx) { PdbTypeSymId type_id(ti); clang::QualType qt = m_ast_builder.GetOrCreateType(type_id); @@ -58,13 +59,32 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( std::unique_ptr<clang::CXXBaseSpecifier> base_spec = m_ast_builder.clang().CreateBaseClassSpecifier( - qt.getAsOpaquePtr(), TranslateMemberAccess(access), false, - udt_cvt.kind() == LF_CLASS); + qt.getAsOpaquePtr(), TranslateMemberAccess(access), + vtable_idx.hasValue(), udt_cvt.kind() == LF_CLASS); lldbassert(base_spec); - m_bases.push_back(std::move(base_spec)); + + m_bases.push_back( + std::make_pair(vtable_idx.getValueOr(0), std::move(base_spec))); + return qt; } +void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx, + MemberAccess access, MethodOptions options, + MemberAttributes attrs) { + clang::QualType method_qt = + m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx)); + m_ast_builder.CompleteType(method_qt); + + lldb::AccessType access_type = TranslateMemberAccess(access); + bool is_artificial = (options & MethodOptions::CompilerGenerated) == + MethodOptions::CompilerGenerated; + m_ast_builder.clang().AddMethodToCXXRecordType( + m_derived_ct.GetOpaqueQualType(), name.data(), nullptr, + m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(), + attrs.isStatic(), false, false, false, is_artificial); +} + Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, BaseClassRecord &base) { clang::QualType base_qt = @@ -82,9 +102,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, VirtualBaseClassRecord &base) { - AddBaseClassForTypeIndex(base.BaseType, base.getAccess()); + AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex); - // FIXME: Handle virtual base offsets. return Error::success(); } @@ -158,11 +177,27 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, OneMethodRecord &one_method) { + AddMethod(one_method.Name, one_method.Type, one_method.getAccess(), + one_method.getOptions(), one_method.Attrs); + return Error::success(); } Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, OverloadedMethodRecord &overloaded) { + TypeIndex method_list_idx = overloaded.MethodList; + + CVType method_list_type = m_tpi.getType(method_list_idx); + assert(method_list_type.kind() == LF_METHODLIST); + + MethodOverloadListRecord method_list; + llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>( + method_list_type, method_list)); + + for (const OneMethodRecord &method : method_list.Methods) + AddMethod(overloaded.Name, method.Type, method.getAccess(), + method.getOptions(), method.Attrs); + return Error::success(); } @@ -177,9 +212,19 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, } void UdtRecordCompleter::complete() { + // Ensure the correct order for virtual bases. + std::stable_sort(m_bases.begin(), m_bases.end(), + [](const IndexedBase &lhs, const IndexedBase &rhs) { + return lhs.first < rhs.first; + }); + + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; + bases.reserve(m_bases.size()); + for (auto &ib : m_bases) + bases.push_back(std::move(ib.second)); + ClangASTContext &clang = m_ast_builder.clang(); - clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), - std::move(m_bases)); + clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases)); clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType()); ClangASTContext::BuildIndirectFields(m_derived_ct); diff --git a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h index 469685126e59..55397582209b 100644 --- a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h +++ b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -1,9 +1,8 @@ -//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// +//===-- UdtRecordCompleter.h ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -36,6 +35,9 @@ namespace npdb { class PdbAstBuilder; class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { + using IndexedBase = + std::pair<uint64_t, std::unique_ptr<clang::CXXBaseSpecifier>>; + union UdtTagRecord { UdtTagRecord() {} llvm::codeview::UnionRecord ur; @@ -48,7 +50,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { clang::TagDecl &m_tag_decl; PdbAstBuilder &m_ast_builder; llvm::pdb::TpiStream &m_tpi; - std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> m_bases; + std::vector<IndexedBase> m_bases; ClangASTImporter::LayoutInfo m_layout; public: @@ -65,8 +67,13 @@ public: void complete(); private: - clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti, - llvm::codeview::MemberAccess access); + clang::QualType AddBaseClassForTypeIndex( + llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access, + llvm::Optional<uint64_t> vtable_idx = llvm::Optional<uint64_t>()); + void AddMethod(llvm::StringRef name, llvm::codeview::TypeIndex type_idx, + llvm::codeview::MemberAccess access, + llvm::codeview::MethodOptions options, + llvm::codeview::MemberAttributes attrs); }; } // namespace npdb |
