[Lldb-commits] [lldb] r364216 - [ABI] Implement Windows ABI for x86_64
Alex Langford via lldb-commits
lldb-commits at lists.llvm.org
Mon Jun 24 11:21:05 PDT 2019
Author: xiaobai
Date: Mon Jun 24 11:21:05 2019
New Revision: 364216
URL: http://llvm.org/viewvc/llvm-project?rev=364216&view=rev
Log:
[ABI] Implement Windows ABI for x86_64
Summary:
Implement the ABI for WIndows-x86_64 including register info and calling convention.
Handled nested struct returned in register (SysV doesn't have it supported)
Reviewers: xiaobai, compnerd
Reviewed By: compnerd
Subscribers: labath, jasonmolenda, fedor.sergeev, mgorny, teemperor, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D62213
Added:
lldb/trunk/source/Plugins/ABI/Windows-x86_64/
lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
lldb/trunk/source/Plugins/ABI/Windows-x86_64/CMakeLists.txt
Modified:
lldb/trunk/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py
lldb/trunk/source/API/SystemInitializerFull.cpp
lldb/trunk/source/Plugins/ABI/CMakeLists.txt
lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/lldbutil/iter/TestRegistersIterator.py Mon Jun 24 11:21:05 2019
@@ -26,7 +26,6 @@ class RegistersIteratorTestCase(TestBase
'main.cpp', '// Set break point at this line.')
@add_test_categories(['pyapi'])
- @expectedFailureAll(oslist=["windows"])
def test_iter_registers(self):
"""Test iterator works correctly for lldbutil.iter_registers()."""
self.build()
Modified: lldb/trunk/source/API/SystemInitializerFull.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SystemInitializerFull.cpp?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/source/API/SystemInitializerFull.cpp (original)
+++ lldb/trunk/source/API/SystemInitializerFull.cpp Mon Jun 24 11:21:05 2019
@@ -34,6 +34,7 @@
#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
+#include "Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h"
#include "Plugins/Architecture/Arm/ArchitectureArm.h"
#include "Plugins/Architecture/Mips/ArchitectureMips.h"
#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h"
@@ -186,6 +187,7 @@ llvm::Error SystemInitializerFull::Initi
ABISysV_mips::Initialize();
ABISysV_mips64::Initialize();
ABISysV_s390x::Initialize();
+ ABIWindows_x86_64::Initialize();
ArchitectureArm::Initialize();
ArchitectureMips::Initialize();
@@ -299,6 +301,7 @@ void SystemInitializerFull::Terminate()
ABISysV_mips::Terminate();
ABISysV_mips64::Terminate();
ABISysV_s390x::Terminate();
+ ABIWindows_x86_64::Terminate();
DisassemblerLLVMC::Terminate();
JITLoaderGDB::Terminate();
Modified: lldb/trunk/source/Plugins/ABI/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/CMakeLists.txt?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/ABI/CMakeLists.txt Mon Jun 24 11:21:05 2019
@@ -11,3 +11,4 @@ add_subdirectory(SysV-x86_64)
add_subdirectory(MacOSX-i386)
add_subdirectory(MacOSX-arm)
add_subdirectory(MacOSX-arm64)
+add_subdirectory(Windows-x86_64)
Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Mon Jun 24 11:21:05 2019
@@ -220,8 +220,19 @@ size_t ABISysV_x86_64::GetRedZoneSize()
ABISP
ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
- return ABISP(new ABISysV_x86_64(process_sp));
+ const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
+ const llvm::Triple::OSType os_type = arch.GetTriple().getOS();
+ if (arch_type == llvm::Triple::x86_64) {
+ switch(os_type) {
+ case llvm::Triple::OSType::MacOSX:
+ case llvm::Triple::OSType::Linux:
+ case llvm::Triple::OSType::FreeBSD:
+ case llvm::Triple::OSType::Solaris:
+ case llvm::Triple::OSType::UnknownOS:
+ return ABISP(new ABISysV_x86_64(process_sp));
+ default:
+ return ABISP();
+ }
}
return ABISP();
}
Added: lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp?rev=364216&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp (added)
+++ lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp Mon Jun 24 11:21:05 2019
@@ -0,0 +1,1809 @@
+//===-- ABIWindows_x86_64.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 "ABIWindows_x86_64.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum dwarf_regnums {
+ dwarf_rax = 0,
+ dwarf_rdx,
+ dwarf_rcx,
+ dwarf_rbx,
+ dwarf_rsi,
+ dwarf_rdi,
+ dwarf_rbp,
+ dwarf_rsp,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_rip,
+ dwarf_xmm0,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_xmm8,
+ dwarf_xmm9,
+ dwarf_xmm10,
+ dwarf_xmm11,
+ dwarf_xmm12,
+ dwarf_xmm13,
+ dwarf_xmm14,
+ dwarf_xmm15,
+ dwarf_stmm0,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_ymm0,
+ dwarf_ymm1,
+ dwarf_ymm2,
+ dwarf_ymm3,
+ dwarf_ymm4,
+ dwarf_ymm5,
+ dwarf_ymm6,
+ dwarf_ymm7,
+ dwarf_ymm8,
+ dwarf_ymm9,
+ dwarf_ymm10,
+ dwarf_ymm11,
+ dwarf_ymm12,
+ dwarf_ymm13,
+ dwarf_ymm14,
+ dwarf_ymm15,
+ dwarf_bnd0 = 126,
+ dwarf_bnd1,
+ dwarf_bnd2,
+ dwarf_bnd3
+};
+
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGIN
+ // LLDB NATIVE
+ // ======== ======= == === ============= ===================
+ // ======================= =====================
+ // =========================== ===================== ======================
+ {"rax",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rbx",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rcx",
+ "arg1",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rdx",
+ "arg2",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rsi",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rsi, dwarf_rsi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rdi",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rdi, dwarf_rdi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rbp",
+ "fp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rsp",
+ "sp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ "arg3",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ "arg4",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rip",
+ "pc",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rflags",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ss",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ds",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"es",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"gs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm0",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm1",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm2",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm3",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm4",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm5",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm6",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm7",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fctrl",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fstat",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ftag",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fiseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fioff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"foseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fooff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fop",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm4",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm5",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm6",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm7",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm8",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm9",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm10",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm11",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm12",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm13",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm14",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm15",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"mxcsr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm0",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm1",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm2",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm3",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm4",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm5",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm6",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm7",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm8",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm9",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm10",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm11",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm12",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm13",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm14",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm15",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bndcfgu",
+ nullptr,
+ 8,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bndstatus",
+ nullptr,
+ 8,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
+static bool g_register_info_names_constified = false;
+
+const lldb_private::RegisterInfo *
+ABIWindows_x86_64::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
+ }
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
+}
+
+bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) {
+ name = "rax";
+ return true;
+}
+
+size_t ABIWindows_x86_64::GetRedZoneSize() const { return 0; }
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP
+ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
+ arch.GetTriple().isOSWindows()) {
+ return ABISP(new ABIWindows_x86_64(process_sp));
+ }
+ return ABISP();
+}
+
+bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ StreamString s;
+ s.Printf("ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
+ args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ const RegisterInfo *reg_info = nullptr;
+
+ if (args.size() > 4) // Windows x64 only put first 4 arguments into registers
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
+ if (log)
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // First, align the SP
+
+ if (log)
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+
+ sp &= ~(0xfull); // 16-byte alignment
+
+ sp -= 8; // return address
+
+ Status error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ ProcessSP process_sp(thread.GetProcess());
+
+ RegisterValue reg_value;
+ if (log)
+ log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
+
+ // Save return address onto the stack
+ if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+ return false;
+
+ // %rsp is set to the actual stack value.
+
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
+
+ // %rip is set to the address of the called function.
+
+ if (log)
+ log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
+
+ return true;
+}
+
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids,
+ unsigned int ¤t_argument_register,
+ addr_t ¤t_stack_argument) {
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 4) { // Windows pass first 4 arguments to register
+ scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ return true;
+ }
+ uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
+ Status error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(
+ current_stack_argument, byte_size, is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
+ return true;
+ }
+ return false;
+}
+
+bool ABIWindows_x86_64::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ addr_t sp = reg_ctx->GetSP(0);
+
+ if (!sp)
+ return false;
+
+ addr_t current_stack_argument = sp + 8; // jump over return address
+
+ uint32_t argument_register_ids[4];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
+ ->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ CompilerType compiler_type = value->GetCompilerType();
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
+ bool is_signed;
+
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
+ } else if (compiler_type.IsPointerType()) {
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
+ }
+ }
+
+ return true;
+}
+
+Status ABIWindows_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Status error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
+
+ DataExtractor data;
+ Status data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
+ }
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ error.SetErrorString(
+ "We don't support returning complex values at present");
+ else {
+ llvm::Optional<uint64_t> bit_width =
+ compiler_type.GetBitSize(frame_sp.get());
+ if (!bit_width) {
+ error.SetErrorString("can't get type size");
+ return error;
+ }
+ if (*bit_width <= 64) {
+ const RegisterInfo *xmm0_info =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ DataExtractor data;
+ Status data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ unsigned char buffer[16];
+ ByteOrder byte_order = data.GetByteOrder();
+
+ data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
+ xmm0_value.SetBytes(buffer, 16, byte_order);
+ reg_ctx->WriteRegister(xmm0_info, xmm0_value);
+ set_it_simple = true;
+ } else {
+ // Windows doesn't support 80 bit FP
+ error.SetErrorString(
+ "Windows-x86_64 doesn't allow FP larger than 64 bits.");
+ }
+ }
+ }
+
+ if (!set_it_simple) {
+ // Okay we've got a structure or something that doesn't fit in a simple
+ // register.
+ // TODO(wanyi): On Windows, if the return type is a struct:
+ // 1) smaller that 64 bits and return by value -> RAX
+ // 2) bigger than 64 bits, the caller will allocate memory for that struct
+ // and pass the struct pointer in RCX then return the pointer in RAX
+ error.SetErrorString("We only support setting simple integer and float "
+ "return types at present.");
+ }
+
+ return error;
+}
+
+ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger) {
+ // Extract the register context so we can read arguments from registers
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("rax", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (*byte_size) {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size <= sizeof(long double)) {
+ const RegisterInfo *xmm0_info =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
+ DataExtractor data;
+ if (xmm0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (*byte_size == sizeof(float)) {
+ value.GetScalar() = (float)data.GetFloat(&offset);
+ success = true;
+ } else if (*byte_size == sizeof(double)) {
+ // double and long double are the same on windows
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if ((type_flags & eTypeIsPointer) ||
+ (type_flags & eTypeInstanceIsPointer)) {
+ unsigned rax_id =
+ reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
+ 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size > 0) {
+ const RegisterInfo *xmm_reg =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ if (xmm_reg == nullptr)
+ xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+
+ if (xmm_reg) {
+ if (*byte_size <= xmm_reg->byte_size) {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
+ Status error;
+ if (reg_value.GetAsMemoryData(
+ xmm_reg, heap_data_up->GetBytes(),
+ heap_data_up->GetByteSize(), byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_up.release()),
+ byte_order,
+ process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return return_valobj_sp;
+}
+
+// The compiler will flatten the nested aggregate type into single
+// layer and push the value to stack
+// This helper function will flatten an aggregate type
+// and return true if it can be returned in register(s) by value
+// return false if the aggregate is in memory
+static bool FlattenAggregateType(
+ Thread &thread, ExecutionContext &exe_ctx,
+ CompilerType &return_compiler_type,
+ uint32_t data_byte_offset,
+ std::vector<uint32_t> &aggregate_field_offsets,
+ std::vector<CompilerType> &aggregate_compiler_types) {
+
+ const uint32_t num_children = return_compiler_type.GetNumFields();
+ for (uint32_t idx = 0; idx < num_children; ++idx) {
+ std::string name;
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ uint64_t field_bit_offset = 0;
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
+ idx, name, &field_bit_offset, nullptr, nullptr);
+ llvm::Optional<uint64_t> field_bit_width =
+ field_compiler_type.GetBitSize(&thread);
+
+ // if we don't know the size of the field (e.g. invalid type), exit
+ if (!field_bit_width || *field_bit_width == 0) {
+ return false;
+ }
+ // If there are any unaligned fields, this is stored in memory.
+ if (field_bit_offset % *field_bit_width != 0) {
+ return false;
+ }
+
+ // add overall offset
+ uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
+
+ const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType() ||
+ field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ aggregate_field_offsets.push_back(field_byte_offset);
+ aggregate_compiler_types.push_back(field_compiler_type);
+ } else if (field_type_flags & eTypeHasChildren) {
+ if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
+ field_byte_offset, aggregate_field_offsets,
+ aggregate_compiler_types)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+
+ if (!return_compiler_type) {
+ return return_valobj_sp;
+ }
+
+ // try extract value as if it's a simple type
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp) {
+ return return_valobj_sp;
+ }
+
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp) {
+ return return_valobj_sp;
+ }
+
+ llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
+ if (!bit_width) {
+ return return_valobj_sp;
+ }
+
+ // if it's not simple or aggregate type, then we don't know how to handle it
+ if (!return_compiler_type.IsAggregateType()) {
+ return return_valobj_sp;
+ }
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ uint32_t max_register_value_bit_width = 64;
+
+ // The scenario here is to have a struct/class which is POD
+ // if the return struct/class size is larger than 64 bits,
+ // the caller will allocate memory for it and pass the return addr in RCX
+ // then return the address in RAX
+
+ // if the struct is returned by value in register (RAX)
+ // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
+ // for floating point, the return value will be copied over to RAX
+ bool is_memory = *bit_width > max_register_value_bit_width ||
+ *bit_width & (*bit_width - 1);
+ std::vector<uint32_t> aggregate_field_offsets;
+ std::vector<CompilerType> aggregate_compiler_types;
+ if (!is_memory &&
+ FlattenAggregateType(thread, exe_ctx, return_compiler_type,
+ 0, aggregate_field_offsets,
+ aggregate_compiler_types)) {
+ ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
+ DataBufferSP data_sp(
+ new DataBufferHeap(max_register_value_bit_width / 8, 0));
+ DataExtractor return_ext(data_sp, byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ // The only register used to return struct/class by value
+ const RegisterInfo *rax_info =
+ reg_ctx_sp->GetRegisterInfoByName("rax", 0);
+ RegisterValue rax_value;
+ reg_ctx_sp->ReadRegister(rax_info, rax_value);
+ DataExtractor rax_data;
+ rax_value.GetData(rax_data);
+
+ uint32_t used_bytes =
+ 0; // Tracks how much of the rax registers we've consumed so far
+
+ // in case of the returned type is a subclass of non-abstract-base class
+ // it will have a padding to skip the base content
+ if (aggregate_field_offsets.size())
+ used_bytes = aggregate_field_offsets[0];
+
+ const uint32_t num_children = aggregate_compiler_types.size();
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ bool is_signed;
+ bool is_complex;
+ uint32_t count;
+
+ CompilerType field_compiler_type = aggregate_compiler_types[idx];
+ uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
+ uint32_t field_byte_offset = aggregate_field_offsets[idx];
+
+ uint32_t field_bit_width = field_byte_width * 8;
+
+ // this is unlikely w/o the overall size being greater than 8 bytes
+ // For now, return a nullptr return value object.
+ if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
+ return return_valobj_sp;
+ }
+
+ DataExtractor *copy_from_extractor = nullptr;
+ uint32_t copy_from_offset = 0;
+ const uint32_t field_byte_flags = field_compiler_type.GetTypeInfo();
+
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType() ||
+ field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ copy_from_extractor = &rax_data;
+ copy_from_offset = used_bytes;
+ used_bytes += field_byte_width;
+ }
+ // These two tests are just sanity checks. If I somehow get the type
+ // calculation wrong above it is better to just return nothing than to
+ // assert or crash.
+ if (!copy_from_extractor) {
+ return return_valobj_sp;
+ }
+ if (copy_from_offset + field_byte_width >
+ copy_from_extractor->GetByteSize()) {
+ return return_valobj_sp;
+ }
+ copy_from_extractor->CopyByteOrderedData(copy_from_offset,
+ field_byte_width, data_sp->GetBytes() + field_byte_offset,
+ field_byte_width, byte_order);
+ }
+ if (!is_memory) {
+ // The result is in our data buffer. Let's make a variable object out
+ // of it:
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ }
+ }
+
+ // The Windows x86_64 ABI specifies that the return address for MEMORY
+ // objects be placed in rax on exit from the function.
+
+ // FIXME: This is just taking a guess, rax may very well no longer hold the
+ // return storage location.
+ // If we are going to do this right, when we make a new frame we should
+ // check to see if it uses a memory return, and if we are at the first
+ // instruction and if so stash away the return location. Then we would
+ // only return the memory return value if we know it is valid.
+ if (is_memory) {
+ unsigned rax_id =
+ reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
+ 0);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+ return return_valobj_sp;
+}
+
+// This defines the CFA as rsp+8
+// the saved pc is at CFA-8 (i.e. rsp+0)
+// The saved rsp is CFA+0
+
+bool ABIWindows_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t sp_reg_num = dwarf_rsp;
+ uint32_t pc_reg_num = dwarf_rip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("x86_64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
+}
+
+// Windows-x86_64 doesn't use %rbp
+// No available Unwind information for Windows-x86_64 (section .pdata)
+// Let's use SysV-x86_64 one for now
+bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = dwarf_rbp;
+ uint32_t sp_reg_num = dwarf_rsp;
+ uint32_t pc_reg_num = dwarf_rip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ const int32_t ptr_size = 8;
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("x86_64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABIWindows_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
+}
+
+bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (!reg_info)
+ return false;
+ assert(reg_info->name != nullptr && "unnamed register?");
+ std::string Name = std::string(reg_info->name);
+ bool IsCalleeSaved =
+ llvm::StringSwitch<bool>(Name)
+ .Cases("rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi", true)
+ .Cases("rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp", true)
+ .Cases("xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
+ "xmm13", "xmm14", "xmm15", true)
+ .Default(false);
+ return IsCalleeSaved;
+}
+
+void ABIWindows_x86_64::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
+}
+
+void ABIWindows_x86_64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString ABIWindows_x86_64::GetPluginNameStatic() {
+ static ConstString g_name("windows-x86_64");
+ return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+lldb_private::ConstString ABIWindows_x86_64::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ABIWindows_x86_64::GetPluginVersion() { return 1; }
Added: lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h?rev=364216&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h (added)
+++ lldb/trunk/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h Mon Jun 24 11:21:05 2019
@@ -0,0 +1,99 @@
+//===-- ABIWindows_x86_64.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 liblldb_ABIWindows_x86_64_h_
+#define liblldb_ABIWindows_x86_64_h_
+
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABIWindows_x86_64 : public lldb_private::ABI {
+public:
+ ~ABIWindows_x86_64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Status
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // In Windows_x86_64 ABI, stack will always be maintained 16-byte aligned
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ if (cfa & (16ull - 1ull))
+ return false; // Not 16 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // We have a 64 bit address space, so anything is valid as opcodes
+ // aren't fixed width...
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ bool GetPointerReturnRegister(const char *&name) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+protected:
+ void CreateRegisterMapIfNeeded();
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
+
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+
+private:
+ ABIWindows_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ // Call CreateInstance instead.
+ }
+};
+
+#endif // liblldb_ABISysV_x86_64_h_
Added: lldb/trunk/source/Plugins/ABI/Windows-x86_64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/Windows-x86_64/CMakeLists.txt?rev=364216&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/Windows-x86_64/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/ABI/Windows-x86_64/CMakeLists.txt Mon Jun 24 11:21:05 2019
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginABIWindows_x86_64 PLUGIN
+ ABIWindows_x86_64.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ LINK_COMPONENTS
+ Support
+ )
Modified: lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp Mon Jun 24 11:21:05 2019
@@ -21,7 +21,7 @@
using namespace lldb;
using namespace lldb_private;
-const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
+const DWORD kWinContextFlags = CONTEXT_ALL;
// Constructors and Destructors
RegisterContextWindows::RegisterContextWindows(Thread &thread,
@@ -114,8 +114,18 @@ bool RegisterContextWindows::CacheAllReg
return true;
TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- memset(&m_context, 0, sizeof(m_context));
- m_context.ContextFlags = kWinContextFlags;
+ uint8_t buffer[2048];
+ memset(buffer, 0, sizeof(buffer));
+ PCONTEXT tmpContext = NULL;
+ DWORD contextLength = (DWORD)sizeof(buffer);
+ if (!::InitializeContext(buffer, kWinContextFlags, &tmpContext,
+ &contextLength)) {
+ return false;
+ }
+ memcpy(&m_context, tmpContext, sizeof(m_context));
+ if (!::SuspendThread(wthread.GetHostThread().GetNativeThread().GetSystemHandle())) {
+ return false;
+ }
if (!::GetThreadContext(
wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
&m_context)) {
@@ -125,6 +135,9 @@ bool RegisterContextWindows::CacheAllReg
::GetLastError());
return false;
}
+ if (!::ResumeThread(wthread.GetHostThread().GetNativeThread().GetSystemHandle())) {
+ return false;
+ }
LLDB_LOG(log, "successfully updated the register values.");
m_context_stale = false;
return true;
Modified: lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp?rev=364216&r1=364215&r2=364216&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp Mon Jun 24 11:21:05 2019
@@ -24,6 +24,11 @@ using namespace lldb_private;
#define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
+#define DEFINE_FPU_XMM(reg) \
+ #reg, NULL, 16, 0, eEncodingUint, eFormatVectorOfUInt64, \
+ {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##reg##_x86_64}, \
+ nullptr, nullptr, nullptr, 0
namespace {
@@ -51,7 +56,24 @@ enum RegisterIndex {
eRegisterIndexR14,
eRegisterIndexR15,
eRegisterIndexRip,
- eRegisterIndexRflags
+ eRegisterIndexRflags,
+
+ eRegisterIndexXmm0,
+ eRegisterIndexXmm1,
+ eRegisterIndexXmm2,
+ eRegisterIndexXmm3,
+ eRegisterIndexXmm4,
+ eRegisterIndexXmm5,
+ eRegisterIndexXmm6,
+ eRegisterIndexXmm7,
+ eRegisterIndexXmm8,
+ eRegisterIndexXmm9,
+ eRegisterIndexXmm10,
+ eRegisterIndexXmm11,
+ eRegisterIndexXmm12,
+ eRegisterIndexXmm13,
+ eRegisterIndexXmm14,
+ eRegisterIndexXmm15
};
// Array of all register information supported by Windows x86
@@ -133,14 +155,14 @@ RegisterInfo g_register_infos[] = {
nullptr,
0},
{DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5,
+ {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, lldb_r10_x86_64},
nullptr,
nullptr,
nullptr,
0},
{DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6,
+ {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, lldb_r11_x86_64},
nullptr,
nullptr,
@@ -188,6 +210,22 @@ RegisterInfo g_register_infos[] = {
nullptr,
nullptr,
0},
+ {DEFINE_FPU_XMM(xmm0)},
+ {DEFINE_FPU_XMM(xmm1)},
+ {DEFINE_FPU_XMM(xmm2)},
+ {DEFINE_FPU_XMM(xmm3)},
+ {DEFINE_FPU_XMM(xmm4)},
+ {DEFINE_FPU_XMM(xmm5)},
+ {DEFINE_FPU_XMM(xmm6)},
+ {DEFINE_FPU_XMM(xmm7)},
+ {DEFINE_FPU_XMM(xmm8)},
+ {DEFINE_FPU_XMM(xmm9)},
+ {DEFINE_FPU_XMM(xmm10)},
+ {DEFINE_FPU_XMM(xmm11)},
+ {DEFINE_FPU_XMM(xmm12)},
+ {DEFINE_FPU_XMM(xmm13)},
+ {DEFINE_FPU_XMM(xmm14)},
+ {DEFINE_FPU_XMM(xmm15)}
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
@@ -202,10 +240,20 @@ uint32_t g_gpr_reg_indices[] = {
eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
+uint32_t g_fpu_reg_indices[] = {
+ eRegisterIndexXmm0, eRegisterIndexXmm1, eRegisterIndexXmm2,
+ eRegisterIndexXmm3, eRegisterIndexXmm4, eRegisterIndexXmm5,
+ eRegisterIndexXmm6, eRegisterIndexXmm7, eRegisterIndexXmm8,
+ eRegisterIndexXmm9, eRegisterIndexXmm10, eRegisterIndexXmm11,
+ eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14,
+ eRegisterIndexXmm15
+};
+
RegisterSet g_register_sets[] = {
{"General Purpose Registers", "gpr",
llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
-};
+ {"Floating Point Registers", "fpu",
+ llvm::array_lengthof(g_fpu_reg_indices), g_fpu_reg_indices}};
}
// Constructors and Destructors
@@ -242,7 +290,9 @@ bool RegisterContextWindows_x64::ReadReg
if (reg_info == nullptr)
return false;
- switch (reg_info->kinds[eRegisterKindLLDB]) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ switch (reg) {
case lldb_rax_x86_64:
reg_value.SetUInt64(m_context.Rax);
break;
@@ -297,6 +347,70 @@ bool RegisterContextWindows_x64::ReadReg
case lldb_rflags_x86_64:
reg_value.SetUInt64(m_context.EFlags);
break;
+ case lldb_xmm0_x86_64:
+ reg_value.SetBytes(&m_context.Xmm0,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm1_x86_64:
+ reg_value.SetBytes(&m_context.Xmm1,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm2_x86_64:
+ reg_value.SetBytes(&m_context.Xmm2,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm3_x86_64:
+ reg_value.SetBytes(&m_context.Xmm3,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm4_x86_64:
+ reg_value.SetBytes(&m_context.Xmm4,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm5_x86_64:
+ reg_value.SetBytes(&m_context.Xmm5,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm6_x86_64:
+ reg_value.SetBytes(&m_context.Xmm6,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm7_x86_64:
+ reg_value.SetBytes(&m_context.Xmm7,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm8_x86_64:
+ reg_value.SetBytes(&m_context.Xmm8,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm9_x86_64:
+ reg_value.SetBytes(&m_context.Xmm9,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm10_x86_64:
+ reg_value.SetBytes(&m_context.Xmm10,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm11_x86_64:
+ reg_value.SetBytes(&m_context.Xmm11,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm12_x86_64:
+ reg_value.SetBytes(&m_context.Xmm12,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm13_x86_64:
+ reg_value.SetBytes(&m_context.Xmm13,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm14_x86_64:
+ reg_value.SetBytes(&m_context.Xmm14,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm15_x86_64:
+ reg_value.SetBytes(&m_context.Xmm15,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
}
return true;
}
@@ -365,6 +479,54 @@ bool RegisterContextWindows_x64::WriteRe
case lldb_rflags_x86_64:
m_context.EFlags = reg_value.GetAsUInt64();
break;
+ case lldb_xmm0_x86_64:
+ memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm1_x86_64:
+ memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm2_x86_64:
+ memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm3_x86_64:
+ memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm4_x86_64:
+ memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm5_x86_64:
+ memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm6_x86_64:
+ memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm7_x86_64:
+ memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm8_x86_64:
+ memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm9_x86_64:
+ memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm10_x86_64:
+ memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm11_x86_64:
+ memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm12_x86_64:
+ memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm13_x86_64:
+ memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm14_x86_64:
+ memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16);
+ break;
+ case lldb_xmm15_x86_64:
+ memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16);
+ break;
}
// Physically update the registers in the target process.
More information about the lldb-commits
mailing list