diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Plugins/Process/Utility | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Plugins/Process/Utility')
128 files changed, 716 insertions, 4331 deletions
diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h index 1f7eb54d10e7c..fd3965fade191 100644 --- a/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ARMDefines_h_ -#define lldb_ARMDefines_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H #include "llvm/Support/ErrorHandling.h" @@ -188,4 +188,4 @@ static inline bool ARMConditionPassed(const uint32_t condition, } // namespace lldb_private -#endif // lldb_ARMDefines_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h index d860348818d33..bbe4c9a35fa6c 100644 --- a/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ARMUtils_h_ -#define lldb_ARMUtils_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H #include "ARMDefines.h" #include "InstructionUtils.h" @@ -371,4 +371,4 @@ static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; } } // namespace lldb_private -#endif // lldb_ARMUtils_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp index 25a1d0b5af060..685d9d0824f64 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -1,4 +1,4 @@ -//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===// +//===-- AuxVector.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h index c16be68aedb18..c8c8b12494131 100644 --- a/lldb/source/Plugins/Process/Utility/AuxVector.h +++ b/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AuxVector_H_ -#define liblldb_AuxVector_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index a86880af22600..443638aa39f66 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===// +//===-- DynamicRegisterInfo.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -742,6 +742,8 @@ const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo( for (auto ®_info : m_regs) { // We can use pointer comparison since we used a ConstString to set the // "name" member in AddRegister() + assert(ConstString(reg_info.name).GetCString() == reg_info.name && + "reg_info.name not from a ConstString?"); if (reg_info.name == reg_name.GetCString()) { return ®_info; } diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index aacf547e187d6..48939375a5040 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_DynamicRegisterInfo_h_ -#define lldb_DynamicRegisterInfo_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H #include <map> #include <vector> @@ -90,4 +90,4 @@ protected: // all registers bool m_finalized = false; }; -#endif // lldb_DynamicRegisterInfo_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H diff --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp index 9f63a594e054e..0a4bdc72b364e 100644 --- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -1,4 +1,4 @@ -//===-- FreeBSDSignals.cpp --------------------------------------*- C++ -*-===// +//===-- FreeBSDSignals.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h index 75462f3c76ffb..c4c810e549854 100644 --- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FreeBSDSignals_H_ -#define liblldb_FreeBSDSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_FreeBSDSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp index ed35273ce3fee..427225c14d3bb 100644 --- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===// +//===-- GDBRemoteSignals.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h index a02dd0604e67e..d37757ab60a52 100644 --- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteSignals_H_ -#define liblldb_GDBRemoteSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -26,4 +26,4 @@ private: } // namespace lldb_private -#endif // liblldb_GDBRemoteSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H diff --git a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index 295c17e474fba..d73b132539f19 100644 --- a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -1,4 +1,4 @@ -//===-- HistoryThread.cpp ---------------------------------------*- C++ -*-===// +//===-- HistoryThread.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,12 +25,14 @@ using namespace lldb_private; // Constructor HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, - std::vector<lldb::addr_t> pcs) + std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses) : Thread(process, tid, true), m_framelist_mutex(), m_framelist(), m_pcs(pcs), m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(), m_thread_name(), m_originating_unique_thread_id(tid), m_queue_id(LLDB_INVALID_QUEUE_ID) { - m_unwinder_up.reset(new HistoryUnwind(*this, pcs)); + m_unwinder_up = + std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this)); } diff --git a/lldb/source/Plugins/Process/Utility/HistoryThread.h b/lldb/source/Plugins/Process/Utility/HistoryThread.h index 1e26586401724..a66e0f2d4207c 100644 --- a/lldb/source/Plugins/Process/Utility/HistoryThread.h +++ b/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_HistoryThread_h_ -#define liblldb_HistoryThread_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H #include <mutex> @@ -33,7 +33,8 @@ namespace lldb_private { class HistoryThread : public lldb_private::Thread { public: HistoryThread(lldb_private::Process &process, lldb::tid_t tid, - std::vector<lldb::addr_t> pcs); + std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses = false); ~HistoryThread() override; @@ -88,4 +89,4 @@ protected: } // namespace lldb_private -#endif // liblldb_HistoryThread_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp index 83fdb011f5a1a..9b9522955de94 100644 --- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp +++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -1,4 +1,4 @@ -//===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===// +//===-- HistoryUnwind.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,8 +23,10 @@ using namespace lldb_private; // Constructor -HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs) - : Unwind(thread), m_pcs(pcs) {} +HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses) + : Unwind(thread), m_pcs(pcs), + m_pcs_are_call_addresses(pcs_are_call_addresses) {} // Destructor @@ -59,7 +61,10 @@ bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, if (frame_idx < m_pcs.size()) { cfa = frame_idx; pc = m_pcs[frame_idx]; - behaves_like_zeroth_frame = (frame_idx == 0); + if (m_pcs_are_call_addresses) + behaves_like_zeroth_frame = true; + else + behaves_like_zeroth_frame = (frame_idx == 0); return true; } return false; diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h index 4d16608bd8c27..cb72b5d0a1764 100644 --- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_HistoryUnwind_h_ -#define liblldb_HistoryUnwind_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H #include <vector> @@ -18,7 +18,8 @@ namespace lldb_private { class HistoryUnwind : public lldb_private::Unwind { public: - HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs); + HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, + bool pcs_are_call_addresses = false); ~HistoryUnwind() override; @@ -35,8 +36,11 @@ protected: private: std::vector<lldb::addr_t> m_pcs; + /// This boolean indicates that the PCs in the non-0 frames are call + /// addresses and not return addresses. + bool m_pcs_are_call_addresses; }; } // namespace lldb_private -#endif // liblldb_HistoryUnwind_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index ee939b01d3509..0f331933f2ea2 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -1,4 +1,4 @@ -//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// +//===-- InferiorCallPOSIX.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h index 2008c5fe0b912..3623e10194f98 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_InferiorCallPOSIX_h_ -#define lldb_InferiorCallPOSIX_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H // Inferior execution of POSIX functions. @@ -32,4 +32,4 @@ bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length); } // namespace lldb_private -#endif // lldb_InferiorCallPOSIX_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H diff --git a/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/lldb/source/Plugins/Process/Utility/InstructionUtils.h index f74933e691eeb..55b89440700b8 100644 --- a/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ b/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_InstructionUtils_h_ -#define lldb_InstructionUtils_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H #include <cassert> #include <cstdint> @@ -113,4 +113,4 @@ static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit, } // namespace lldb_private -#endif // lldb_InstructionUtils_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H diff --git a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp index 1ba432aa542bf..0c7d9ddc5ac6b 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -1,4 +1,4 @@ -//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===// +//===-- LinuxProcMaps.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h index e1f0e48ac5c95..363f248fd416e 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h +++ b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LinuxProcMaps_H_ -#define liblldb_LinuxProcMaps_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" @@ -24,4 +24,4 @@ void ParseLinuxMapRegions(llvm::StringRef linux_map, } // namespace lldb_private -#endif // liblldb_LinuxProcMaps_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index bef47cd263071..4dd619e3bade8 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -1,4 +1,4 @@ -//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===// +//===-- LinuxSignals.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.h b/lldb/source/Plugins/Process/Utility/LinuxSignals.h index 7ad8cfcbef683..32c4744a96d04 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.h +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LinuxSignals_H_ -#define liblldb_LinuxSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_LinuxSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index d8e5426ab5a5b..8f75844277c0e 100644 --- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -1,5 +1,4 @@ -//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++ -//-*-===// +//===-- MipsLinuxSignals.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h index b5e3ed86f568c..6b78fc72a91c6 100644 --- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MipsLinuxSignals_H_ -#define liblldb_MipsLinuxSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -25,4 +25,4 @@ private: } // namespace lldb_private -#endif // liblldb_MipsLinuxSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp index be61cfdd73745..3a875f7bb39be 100644 --- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextRegisterInfo.cpp -------------------*- C++ -*-===// +//===-- NativeRegisterContextRegisterInfo.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h index b285c477cd963..0e96841fd9091 100644 --- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h +++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO -#define LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H #include <memory> @@ -33,7 +33,7 @@ public: const RegisterInfoInterface &GetRegisterInfoInterface() const; -private: +protected: std::unique_ptr<RegisterInfoInterface> m_register_info_interface_up; }; } diff --git a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp index 29967deb7e9b4..ffdfd19b4efe2 100644 --- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -1,4 +1,4 @@ -//===-- NetBSDSignals.cpp --------------------------------------*- C++ -*-===// +//===-- NetBSDSignals.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/lldb/source/Plugins/Process/Utility/NetBSDSignals.h index bf7399a890603..e6740a304a024 100644 --- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.h +++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NetBSDSignals_H_ -#define liblldb_NetBSDSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_NetBSDSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h index ef40162984f12..21582df91fb03 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_REGISTERCONTEXTDARWINCONSTANTS_H -#define LLDB_REGISTERCONTEXTDARWINCONSTANTS_H +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H namespace lldb_private { @@ -22,4 +22,4 @@ namespace lldb_private { } // namespace lldb_private -#endif // LLDB_REGISTERCONTEXTDARWINCONSTANTS_H +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 173e669041517..eef4541e7edd7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_arm.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index d7c1809a32228..1bd60f7564873 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_arm_h_ -#define liblldb_RegisterContextDarwin_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -261,4 +261,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index fa5197cd6bf44..9fc275276699a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -//-*-===// +//===-- RegisterContextDarwin_arm64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index abb87e3c23483..010e566be32c7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_arm64_h_ -#define liblldb_RegisterContextDarwin_arm64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -228,4 +228,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 959b04700b176..c5ebddc56b6c9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_i386.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index e52f0fe63250c..9c759c31caed9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_i386_h_ -#define liblldb_RegisterContextDarwin_i386_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -205,4 +205,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_i386_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 22088a7d6448e..38cd00aea9cc8 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_x86_64.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index 1a65a4f28b339..d9ba8d0b23191 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_x86_64_h_ -#define liblldb_RegisterContextDarwin_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -210,4 +210,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index 6832b6095931b..4c2e291c62d6e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextDummy.cpp ---------------------------------*- C++ -//-*-===// +//===-- RegisterContextDummy.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h index bdaa2217d2077..de98767693fe1 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextDummy_h_ -#define lldb_RegisterContextDummy_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H #include <vector> @@ -56,9 +56,10 @@ private: lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only) lldb_private::RegisterInfo m_pc_reg_info; - DISALLOW_COPY_AND_ASSIGN(RegisterContextDummy); + RegisterContextDummy(const RegisterContextDummy &) = delete; + const RegisterContextDummy &operator=(const RegisterContextDummy &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextDummy_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp index b90b381082672..10d346a3cb7e1 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_i386.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h index 7aadf3a0a4c9f..5a3e5b0551d64 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_i386_H_ -#define liblldb_RegisterContextFreeBSD_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp index 4331ef5ad14ec..0c5d34f345db0 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_mips64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_mips64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h index 96f02b4440c56..39968eacf4755 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_mips64_H_ -#define liblldb_RegisterContextFreeBSD_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp index 4f869eb3b1771..9fe6255d698ed 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_powerpc.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h index ba2751194d168..7e4c43ba908a7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_powerpc_h_ -#define liblldb_RegisterContextFreeBSD_powerpc_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H #include "RegisterInfoInterface.h" @@ -49,4 +49,4 @@ public: uint32_t GetRegisterCount() const override; }; -#endif // liblldb_RegisterContextFreeBSD_powerpc_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp index bcf3951ee0775..c1f390ade9b91 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_x86_64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h index c379e1a5cd75f..d0f69fde18175 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_x86_64_H_ -#define liblldb_RegisterContextFreeBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index c19a2bfae668a..5779587389009 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextHistory.cpp ---------------------------------*- C++ -//-*-===// +//===-- RegisterContextHistory.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h index 952e4263d9559..407640d2bdb9e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextHistory_h_ -#define lldb_RegisterContextHistory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H #include <vector> @@ -58,8 +58,10 @@ private: lldb::addr_t m_pc_value; - DISALLOW_COPY_AND_ASSIGN(RegisterContextHistory); + RegisterContextHistory(const RegisterContextHistory &) = delete; + const RegisterContextHistory & + operator=(const RegisterContextHistory &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextHistory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp deleted file mode 100644 index 49a589f14989d..0000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ /dev/null @@ -1,2198 +0,0 @@ -//===-- RegisterContextLLDB.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 "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/Value.h" -#include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/ArmUnwindInfo.h" -#include "lldb/Symbol/CallFrameInfo.h" -#include "lldb/Symbol/DWARFCallFrameInfo.h" -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Target/ABI.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Platform.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/RegisterValue.h" -#include "lldb/lldb-private.h" - -#include "RegisterContextLLDB.h" - -#include <memory> - -using namespace lldb; -using namespace lldb_private; - -static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) { - if (sym_ctx.symbol) - return sym_ctx.symbol->GetName(); - else if (sym_ctx.function) - return sym_ctx.function->GetName(); - return ConstString(); -} - -RegisterContextLLDB::RegisterContextLLDB(Thread &thread, - const SharedPtr &next_frame, - SymbolContext &sym_ctx, - uint32_t frame_number, - UnwindLLDB &unwind_lldb) - : RegisterContext(thread, frame_number), m_thread(thread), - m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(), - m_fallback_unwind_plan_sp(), m_all_registers_available(false), - m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), - m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), - m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0), - m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number), - m_registers(), m_parent_unwind(unwind_lldb) { - m_sym_ctx.Clear(false); - m_sym_ctx_valid = false; - - if (IsFrameZero()) { - InitializeZerothFrame(); - } else { - InitializeNonZerothFrame(); - } - - // This same code exists over in the GetFullUnwindPlanForFrame() but it may - // not have been executed yet - if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame || - next_frame->m_frame_type == eDebuggerFrame) { - m_all_registers_available = true; - } -} - -bool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC( - lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) { - if (!unwind_plan_sp) - return false; - - // check if m_current_pc is valid - if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - // yes - current offset can be used as is - valid_pc_offset = m_current_offset; - return true; - } - - // if m_current_offset <= 0, we've got nothing else to try - if (m_current_offset <= 0) - return false; - - // check pc - 1 to see if it's valid - Address pc_minus_one(m_current_pc); - pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1); - if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) { - // *valid_pc_offset = m_current_offset - 1; - valid_pc_offset = m_current_pc.GetOffset() - 1; - return true; - } - - return false; -} - -// Initialize a RegisterContextLLDB which is the first frame of a stack -- the -// zeroth frame or currently executing frame. - -void RegisterContextLLDB::InitializeZerothFrame() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - ExecutionContext exe_ctx(m_thread.shared_from_this()); - RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); - - if (reg_ctx_sp.get() == nullptr) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("frame does not have a register context"); - return; - } - - addr_t current_pc = reg_ctx_sp->GetPC(); - - if (current_pc == LLDB_INVALID_ADDRESS) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("frame does not have a pc"); - return; - } - - Process *process = exe_ctx.GetProcessPtr(); - - // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs - // this will strip bit zero in case we read a PC from memory or from the LR. - // (which would be a no-op in frame 0 where we get it from the register set, - // but still a good idea to make the call here for other ABIs that may - // exist.) - ABI *abi = process->GetABI().get(); - if (abi) - current_pc = abi->FixCodeAddress(current_pc); - - // Initialize m_current_pc, an Address object, based on current_pc, an - // addr_t. - m_current_pc.SetLoadAddress(current_pc, &process->GetTarget()); - - // If we don't have a Module for some reason, we're not going to find - // symbol/function information - just stick in some reasonable defaults and - // hope we can unwind past this frame. - ModuleSP pc_module_sp(m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp) { - UnwindLogMsg("using architectural default unwind method"); - } - - AddressRange addr_range; - m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); - - if (m_sym_ctx.symbol) { - UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", - current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - } else if (m_sym_ctx.function) { - UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", - current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - } else { - UnwindLogMsg("with pc value of 0x%" PRIx64 - ", no symbol/function name is known.", - current_pc); - } - - if (IsTrapHandlerSymbol(process, m_sym_ctx)) { - m_frame_type = eTrapHandlerFrame; - } else { - // FIXME: Detect eDebuggerFrame here. - m_frame_type = eNormalFrame; - } - - // If we were able to find a symbol/function, set addr_range to the bounds of - // that symbol/function. else treat the current pc value as the start_pc and - // record no offset. - if (addr_range.GetBaseAddress().IsValid()) { - m_start_pc = addr_range.GetBaseAddress(); - if (m_current_pc.GetSection() == m_start_pc.GetSection()) { - m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); - } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) { - // This means that whatever symbol we kicked up isn't really correct --- - // we should not cross section boundaries ... We really should NULL out - // the function/symbol in this case unless there is a bad assumption here - // due to inlined functions? - m_current_offset = - m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress(); - } - m_current_offset_backed_up_one = m_current_offset; - } else { - m_start_pc = m_current_pc; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - } - - // We've set m_frame_type and m_sym_ctx before these calls. - - m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); - - UnwindPlan::RowSP active_row; - lldb::RegisterKind row_register_kind = eRegisterKindGeneric; - if (m_full_unwind_plan_sp && - m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - active_row = - m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); - if (active_row.get() && log) { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, - m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - UnwindLogMsg("%s", active_row_strm.GetData()); - } - } - - if (!active_row.get()) { - UnwindLogMsg("could not find an unwindplan row for this frame's pc"); - m_frame_type = eNotAValidFrame; - return; - } - - if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { - // Try the fall back unwind plan since the - // full unwind plan failed. - FuncUnwindersSP func_unwinders_sp; - UnwindPlanSP call_site_unwind_plan; - bool cfa_status = false; - - if (m_sym_ctx_valid) { - func_unwinders_sp = - pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( - m_current_pc, m_sym_ctx); - } - - if (func_unwinders_sp.get() != nullptr) - call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite( - process->GetTarget(), m_thread); - - if (call_site_unwind_plan.get() != nullptr) { - m_fallback_unwind_plan_sp = call_site_unwind_plan; - if (TryFallbackUnwindPlan()) - cfa_status = true; - } - if (!cfa_status) { - UnwindLogMsg("could not read CFA value for first frame."); - m_frame_type = eNotAValidFrame; - return; - } - } else - ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); - - UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 - " afa is 0x%" PRIx64 " using %s UnwindPlan", - (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), - (uint64_t)m_cfa, - (uint64_t)m_afa, - m_full_unwind_plan_sp->GetSourceName().GetCString()); -} - -// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the -// RegisterContextLLDB "below" it to provide things like its current pc value. - -void RegisterContextLLDB::InitializeNonZerothFrame() { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (IsFrameZero()) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that " - "shouldn't happen."); - return; - } - - if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("Could not get next frame, marking this frame as invalid."); - return; - } - if (!m_thread.GetRegisterContext()) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("Could not get register context for this thread, marking this " - "frame as invalid."); - return; - } - - addr_t pc; - if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { - UnwindLogMsg("could not get pc value"); - m_frame_type = eNotAValidFrame; - return; - } - - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs - // this will strip bit zero in case we read a PC from memory or from the LR. - ABI *abi = process->GetABI().get(); - if (abi) - pc = abi->FixCodeAddress(pc); - - if (log) { - UnwindLogMsg("pc = 0x%" PRIx64, pc); - addr_t reg_val; - if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) - UnwindLogMsg("fp = 0x%" PRIx64, reg_val); - if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) - UnwindLogMsg("sp = 0x%" PRIx64, reg_val); - } - - // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap - // handler function - bool above_trap_handler = false; - if (GetNextFrame().get() && GetNextFrame()->IsValid() && - GetNextFrame()->IsTrapHandlerFrame()) - above_trap_handler = true; - - if (pc == 0 || pc == 0x1) { - if (!above_trap_handler) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("this frame has a pc of 0x0"); - return; - } - } - - const bool allow_section_end = true; - m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end); - - // If we don't have a Module for some reason, we're not going to find - // symbol/function information - just stick in some reasonable defaults and - // hope we can unwind past this frame. - ModuleSP pc_module_sp(m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp) { - UnwindLogMsg("using architectural default unwind method"); - - // Test the pc value to see if we know it's in an unmapped/non-executable - // region of memory. - uint32_t permissions; - if (process->GetLoadAddressPermissions(pc, permissions) && - (permissions & ePermissionsExecutable) == 0) { - // If this is the second frame off the stack, we may have unwound the - // first frame incorrectly. But using the architecture default unwind - // plan may get us back on track -- albeit possibly skipping a real - // frame. Give this frame a clearly-invalid pc and see if we can get any - // further. - if (GetNextFrame().get() && GetNextFrame()->IsValid() && - GetNextFrame()->IsFrameZero()) { - UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable " - "memory but on frame 1 -- " - "allowing it once.", - (uint64_t)pc); - m_frame_type = eSkipFrame; - } else { - // anywhere other than the second frame, a non-executable pc means - // we're off in the weeds -- stop now. - m_frame_type = eNotAValidFrame; - UnwindLogMsg("pc is in a non-executable section of memory and this " - "isn't the 2nd frame in the stack walk."); - return; - } - } - - if (abi) { - m_fast_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = - std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNormalFrame; - } - m_all_registers_available = false; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); - UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); - if (row.get()) { - if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) { - UnwindLogMsg("failed to get cfa value"); - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNotAValidFrame; - } - return; - } - - ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa); - - // A couple of sanity checks.. - if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { - UnwindLogMsg("could not find a valid cfa address"); - m_frame_type = eNotAValidFrame; - return; - } - - // m_cfa should point into the stack memory; if we can query memory - // region permissions, see if the memory is allocated & readable. - if (process->GetLoadAddressPermissions(m_cfa, permissions) && - (permissions & ePermissionsReadable) == 0) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg( - "the CFA points to a region of memory that is not readable"); - return; - } - } else { - UnwindLogMsg("could not find a row for function offset zero"); - m_frame_type = eNotAValidFrame; - return; - } - - if (CheckIfLoopingStack()) { - TryFallbackUnwindPlan(); - if (CheckIfLoopingStack()) { - UnwindLogMsg("same CFA address as next frame, assuming the unwind is " - "looping - stopping"); - m_frame_type = eNotAValidFrame; - return; - } - } - - UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, - (uint64_t)m_cfa, (uint64_t)m_afa); - return; - } - m_frame_type = eNotAValidFrame; - UnwindLogMsg("could not find any symbol for this pc, or a default unwind " - "plan, to continue unwind."); - return; - } - - AddressRange addr_range; - m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); - - if (m_sym_ctx.symbol) { - UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc, - GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - } else if (m_sym_ctx.function) { - UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc, - GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - } else { - UnwindLogMsg("with pc value of 0x%" PRIx64 - ", no symbol/function name is known.", - pc); - } - - bool decr_pc_and_recompute_addr_range; - - if (!m_sym_ctx_valid) { - // Always decrement and recompute if the symbol lookup failed - decr_pc_and_recompute_addr_range = true; - } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame || - GetNextFrame()->m_frame_type == eDebuggerFrame) { - // Don't decrement if we're "above" an asynchronous event like - // sigtramp. - decr_pc_and_recompute_addr_range = false; - } else if (!addr_range.GetBaseAddress().IsValid() || - addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() || - addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) { - // If our "current" pc isn't the start of a function, no need - // to decrement and recompute. - decr_pc_and_recompute_addr_range = false; - } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) { - // Signal dispatch may set the return address of the handler it calls to - // point to the first byte of a return trampoline (like __kernel_rt_sigreturn), - // so do not decrement and recompute if the symbol we already found is a trap - // handler. - decr_pc_and_recompute_addr_range = false; - } else { - // Decrement to find the function containing the call. - decr_pc_and_recompute_addr_range = true; - } - - // We need to back up the pc by 1 byte and re-search for the Symbol to handle - // the case where the "saved pc" value is pointing to the next function, e.g. - // if a function ends with a CALL instruction. - // FIXME this may need to be an architectural-dependent behavior; if so we'll - // need to add a member function - // to the ABI plugin and consult that. - if (decr_pc_and_recompute_addr_range) { - UnwindLogMsg("Backing up the pc value of 0x%" PRIx64 - " by 1 and re-doing symbol lookup; old symbol was %s", - pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - Address temporary_pc; - temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); - m_sym_ctx.Clear(false); - m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); - - UnwindLogMsg("Symbol is now %s", - GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - } - - // If we were able to find a symbol/function, set addr_range_ptr to the - // bounds of that symbol/function. else treat the current pc value as the - // start_pc and record no offset. - if (addr_range.GetBaseAddress().IsValid()) { - m_start_pc = addr_range.GetBaseAddress(); - m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget()); - m_current_offset_backed_up_one = m_current_offset; - if (decr_pc_and_recompute_addr_range && - m_current_offset_backed_up_one > 0) { - m_current_offset_backed_up_one--; - if (m_sym_ctx_valid) { - m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget()); - } - } - } else { - m_start_pc = m_current_pc; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - } - - if (IsTrapHandlerSymbol(process, m_sym_ctx)) { - m_frame_type = eTrapHandlerFrame; - } else { - // FIXME: Detect eDebuggerFrame here. - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNormalFrame; - } - } - - // We've set m_frame_type and m_sym_ctx before this call. - m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); - - UnwindPlan::RowSP active_row; - RegisterKind row_register_kind = eRegisterKindGeneric; - - // Try to get by with just the fast UnwindPlan if possible - the full - // UnwindPlan may be expensive to get (e.g. if we have to parse the entire - // eh_frame section of an ObjectFile for the first time.) - - if (m_fast_unwind_plan_sp && - m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - active_row = - m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind(); - PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp); - if (active_row.get() && log) { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, - m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - UnwindLogMsg("active row: %s", active_row_strm.GetData()); - } - } else { - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); - int valid_offset = -1; - if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) { - active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset); - row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); - PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); - if (active_row.get() && log) { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), - &m_thread, - m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - UnwindLogMsg("active row: %s", active_row_strm.GetData()); - } - } - } - - if (!active_row.get()) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg("could not find unwind row for this pc"); - return; - } - - if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { - UnwindLogMsg("failed to get cfa"); - m_frame_type = eNotAValidFrame; - return; - } - - ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); - - UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); - - if (CheckIfLoopingStack()) { - TryFallbackUnwindPlan(); - if (CheckIfLoopingStack()) { - UnwindLogMsg("same CFA address as next frame, assuming the unwind is " - "looping - stopping"); - m_frame_type = eNotAValidFrame; - return; - } - } - - UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 - " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, - (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), - (uint64_t)m_cfa, - (uint64_t)m_afa); -} - -bool RegisterContextLLDB::CheckIfLoopingStack() { - // If we have a bad stack setup, we can get the same CFA value multiple times - // -- or even more devious, we can actually oscillate between two CFA values. - // Detect that here and break out to avoid a possible infinite loop in lldb - // trying to unwind the stack. To detect when we have the same CFA value - // multiple times, we compare the - // CFA of the current - // frame with the 2nd next frame because in some specail case (e.g. signal - // hanlders, hand written assembly without ABI compiance) we can have 2 - // frames with the same - // CFA (in theory we - // can have arbitrary number of frames with the same CFA, but more then 2 is - // very very unlikely) - - RegisterContextLLDB::SharedPtr next_frame = GetNextFrame(); - if (next_frame) { - RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame(); - addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS; - if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) { - if (next_next_frame_cfa == m_cfa) { - // We have a loop in the stack unwind - return true; - } - } - } - return false; -} - -bool RegisterContextLLDB::IsFrameZero() const { return m_frame_number == 0; } - -// Find a fast unwind plan for this frame, if possible. -// -// On entry to this method, -// -// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame -// if either of those are correct, -// 2. m_sym_ctx should already be filled in, and -// 3. m_current_pc should have the current pc value for this frame -// 4. m_current_offset_backed_up_one should have the current byte offset into -// the function, maybe backed up by 1, -1 if unknown - -UnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame() { - UnwindPlanSP unwind_plan_sp; - ModuleSP pc_module_sp(m_current_pc.GetModule()); - - if (!m_current_pc.IsValid() || !pc_module_sp || - pc_module_sp->GetObjectFile() == nullptr) - return unwind_plan_sp; - - if (IsFrameZero()) - return unwind_plan_sp; - - FuncUnwindersSP func_unwinders_sp( - pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( - m_current_pc, m_sym_ctx)); - if (!func_unwinders_sp) - return unwind_plan_sp; - - // If we're in _sigtramp(), unwinding past this frame requires special - // knowledge. - if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame) - return unwind_plan_sp; - - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind( - *m_thread.CalculateTarget(), m_thread); - if (unwind_plan_sp) { - if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log && log->GetVerbose()) { - if (m_fast_unwind_plan_sp) - UnwindLogMsgVerbose("frame, and has a fast UnwindPlan"); - else - UnwindLogMsgVerbose("frame"); - } - m_frame_type = eNormalFrame; - return unwind_plan_sp; - } else { - unwind_plan_sp.reset(); - } - } - return unwind_plan_sp; -} - -// On entry to this method, -// -// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame -// if either of those are correct, -// 2. m_sym_ctx should already be filled in, and -// 3. m_current_pc should have the current pc value for this frame -// 4. m_current_offset_backed_up_one should have the current byte offset into -// the function, maybe backed up by 1, -1 if unknown - -UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { - UnwindPlanSP unwind_plan_sp; - UnwindPlanSP arch_default_unwind_plan_sp; - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - ABI *abi = process ? process->GetABI().get() : nullptr; - if (abi) { - arch_default_unwind_plan_sp = - std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); - } else { - UnwindLogMsg( - "unable to get architectural default UnwindPlan from ABI plugin"); - } - - bool behaves_like_zeroth_frame = false; - if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame || - GetNextFrame()->m_frame_type == eDebuggerFrame) { - behaves_like_zeroth_frame = true; - // If this frame behaves like a 0th frame (currently executing or - // interrupted asynchronously), all registers can be retrieved. - m_all_registers_available = true; - } - - // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) - // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first - // instruction" arch default UnwindPlan Also, if this Process can report on - // memory region attributes, any non-executable region means we jumped - // through a bad function pointer - handle the same way as 0x0. Note, if we - // have a symbol context & a symbol, we don't want to follow this code path. - // This is for jumping to memory regions without any information available. - - if ((!m_sym_ctx_valid || - (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) && - behaves_like_zeroth_frame && m_current_pc.IsValid()) { - uint32_t permissions; - addr_t current_pc_addr = - m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()); - if (current_pc_addr == 0 || - (process && - process->GetLoadAddressPermissions(current_pc_addr, permissions) && - (permissions & ePermissionsExecutable) == 0)) { - if (abi) { - unwind_plan_sp = - std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); - m_frame_type = eNormalFrame; - return unwind_plan_sp; - } - } - } - - // No Module for the current pc, try using the architecture default unwind. - ModuleSP pc_module_sp(m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp || - pc_module_sp->GetObjectFile() == nullptr) { - m_frame_type = eNormalFrame; - return arch_default_unwind_plan_sp; - } - - FuncUnwindersSP func_unwinders_sp; - if (m_sym_ctx_valid) { - func_unwinders_sp = - pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( - m_current_pc, m_sym_ctx); - } - - // No FuncUnwinders available for this pc (stripped function symbols, lldb - // could not augment its function table with another source, like - // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the - // .ARM.exidx tables have unwind information for this address, else fall back - // to the architectural default unwind. - if (!func_unwinders_sp) { - m_frame_type = eNormalFrame; - - if (!pc_module_sp || !pc_module_sp->GetObjectFile() || - !m_current_pc.IsValid()) - return arch_default_unwind_plan_sp; - - // Even with -fomit-frame-pointer, we can try eh_frame to get back on - // track. - DWARFCallFrameInfo *eh_frame = - pc_module_sp->GetUnwindTable().GetEHFrameInfo(); - if (eh_frame) { - unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) - return unwind_plan_sp; - else - unwind_plan_sp.reset(); - } - - ArmUnwindInfo *arm_exidx = - pc_module_sp->GetUnwindTable().GetArmUnwindInfo(); - if (arm_exidx) { - unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc, - *unwind_plan_sp)) - return unwind_plan_sp; - else - unwind_plan_sp.reset(); - } - - CallFrameInfo *object_file_unwind = - pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo(); - if (object_file_unwind) { - unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) - return unwind_plan_sp; - else - unwind_plan_sp.reset(); - } - - return arch_default_unwind_plan_sp; - } - - // If we're in _sigtramp(), unwinding past this frame requires special - // knowledge. On Mac OS X this knowledge is properly encoded in the eh_frame - // section, so prefer that if available. On other platforms we may need to - // provide a platform-specific UnwindPlan which encodes the details of how to - // unwind out of sigtramp. - if (m_frame_type == eTrapHandlerFrame && process) { - m_fast_unwind_plan_sp.reset(); - unwind_plan_sp = - func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); - if (!unwind_plan_sp) - unwind_plan_sp = - func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) && - unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) { - return unwind_plan_sp; - } - } - - // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame - // even when it's frame zero This comes up if we have hand-written functions - // in a Module and hand-written eh_frame. The assembly instruction - // inspection may fail and the eh_frame CFI were probably written with some - // care to do the right thing. It'd be nice if there was a way to ask the - // eh_frame directly if it is asynchronous (can be trusted at every - // instruction point) or synchronous (the normal case - only at call sites). - // But there is not. - if (process && process->GetDynamicLoader() && - process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) { - // We must specifically call the GetEHFrameUnwindPlan() method here -- - // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may - // return an unwind plan sourced from either eh_frame (that's what we - // intend) or compact unwind (this won't work) - unwind_plan_sp = - func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); - if (!unwind_plan_sp) - unwind_plan_sp = - func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the " - "DynamicLoader suggested we prefer it", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - } - - // Typically the NonCallSite UnwindPlan is the unwind created by inspecting - // the assembly language instructions - if (behaves_like_zeroth_frame && process) { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( - process->GetTarget(), m_thread); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { - if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { - // We probably have an UnwindPlan created by inspecting assembly - // instructions. The assembly profilers work really well with compiler- - // generated functions but hand- written assembly can be problematic. - // We set the eh_frame based unwind plan as our fallback unwind plan if - // instruction emulation doesn't work out even for non call sites if it - // is available and use the architecture default unwind plan if it is - // not available. The eh_frame unwind plan is more reliable even on non - // call sites then the architecture default plan and for hand written - // assembly code it is often written in a way that it valid at all - // location what helps in the most common cases when the instruction - // emulation fails. - UnwindPlanSP call_site_unwind_plan = - func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), - m_thread); - if (call_site_unwind_plan && - call_site_unwind_plan.get() != unwind_plan_sp.get() && - call_site_unwind_plan->GetSourceName() != - unwind_plan_sp->GetSourceName()) { - m_fallback_unwind_plan_sp = call_site_unwind_plan; - } else { - m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; - } - } - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " - "is the non-call site unwind plan and this is a " - "zeroth frame", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - - // If we're on the first instruction of a function, and we have an - // architectural default UnwindPlan for the initial instruction of a - // function, use that. - if (m_current_offset == 0) { - unwind_plan_sp = - func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry( - m_thread); - if (unwind_plan_sp) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at " - "the first instruction of a function", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - } - } - - // Typically this is unwind info from an eh_frame section intended for - // exception handling; only valid at call sites - if (process) { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite( - process->GetTarget(), m_thread); - } - int valid_offset = -1; - if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " - "is the call-site unwind plan", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - - // We'd prefer to use an UnwindPlan intended for call sites when we're at a - // call site but if we've struck out on that, fall back to using the non- - // call-site assembly inspection UnwindPlan if possible. - if (process) { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( - process->GetTarget(), m_thread); - } - if (unwind_plan_sp && - unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { - // We probably have an UnwindPlan created by inspecting assembly - // instructions. The assembly profilers work really well with compiler- - // generated functions but hand- written assembly can be problematic. We - // set the eh_frame based unwind plan as our fallback unwind plan if - // instruction emulation doesn't work out even for non call sites if it is - // available and use the architecture default unwind plan if it is not - // available. The eh_frame unwind plan is more reliable even on non call - // sites then the architecture default plan and for hand written assembly - // code it is often written in a way that it valid at all location what - // helps in the most common cases when the instruction emulation fails. - UnwindPlanSP call_site_unwind_plan = - func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), - m_thread); - if (call_site_unwind_plan && - call_site_unwind_plan.get() != unwind_plan_sp.get() && - call_site_unwind_plan->GetSourceName() != - unwind_plan_sp->GetSourceName()) { - m_fallback_unwind_plan_sp = call_site_unwind_plan; - } else { - m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; - } - } - - if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we " - "failed to find a call-site unwind plan that would work", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - - // If nothing else, use the architectural default UnwindPlan and hope that - // does the job. - if (arch_default_unwind_plan_sp) - UnwindLogMsgVerbose( - "frame uses %s for full UnwindPlan because we are falling back " - "to the arch default plan", - arch_default_unwind_plan_sp->GetSourceName().GetCString()); - else - UnwindLogMsg( - "Unable to find any UnwindPlan for full unwind of this frame."); - - return arch_default_unwind_plan_sp; -} - -void RegisterContextLLDB::InvalidateAllRegisters() { - m_frame_type = eNotAValidFrame; -} - -size_t RegisterContextLLDB::GetRegisterCount() { - return m_thread.GetRegisterContext()->GetRegisterCount(); -} - -const RegisterInfo *RegisterContextLLDB::GetRegisterInfoAtIndex(size_t reg) { - return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg); -} - -size_t RegisterContextLLDB::GetRegisterSetCount() { - return m_thread.GetRegisterContext()->GetRegisterSetCount(); -} - -const RegisterSet *RegisterContextLLDB::GetRegisterSet(size_t reg_set) { - return m_thread.GetRegisterContext()->GetRegisterSet(reg_set); -} - -uint32_t RegisterContextLLDB::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber( - kind, num); -} - -bool RegisterContextLLDB::ReadRegisterValueFromRegisterLocation( - lldb_private::UnwindLLDB::RegisterLocation regloc, - const RegisterInfo *reg_info, RegisterValue &value) { - if (!IsValid()) - return false; - bool success = false; - - switch (regloc.type) { - case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: { - const RegisterInfo *other_reg_info = - GetRegisterInfoAtIndex(regloc.location.register_number); - - if (!other_reg_info) - return false; - - success = - m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); - } break; - case UnwindLLDB::RegisterLocation::eRegisterInRegister: { - const RegisterInfo *other_reg_info = - GetRegisterInfoAtIndex(regloc.location.register_number); - - if (!other_reg_info) - return false; - - if (IsFrameZero()) { - success = - m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); - } else { - success = GetNextFrame()->ReadRegister(other_reg_info, value); - } - } break; - case UnwindLLDB::RegisterLocation::eRegisterValueInferred: - success = - value.SetUInt(regloc.location.inferred_value, reg_info->byte_size); - break; - - case UnwindLLDB::RegisterLocation::eRegisterNotSaved: - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: - llvm_unreachable("FIXME debugger inferior function call unwind"); - case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: { - Status error(ReadRegisterValueFromMemory( - reg_info, regloc.location.target_memory_location, reg_info->byte_size, - value)); - success = error.Success(); - } break; - default: - llvm_unreachable("Unknown RegisterLocation type."); - } - return success; -} - -bool RegisterContextLLDB::WriteRegisterValueToRegisterLocation( - lldb_private::UnwindLLDB::RegisterLocation regloc, - const RegisterInfo *reg_info, const RegisterValue &value) { - if (!IsValid()) - return false; - - bool success = false; - - switch (regloc.type) { - case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: { - const RegisterInfo *other_reg_info = - GetRegisterInfoAtIndex(regloc.location.register_number); - success = - m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); - } break; - case UnwindLLDB::RegisterLocation::eRegisterInRegister: { - const RegisterInfo *other_reg_info = - GetRegisterInfoAtIndex(regloc.location.register_number); - if (IsFrameZero()) { - success = - m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); - } else { - success = GetNextFrame()->WriteRegister(other_reg_info, value); - } - } break; - case UnwindLLDB::RegisterLocation::eRegisterValueInferred: - case UnwindLLDB::RegisterLocation::eRegisterNotSaved: - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: - llvm_unreachable("FIXME debugger inferior function call unwind"); - case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: { - Status error(WriteRegisterValueToMemory( - reg_info, regloc.location.target_memory_location, reg_info->byte_size, - value)); - success = error.Success(); - } break; - default: - llvm_unreachable("Unknown RegisterLocation type."); - } - return success; -} - -bool RegisterContextLLDB::IsValid() const { - return m_frame_type != eNotAValidFrame; -} - -// After the final stack frame in a stack walk we'll get one invalid -// (eNotAValidFrame) stack frame -- one past the end of the stack walk. But -// higher-level code will need to tell the differnece between "the unwind plan -// below this frame failed" versus "we successfully completed the stack walk" -// so this method helps to disambiguate that. - -bool RegisterContextLLDB::IsTrapHandlerFrame() const { - return m_frame_type == eTrapHandlerFrame; -} - -// A skip frame is a bogus frame on the stack -- but one where we're likely to -// find a real frame farther -// up the stack if we keep looking. It's always the second frame in an unwind -// (i.e. the first frame after frame zero) where unwinding can be the -// trickiest. Ideally we'll mark up this frame in some way so the user knows -// we're displaying bad data and we may have skipped one frame of their real -// program in the process of getting back on track. - -bool RegisterContextLLDB::IsSkipFrame() const { - return m_frame_type == eSkipFrame; -} - -bool RegisterContextLLDB::IsTrapHandlerSymbol( - lldb_private::Process *process, - const lldb_private::SymbolContext &m_sym_ctx) const { - PlatformSP platform_sp(process->GetTarget().GetPlatform()); - if (platform_sp) { - const std::vector<ConstString> trap_handler_names( - platform_sp->GetTrapHandlerSymbolNames()); - for (ConstString name : trap_handler_names) { - if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || - (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { - return true; - } - } - } - const std::vector<ConstString> user_specified_trap_handler_names( - m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames()); - for (ConstString name : user_specified_trap_handler_names) { - if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || - (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { - return true; - } - } - - return false; -} - -// Answer the question: Where did THIS frame save the CALLER frame ("previous" -// frame)'s register value? - -enum UnwindLLDB::RegisterSearchResult -RegisterContextLLDB::SavedLocationForRegister( - uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc) { - RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum); - - // Have we already found this register location? - if (!m_registers.empty()) { - std::map<uint32_t, - lldb_private::UnwindLLDB::RegisterLocation>::const_iterator - iterator; - iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB)); - if (iterator != m_registers.end()) { - regloc = iterator->second; - UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - } - - // Look through the available UnwindPlans for the register location. - - UnwindPlan::Row::RegisterLocation unwindplan_regloc; - bool have_unwindplan_regloc = false; - RegisterKind unwindplan_registerkind = kNumRegisterKinds; - - if (m_fast_unwind_plan_sp) { - UnwindPlan::RowSP active_row = - m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind(); - if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { - UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind " - "reg numbering scheme", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), - (int)unwindplan_registerkind); - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), - unwindplan_regloc)) { - UnwindLogMsg( - "supplying caller's saved %s (%d)'s location using FastUnwindPlan", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - have_unwindplan_regloc = true; - } - } - - if (!have_unwindplan_regloc) { - // m_full_unwind_plan_sp being NULL means that we haven't tried to find a - // full UnwindPlan yet - if (!m_full_unwind_plan_sp) - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); - - if (m_full_unwind_plan_sp) { - RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC); - - UnwindPlan::RowSP active_row = - m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); - - RegisterNumber return_address_reg; - - // If we're fetching the saved pc and this UnwindPlan defines a - // ReturnAddress register (e.g. lr on arm), look for the return address - // register number in the UnwindPlan's row. - if (pc_regnum.IsValid() && pc_regnum == regnum && - m_full_unwind_plan_sp->GetReturnAddressRegister() != - LLDB_INVALID_REGNUM) { - - return_address_reg.init( - m_thread, m_full_unwind_plan_sp->GetRegisterKind(), - m_full_unwind_plan_sp->GetReturnAddressRegister()); - regnum = return_address_reg; - UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a " - "RA reg; getting %s (%d) instead", - return_address_reg.GetName(), - return_address_reg.GetAsKind(eRegisterKindLLDB)); - } else { - if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { - if (unwindplan_registerkind == eRegisterKindGeneric) { - UnwindLogMsg("could not convert lldb regnum %s (%d) into " - "eRegisterKindGeneric reg numbering scheme", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - } else { - UnwindLogMsg("could not convert lldb regnum %s (%d) into %d " - "RegisterKind reg numbering scheme", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), - (int)unwindplan_registerkind); - } - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - } - - if (regnum.IsValid() && - active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), - unwindplan_regloc)) { - have_unwindplan_regloc = true; - UnwindLogMsg( - "supplying caller's saved %s (%d)'s location using %s UnwindPlan", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), - m_full_unwind_plan_sp->GetSourceName().GetCString()); - } - - // This is frame 0 and we're retrieving the PC and it's saved in a Return - // Address register and it hasn't been saved anywhere yet -- that is, - // it's still live in the actual register. Handle this specially. - - if (!have_unwindplan_regloc && return_address_reg.IsValid() && - IsFrameZero()) { - if (return_address_reg.GetAsKind(eRegisterKindLLDB) != - LLDB_INVALID_REGNUM) { - lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = - UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; - new_regloc.location.register_number = - return_address_reg.GetAsKind(eRegisterKindLLDB); - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; - regloc = new_regloc; - UnwindLogMsg("supplying caller's register %s (%d) from the live " - "RegisterContext at frame 0, saved in %d", - return_address_reg.GetName(), - return_address_reg.GetAsKind(eRegisterKindLLDB), - return_address_reg.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - } - - // If this architecture stores the return address in a register (it - // defines a Return Address register) and we're on a non-zero stack frame - // and the Full UnwindPlan says that the pc is stored in the - // RA registers (e.g. lr on arm), then we know that the full unwindplan is - // not trustworthy -- this - // is an impossible situation and the instruction emulation code has - // likely been misled. If this stack frame meets those criteria, we need - // to throw away the Full UnwindPlan that the instruction emulation came - // up with and fall back to the architecture's Default UnwindPlan so the - // stack walk can get past this point. - - // Special note: If the Full UnwindPlan was generated from the compiler, - // don't second-guess it when we're at a call site location. - - // arch_default_ra_regnum is the return address register # in the Full - // UnwindPlan register numbering - RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_RA); - - if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) != - LLDB_INVALID_REGNUM && - pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() && - unwindplan_regloc.GetRegisterNumber() == - arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) && - m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes && - !m_all_registers_available) { - UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link " - "register but this is a non-zero frame", - m_full_unwind_plan_sp->GetSourceName().GetCString()); - - // Throw away the full unwindplan; install the arch default unwindplan - if (ForceSwitchToFallbackUnwindPlan()) { - // Update for the possibly new unwind plan - unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); - UnwindPlan::RowSP active_row = - m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - - // Sanity check: Verify that we can fetch a pc value and CFA value - // with this unwind plan - - RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC); - bool can_fetch_pc_value = false; - bool can_fetch_cfa = false; - addr_t cfa_value; - if (active_row) { - if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) != - LLDB_INVALID_REGNUM && - active_row->GetRegisterInfo( - arch_default_pc_reg.GetAsKind(unwindplan_registerkind), - unwindplan_regloc)) { - can_fetch_pc_value = true; - } - if (ReadFrameAddress(unwindplan_registerkind, - active_row->GetCFAValue(), cfa_value)) { - can_fetch_cfa = true; - } - } - - have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa; - } else { - // We were unable to fall back to another unwind plan - have_unwindplan_regloc = false; - } - } - } - } - - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - if (!have_unwindplan_regloc) { - // If the UnwindPlan failed to give us an unwind location for this - // register, we may be able to fall back to some ABI-defined default. For - // example, some ABIs allow to determine the caller's SP via the CFA. Also, - // the ABI may set volatile registers to the undefined state. - ABI *abi = process ? process->GetABI().get() : nullptr; - if (abi) { - const RegisterInfo *reg_info = - GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB)); - if (reg_info && - abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) { - UnwindLogMsg( - "supplying caller's saved %s (%d)'s location using ABI default", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - have_unwindplan_regloc = true; - } - } - } - - if (!have_unwindplan_regloc) { - if (IsFrameZero()) { - // This is frame 0 - we should return the actual live register context - // value - lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = - UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; - new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; - regloc = new_regloc; - UnwindLogMsg("supplying caller's register %s (%d) from the live " - "RegisterContext at frame 0", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } else { - std::string unwindplan_name(""); - if (m_full_unwind_plan_sp) { - unwindplan_name += "via '"; - unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString(); - unwindplan_name += "'"; - } - UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(), - regnum.GetAsKind(eRegisterKindLLDB), - unwindplan_name.c_str()); - } - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - - // unwindplan_regloc has valid contents about where to retrieve the register - if (unwindplan_regloc.IsUnspecified()) { - lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; - UnwindLogMsg("save location for %s (%d) is unspecified, continue searching", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - - if (unwindplan_regloc.IsUndefined()) { - UnwindLogMsg( - "did not supply reg location for %s (%d) because it is volatile", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; - } - - if (unwindplan_regloc.IsSame()) { - if (!IsFrameZero() && - (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC || - regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) { - UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or " - "return address reg on a non-zero frame -- treat as if we " - "have no information", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } else { - regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg( - "supplying caller's register %s (%d), saved in register %s (%d)", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - } - - if (unwindplan_regloc.IsCFAPlusOffset()) { - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = m_cfa + offset; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus " - "offset %d [value is 0x%" PRIx64 "]", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, - regloc.location.inferred_value); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - - if (unwindplan_regloc.IsAtCFAPlusOffset()) { - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; - regloc.location.target_memory_location = m_cfa + offset; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " - "CFA plus offset %d [saved at 0x%" PRIx64 "]", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, - regloc.location.target_memory_location); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - - if (unwindplan_regloc.IsAFAPlusOffset()) { - if (m_afa == LLDB_INVALID_ADDRESS) - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = m_afa + offset; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus " - "offset %d [value is 0x%" PRIx64 "]", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, - regloc.location.inferred_value); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - - if (unwindplan_regloc.IsAtAFAPlusOffset()) { - if (m_afa == LLDB_INVALID_ADDRESS) - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; - regloc.location.target_memory_location = m_afa + offset; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " - "AFA plus offset %d [saved at 0x%" PRIx64 "]", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, - regloc.location.target_memory_location); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - - if (unwindplan_regloc.IsInOtherRegister()) { - uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); - RegisterNumber row_regnum(m_thread, unwindplan_registerkind, - unwindplan_regnum); - if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) { - UnwindLogMsg("could not supply caller's %s (%d) location - was saved in " - "another reg but couldn't convert that regnum", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB); - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg( - "supplying caller's register %s (%d), saved in register %s (%d)", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), - row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - - if (unwindplan_regloc.IsDWARFExpression() || - unwindplan_regloc.IsAtDWARFExpression()) { - DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(), - unwindplan_regloc.GetDWARFExpressionLength(), - process->GetByteOrder(), - process->GetAddressByteSize()); - ModuleSP opcode_ctx; - DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); - dwarfexpr.SetRegisterKind(unwindplan_registerkind); - Value cfa_val = Scalar(m_cfa); - cfa_val.SetValueType(Value::eValueTypeLoadAddress); - Value result; - Status error; - if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result, - &error)) { - addr_t val; - val = result.GetScalar().ULongLong(); - if (unwindplan_regloc.IsDWARFExpression()) { - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = val; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " - "(IsDWARFExpression)", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } else { - regloc.type = - UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; - regloc.location.target_memory_location = val; - m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; - UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " - "(IsAtDWARFExpression)", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - } - UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s " - "(%d) but failed", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - } - - UnwindLogMsg("no save location for %s (%d) in this stack frame", - regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); - - // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are - // unsupported. - - return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; -} - -// TryFallbackUnwindPlan() -- this method is a little tricky. -// -// When this is called, the frame above -- the caller frame, the "previous" -// frame -- is invalid or bad. -// -// Instead of stopping the stack walk here, we'll try a different UnwindPlan -// and see if we can get a valid frame above us. -// -// This most often happens when an unwind plan based on assembly instruction -// inspection is not correct -- mostly with hand-written assembly functions or -// functions where the stack frame is set up "out of band", e.g. the kernel -// saved the register context and then called an asynchronous trap handler like -// _sigtramp. -// -// Often in these cases, if we just do a dumb stack walk we'll get past this -// tricky frame and our usual techniques can continue to be used. - -bool RegisterContextLLDB::TryFallbackUnwindPlan() { - if (m_fallback_unwind_plan_sp.get() == nullptr) - return false; - - if (m_full_unwind_plan_sp.get() == nullptr) - return false; - - if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || - m_full_unwind_plan_sp->GetSourceName() == - m_fallback_unwind_plan_sp->GetSourceName()) { - return false; - } - - // If a compiler generated unwind plan failed, trying the arch default - // unwindplan isn't going to do any better. - if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) - return false; - - // Get the caller's pc value and our own CFA value. Swap in the fallback - // unwind plan, re-fetch the caller's pc value and CFA value. If they're the - // same, then the fallback unwind plan provides no benefit. - - RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC); - - addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; - addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; - UnwindLLDB::RegisterLocation regloc; - if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), - regloc) == - UnwindLLDB::RegisterSearchResult::eRegisterFound) { - const RegisterInfo *reg_info = - GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); - if (reg_info) { - RegisterValue reg_value; - if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { - old_caller_pc_value = reg_value.GetAsUInt64(); - } - } - } - - // This is a tricky wrinkle! If SavedLocationForRegister() detects a really - // impossible register location for the full unwind plan, it may call - // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full - // unwindplan with the fallback... in short, we're done, we're using the - // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr - // at the top -- the only way it became nullptr since then is via - // SavedLocationForRegister(). - if (m_fallback_unwind_plan_sp.get() == nullptr) - return true; - - // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide - // this isn't working, we need to restore. We'll also need to save & restore - // the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'. - UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp; - addr_t old_cfa = m_cfa; - addr_t old_afa = m_afa; - - m_registers.clear(); - - m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; - - UnwindPlan::RowSP active_row = - m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - - if (active_row && - active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::FAValue::unspecified) { - addr_t new_cfa; - if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { - UnwindLogMsg("failed to get cfa with fallback unwindplan"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - return false; - } - m_cfa = new_cfa; - - ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetAFAValue(), m_afa); - - if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), - regloc) == - UnwindLLDB::RegisterSearchResult::eRegisterFound) { - const RegisterInfo *reg_info = - GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); - if (reg_info) { - RegisterValue reg_value; - if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, - reg_value)) { - new_caller_pc_value = reg_value.GetAsUInt64(); - } - } - } - - if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { - UnwindLogMsg("failed to get a pc value for the caller frame with the " - "fallback unwind plan"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - m_cfa = old_cfa; - m_afa = old_afa; - return false; - } - - if (old_caller_pc_value == new_caller_pc_value && - m_cfa == old_cfa && - m_afa == old_afa) { - UnwindLogMsg("fallback unwind plan got the same values for this frame " - "CFA and caller frame pc, not using"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - return false; - } - - UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' " - "because UnwindPlan '%s' failed.", - m_fallback_unwind_plan_sp->GetSourceName().GetCString(), - original_full_unwind_plan_sp->GetSourceName().GetCString()); - - // We've copied the fallback unwind plan into the full - now clear the - // fallback. - m_fallback_unwind_plan_sp.reset(); - PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); - } - - return true; -} - -bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { - if (m_fallback_unwind_plan_sp.get() == nullptr) - return false; - - if (m_full_unwind_plan_sp.get() == nullptr) - return false; - - if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || - m_full_unwind_plan_sp->GetSourceName() == - m_fallback_unwind_plan_sp->GetSourceName()) { - return false; - } - - UnwindPlan::RowSP active_row = - m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - - if (active_row && - active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::FAValue::unspecified) { - addr_t new_cfa; - if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { - UnwindLogMsg("failed to get cfa with fallback unwindplan"); - m_fallback_unwind_plan_sp.reset(); - return false; - } - - ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetAFAValue(), m_afa); - - m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; - m_fallback_unwind_plan_sp.reset(); - - m_registers.clear(); - - m_cfa = new_cfa; - - PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); - - UnwindLogMsg("switched unconditionally to the fallback unwindplan %s", - m_full_unwind_plan_sp->GetSourceName().GetCString()); - return true; - } - return false; -} - -void RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan( - lldb::UnwindPlanSP unwind_plan) { - if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) { - // Unwind plan does not indicate trap handler. Do nothing. We may - // already be flagged as trap handler flag due to the symbol being - // in the trap handler symbol list, and that should take precedence. - return; - } else if (m_frame_type != eNormalFrame) { - // If this is already a trap handler frame, nothing to do. - // If this is a skip or debug or invalid frame, don't override that. - return; - } - - m_frame_type = eTrapHandlerFrame; - - if (m_current_offset_backed_up_one != m_current_offset) { - // We backed up the pc by 1 to compute the symbol context, but - // now need to undo that because the pc of the trap handler - // frame may in fact be the first instruction of a signal return - // trampoline, rather than the instruction after a call. This - // happens on systems where the signal handler dispatch code, rather - // than calling the handler and being returned to, jumps to the - // handler after pushing the address of a return trampoline on the - // stack -- on these systems, when the handler returns, control will - // be transferred to the return trampoline, so that's the best - // symbol we can present in the callstack. - UnwindLogMsg("Resetting current offset and re-doing symbol lookup; " - "old symbol was %s", - GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - m_current_offset_backed_up_one = m_current_offset; - - AddressRange addr_range; - m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); - - UnwindLogMsg("Symbol is now %s", - GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); - - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - Target *target = &process->GetTarget(); - - m_start_pc = addr_range.GetBaseAddress(); - m_current_offset = - m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target); - } -} - -bool RegisterContextLLDB::ReadFrameAddress( - lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, - addr_t &address) { - RegisterValue reg_value; - - address = LLDB_INVALID_ADDRESS; - addr_t cfa_reg_contents; - - switch (fa.GetValueType()) { - case UnwindPlan::Row::FAValue::isRegisterDereferenced: { - RegisterNumber cfa_reg(m_thread, row_register_kind, - fa.GetRegisterNumber()); - if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { - const RegisterInfo *reg_info = - GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); - RegisterValue reg_value; - if (reg_info) { - Status error = ReadRegisterValueFromMemory( - reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); - if (error.Success()) { - address = reg_value.GetAsUInt64(); - UnwindLogMsg( - "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 - ", CFA value is 0x%" PRIx64, - cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents, address); - return true; - } else { - UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64 - "] but memory read failed.", - cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents); - } - } - } - break; - } - case UnwindPlan::Row::FAValue::isRegisterPlusOffset: { - RegisterNumber cfa_reg(m_thread, row_register_kind, - fa.GetRegisterNumber()); - if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { - if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || - cfa_reg_contents == 1) { - UnwindLogMsg( - "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, - cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents); - cfa_reg_contents = LLDB_INVALID_ADDRESS; - return false; - } - address = cfa_reg_contents + fa.GetOffset(); - UnwindLogMsg( - "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 - ", offset is %d", - address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents, fa.GetOffset()); - return true; - } - break; - } - case UnwindPlan::Row::FAValue::isDWARFExpression: { - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(), - fa.GetDWARFExpressionLength(), - process->GetByteOrder(), - process->GetAddressByteSize()); - ModuleSP opcode_ctx; - DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); - dwarfexpr.SetRegisterKind(row_register_kind); - Value result; - Status error; - if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result, - &error)) { - address = result.GetScalar().ULongLong(); - - UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, - address); - return true; - } - UnwindLogMsg("Failed to set CFA value via DWARF expression: %s", - error.AsCString()); - break; - } - case UnwindPlan::Row::FAValue::isRaSearch: { - Process &process = *m_thread.GetProcess(); - lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset()); - if (return_address_hint == LLDB_INVALID_ADDRESS) - return false; - const unsigned max_iterations = 256; - for (unsigned i = 0; i < max_iterations; ++i) { - Status st; - lldb::addr_t candidate_addr = - return_address_hint + i * process.GetAddressByteSize(); - lldb::addr_t candidate = - process.ReadPointerFromMemory(candidate_addr, st); - if (st.Fail()) { - UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr, - st.AsCString()); - return false; - } - Address addr; - uint32_t permissions; - if (process.GetLoadAddressPermissions(candidate, permissions) && - permissions & lldb::ePermissionsExecutable) { - address = candidate_addr; - UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address); - return true; - } - } - UnwindLogMsg("No suitable CFA found"); - break; - } - default: - return false; - } - return false; -} - -lldb::addr_t RegisterContextLLDB::GetReturnAddressHint(int32_t plan_offset) { - addr_t hint; - if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint)) - return LLDB_INVALID_ADDRESS; - if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) - return LLDB_INVALID_ADDRESS; - - hint += plan_offset; - - if (auto next = GetNextFrame()) { - if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol) - return LLDB_INVALID_ADDRESS; - if (auto expected_size = - next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize( - *next->m_sym_ctx.symbol)) - hint += *expected_size; - else { - UnwindLogMsgVerbose("Could not retrieve parameter size: %s", - llvm::toString(expected_size.takeError()).c_str()); - return LLDB_INVALID_ADDRESS; - } - } - return hint; -} - -// Retrieve a general purpose register value for THIS frame, as saved by the -// NEXT frame, i.e. the frame that -// this frame called. e.g. -// -// foo () { } -// bar () { foo (); } -// main () { bar (); } -// -// stopped in foo() so -// frame 0 - foo -// frame 1 - bar -// frame 2 - main -// and this RegisterContext is for frame 1 (bar) - if we want to get the pc -// value for frame 1, we need to ask -// where frame 0 (the "next" frame) saved that and retrieve the value. - -bool RegisterContextLLDB::ReadGPRValue(lldb::RegisterKind register_kind, - uint32_t regnum, addr_t &value) { - if (!IsValid()) - return false; - - uint32_t lldb_regnum; - if (register_kind == eRegisterKindLLDB) { - lldb_regnum = regnum; - } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( - register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) { - return false; - } - - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); - RegisterValue reg_value; - // if this is frame 0 (currently executing frame), get the requested reg - // contents from the actual thread registers - if (IsFrameZero()) { - if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) { - value = reg_value.GetAsUInt64(); - return true; - } - return false; - } - - bool pc_register = false; - uint32_t generic_regnum; - if (register_kind == eRegisterKindGeneric && - (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) { - pc_register = true; - } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( - register_kind, regnum, eRegisterKindGeneric, generic_regnum) && - (generic_regnum == LLDB_REGNUM_GENERIC_PC || - generic_regnum == LLDB_REGNUM_GENERIC_RA)) { - pc_register = true; - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - if (!m_parent_unwind.SearchForSavedLocationForRegister( - lldb_regnum, regloc, m_frame_number - 1, pc_register)) { - return false; - } - if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { - value = reg_value.GetAsUInt64(); - return true; - } - return false; -} - -bool RegisterContextLLDB::ReadGPRValue(const RegisterNumber ®num, - addr_t &value) { - return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(), - value); -} - -// Find the value of a register in THIS frame - -bool RegisterContextLLDB::ReadRegister(const RegisterInfo *reg_info, - RegisterValue &value) { - if (!IsValid()) - return false; - - const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; - UnwindLogMsgVerbose("looking for register saved location for reg %d", - lldb_regnum); - - // If this is the 0th frame, hand this over to the live register context - if (IsFrameZero()) { - UnwindLogMsgVerbose("passing along to the live register context for reg %d", - lldb_regnum); - return m_thread.GetRegisterContext()->ReadRegister(reg_info, value); - } - - bool is_pc_regnum = false; - if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC || - reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) { - is_pc_regnum = true; - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - // Find out where the NEXT frame saved THIS frame's register contents - if (!m_parent_unwind.SearchForSavedLocationForRegister( - lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum)) - return false; - - return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); -} - -bool RegisterContextLLDB::WriteRegister(const RegisterInfo *reg_info, - const RegisterValue &value) { - if (!IsValid()) - return false; - - const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; - UnwindLogMsgVerbose("looking for register saved location for reg %d", - lldb_regnum); - - // If this is the 0th frame, hand this over to the live register context - if (IsFrameZero()) { - UnwindLogMsgVerbose("passing along to the live register context for reg %d", - lldb_regnum); - return m_thread.GetRegisterContext()->WriteRegister(reg_info, value); - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - // Find out where the NEXT frame saved THIS frame's register contents - if (!m_parent_unwind.SearchForSavedLocationForRegister( - lldb_regnum, regloc, m_frame_number - 1, false)) - return false; - - return WriteRegisterValueToRegisterLocation(regloc, reg_info, value); -} - -// Don't need to implement this one -bool RegisterContextLLDB::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { - return false; -} - -// Don't need to implement this one -bool RegisterContextLLDB::WriteAllRegisterValues( - const lldb::DataBufferSP &data_sp) { - return false; -} - -// Retrieve the pc value for THIS from - -bool RegisterContextLLDB::GetCFA(addr_t &cfa) { - if (!IsValid()) { - return false; - } - if (m_cfa == LLDB_INVALID_ADDRESS) { - return false; - } - cfa = m_cfa; - return true; -} - -RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetNextFrame() const { - RegisterContextLLDB::SharedPtr regctx; - if (m_frame_number == 0) - return regctx; - return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1); -} - -RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetPrevFrame() const { - RegisterContextLLDB::SharedPtr regctx; - return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1); -} - -// Retrieve the address of the start of the function of THIS frame - -bool RegisterContextLLDB::GetStartPC(addr_t &start_pc) { - if (!IsValid()) - return false; - - if (!m_start_pc.IsValid()) { - bool read_successfully = ReadPC (start_pc); - if (read_successfully) - { - ProcessSP process_sp (m_thread.GetProcess()); - if (process_sp) - { - ABI *abi = process_sp->GetABI().get(); - if (abi) - start_pc = abi->FixCodeAddress(start_pc); - } - } - return read_successfully; - } - start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get()); - return true; -} - -// Retrieve the current pc value for THIS frame, as saved by the NEXT frame. - -bool RegisterContextLLDB::ReadPC(addr_t &pc) { - if (!IsValid()) - return false; - - bool above_trap_handler = false; - if (GetNextFrame().get() && GetNextFrame()->IsValid() && - GetNextFrame()->IsTrapHandlerFrame()) - above_trap_handler = true; - - if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { - // A pc value of 0 or 1 is impossible in the middle of the stack -- it - // indicates the end of a stack walk. - // On the currently executing frame (or such a frame interrupted - // asynchronously by sigtramp et al) this may occur if code has jumped - // through a NULL pointer -- we want to be able to unwind past that frame - // to help find the bug. - - ProcessSP process_sp (m_thread.GetProcess()); - if (process_sp) - { - ABI *abi = process_sp->GetABI().get(); - if (abi) - pc = abi->FixCodeAddress(pc); - } - - return !(m_all_registers_available == false && - above_trap_handler == false && (pc == 0 || pc == 1)); - } else { - return false; - } -} - -void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log) { - va_list args; - va_start(args, fmt); - - char *logmsg; - if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { - if (logmsg) - free(logmsg); - va_end(args); - return; - } - va_end(args); - - LLDB_LOGF(log, "%*sth%d/fr%u %s", - m_frame_number < 100 ? m_frame_number : 100, "", - m_thread.GetIndexID(), m_frame_number, logmsg); - free(logmsg); - } -} - -void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log && log->GetVerbose()) { - va_list args; - va_start(args, fmt); - - char *logmsg; - if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { - if (logmsg) - free(logmsg); - va_end(args); - return; - } - va_end(args); - - LLDB_LOGF(log, "%*sth%d/fr%u %s", - m_frame_number < 100 ? m_frame_number : 100, "", - m_thread.GetIndexID(), m_frame_number, logmsg); - free(logmsg); - } -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h deleted file mode 100644 index 114ac35591e7e..0000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ /dev/null @@ -1,259 +0,0 @@ -//===-- RegisterContextLLDB.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_RegisterContextLLDB_h_ -#define lldb_RegisterContextLLDB_h_ - -#include <vector> - -#include "UnwindLLDB.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/RegisterNumber.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class UnwindLLDB; - -class RegisterContextLLDB : public lldb_private::RegisterContext { -public: - typedef std::shared_ptr<RegisterContextLLDB> SharedPtr; - - RegisterContextLLDB(lldb_private::Thread &thread, const SharedPtr &next_frame, - lldb_private::SymbolContext &sym_ctx, - uint32_t frame_number, - lldb_private::UnwindLLDB &unwind_lldb); - - ~RegisterContextLLDB() override = default; - - void InvalidateAllRegisters() override; - - size_t GetRegisterCount() override; - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; - - size_t GetRegisterSetCount() override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; - - bool ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value) override; - - bool WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value) override; - - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; - - bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; - - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - - bool IsValid() const; - - bool IsTrapHandlerFrame() const; - - bool GetCFA(lldb::addr_t &cfa); - - bool GetStartPC(lldb::addr_t &start_pc); - - bool ReadPC(lldb::addr_t &start_pc); - -private: - enum FrameType { - eNormalFrame, - eTrapHandlerFrame, - eDebuggerFrame, // a debugger inferior function call frame; we get caller's - // registers from debugger - eSkipFrame, // The unwind resulted in a bogus frame but may get back on - // track so we don't want to give up yet - eNotAValidFrame // this frame is invalid for some reason - most likely it is - // past the top (end) of the stack - }; - - // UnwindLLDB needs to pass around references to RegisterLocations - friend class UnwindLLDB; - - // Returns true if we have an unwind loop -- the same stack frame unwinding - // multiple times. - bool CheckIfLoopingStack(); - - // Indicates whether this frame is frame zero -- the currently - // executing frame -- or not. - bool IsFrameZero() const; - - void InitializeZerothFrame(); - - void InitializeNonZerothFrame(); - - SharedPtr GetNextFrame() const; - - SharedPtr GetPrevFrame() const; - - // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've - // got one bogus frame at frame #1. - // There is a good chance we'll get back on track if we follow the frame - // pointer chain (or whatever is appropriate - // on this ABI) so we allow one invalid frame to be in the stack. Ideally - // we'll mark this frame specially at some - // point and indicate to the user that the unwinder had a hiccup. Often when - // this happens we will miss a frame of - // the program's actual stack in the unwind and we want to flag that for the - // user somehow. - bool IsSkipFrame() const; - - /// Determines if a SymbolContext is a trap handler or not - /// - /// Given a SymbolContext, determines if this is a trap handler function - /// aka asynchronous signal handler. - /// - /// \return - /// Returns true if the SymbolContext is a trap handler. - bool IsTrapHandlerSymbol(lldb_private::Process *process, - const lldb_private::SymbolContext &m_sym_ctx) const; - - /// Check if the given unwind plan indicates a signal trap handler, and - /// update frame type and symbol context if so. - void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan); - - // Provide a location for where THIS function saved the CALLER's register - // value - // Or a frame "below" this one saved it, i.e. a function called by this one, - // preserved a register that this - // function didn't modify/use. - // - // The RegisterLocation type may be set to eRegisterNotAvailable -- this will - // happen for a volatile register - // being queried mid-stack. Instead of floating frame 0's contents of that - // register up the stack (which may - // or may not be the value of that reg when the function was executing), we - // won't return any value. - // - // If a non-volatile register (a "preserved" register) is requested mid-stack - // and no frames "below" the requested - // stack have saved the register anywhere, it is safe to assume that frame 0's - // register values are still the same - // as the requesting frame's. - lldb_private::UnwindLLDB::RegisterSearchResult - SavedLocationForRegister(uint32_t lldb_regnum, - lldb_private::UnwindLLDB::RegisterLocation ®loc); - - bool ReadRegisterValueFromRegisterLocation( - lldb_private::UnwindLLDB::RegisterLocation regloc, - const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool WriteRegisterValueToRegisterLocation( - lldb_private::UnwindLLDB::RegisterLocation regloc, - const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - /// If the unwind has to the caller frame has failed, try something else - /// - /// If lldb is using an assembly language based UnwindPlan for a frame and - /// the unwind to the caller frame fails, try falling back to a generic - /// UnwindPlan (architecture default unwindplan) to see if that might work - /// better. This is mostly helping to work around problems where the - /// assembly language inspection fails on hand-written assembly code. - /// - /// \return - /// Returns true if a fallback unwindplan was found & was installed. - bool TryFallbackUnwindPlan(); - - /// Switch to the fallback unwind plan unconditionally without any safety - /// checks that it is providing better results than the normal unwind plan. - /// - /// The only time it is valid to call this method is if the full unwindplan is - /// found to be fundamentally incorrect/impossible. - /// - /// Returns true if it was able to install the fallback unwind plan. - bool ForceSwitchToFallbackUnwindPlan(); - - // Get the contents of a general purpose (address-size) register for this - // frame - // (usually retrieved from the next frame) - bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum, - lldb::addr_t &value); - - bool ReadGPRValue(const RegisterNumber ®_num, lldb::addr_t &value); - - // Get the Frame Address register for a given frame. - bool ReadFrameAddress(lldb::RegisterKind register_kind, - UnwindPlan::Row::FAValue &fa, lldb::addr_t &address); - - lldb::UnwindPlanSP GetFastUnwindPlanForFrame(); - - lldb::UnwindPlanSP GetFullUnwindPlanForFrame(); - - void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3))); - - void UnwindLogMsgVerbose(const char *fmt, ...) - __attribute__((format(printf, 2, 3))); - - bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, - int &valid_pc_offset); - - lldb::addr_t GetReturnAddressHint(int32_t plan_offset); - - lldb_private::Thread &m_thread; - - /// - // The following tell us how to retrieve the CALLER's register values (ie the - // "previous" frame, aka the frame above) - // i.e. where THIS frame saved them - /// - - lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL - lldb::UnwindPlanSP m_full_unwind_plan_sp; - lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL - - bool m_all_registers_available; // Can we retrieve all regs or just - // nonvolatile regs? - int m_frame_type; // enum FrameType - - lldb::addr_t m_cfa; - lldb::addr_t m_afa; - lldb_private::Address m_start_pc; - lldb_private::Address m_current_pc; - - int m_current_offset; // how far into the function we've executed; -1 if - // unknown - // 0 if no instructions have been executed yet. - - int m_current_offset_backed_up_one; // how far into the function we've - // executed; -1 if unknown - // 0 if no instructions have been executed yet. - // On architectures where the return address on the stack points - // to the instruction after the CALL, this value will have 1 - // subtracted from it. Else a function that ends in a CALL will - // have an offset pointing into the next function's address range. - // m_current_pc has the actual address of the "current" pc. - - lldb_private::SymbolContext &m_sym_ctx; - bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to - // use m_sym_ctx - - uint32_t m_frame_number; // What stack frame this RegisterContext is - - std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> - m_registers; // where to find reg values for this frame - - lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating - // this RegisterContextLLDB - - // For RegisterContextLLDB only - - DISALLOW_COPY_AND_ASSIGN(RegisterContextLLDB); -}; - -} // namespace lldb_private - -#endif // lldb_RegisterContextLLDB_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp index 79979639dc7ee..518dc273faf48 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_i386.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextLinux_i386.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h index 5567a1ac42e50..ef731a5a79948 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_i386_H_ -#define liblldb_RegisterContextLinux_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp index fc60fea791761..837549e2a4957 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_mips.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_mips.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h index e637dfc15e4d6..9b59ab421ff46 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_mips_H_ -#define liblldb_RegisterContextLinux_mips_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H #include "RegisterInfoInterface.h" #include "lldb/lldb-private.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp index 3927883c47a42..432a78129fde1 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_mips64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h index ca0f0140a22d3..899f0a40e4ae9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_mips64_H_ -#define liblldb_RegisterContextLinux_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H #include "RegisterInfoInterface.h" #include "lldb/lldb-private.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp index d6401d788ab2b..7a8989cd1225e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_s390x.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextLinux_s390x.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h index 10810c97af80a..f381f38ecbf9a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_s390x_h_ -#define liblldb_RegisterContextLinux_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp index 640d5bc022569..f9d4e23fcde2c 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_x86_64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h index 02f273cb02c96..ea21b913d5c51 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_x86_64_H_ -#define liblldb_RegisterContextLinux_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp deleted file mode 100644 index bc78c1d6160c2..0000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ /dev/null @@ -1,160 +0,0 @@ -//===-- RegisterContextMacOSXFrameBackchain.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 "RegisterContextMacOSXFrameBackchain.h" - -#include "lldb/Target/Thread.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/Scalar.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringExtractorGDBRemote.h" - -using namespace lldb; -using namespace lldb_private; - -// RegisterContextMacOSXFrameBackchain constructor -RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain( - Thread &thread, uint32_t concrete_frame_idx, - const UnwindMacOSXFrameBackchain::Cursor &cursor) - : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor), - m_cursor_is_valid(true) {} - -// Destructor -RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {} - -void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() { - m_cursor_is_valid = false; -} - -size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() { - return m_thread.GetRegisterContext()->GetRegisterCount(); -} - -const RegisterInfo * -RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) { - return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg); -} - -size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() { - return m_thread.GetRegisterContext()->GetRegisterSetCount(); -} - -const RegisterSet * -RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) { - return m_thread.GetRegisterContext()->GetRegisterSet(reg_set); -} - -bool RegisterContextMacOSXFrameBackchain::ReadRegister( - const RegisterInfo *reg_info, RegisterValue &value) { - if (!m_cursor_is_valid) - return false; - - uint64_t reg_value = LLDB_INVALID_ADDRESS; - - switch (reg_info->kinds[eRegisterKindGeneric]) { - case LLDB_REGNUM_GENERIC_PC: - if (m_cursor.pc == LLDB_INVALID_ADDRESS) - return false; - reg_value = m_cursor.pc; - break; - - case LLDB_REGNUM_GENERIC_FP: - if (m_cursor.fp == LLDB_INVALID_ADDRESS) - return false; - reg_value = m_cursor.fp; - break; - - default: - return false; - } - - switch (reg_info->encoding) { - case eEncodingInvalid: - case eEncodingVector: - break; - - case eEncodingUint: - case eEncodingSint: - value.SetUInt(reg_value, reg_info->byte_size); - return true; - - case eEncodingIEEE754: - switch (reg_info->byte_size) { - case sizeof(float): - if (sizeof(float) == sizeof(uint32_t)) { - value.SetUInt32(reg_value, RegisterValue::eTypeFloat); - return true; - } else if (sizeof(float) == sizeof(uint64_t)) { - value.SetUInt64(reg_value, RegisterValue::eTypeFloat); - return true; - } - break; - - case sizeof(double): - if (sizeof(double) == sizeof(uint32_t)) { - value.SetUInt32(reg_value, RegisterValue::eTypeDouble); - return true; - } else if (sizeof(double) == sizeof(uint64_t)) { - value.SetUInt64(reg_value, RegisterValue::eTypeDouble); - return true; - } - break; - -// TOOD: need a better way to detect when "long double" types are -// the same bytes size as "double" -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \ - !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \ - !defined(__ANDROID__) - case sizeof(long double): - if (sizeof(long double) == sizeof(uint32_t)) { - value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble); - return true; - } else if (sizeof(long double) == sizeof(uint64_t)) { - value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble); - return true; - } - break; -#endif - } - break; - } - return false; -} - -bool RegisterContextMacOSXFrameBackchain::WriteRegister( - const RegisterInfo *reg_info, const RegisterValue &value) { - // Not supported yet. We could easily add support for this by remembering the - // address of each entry (it would need to be part of the cursor) - return false; -} - -bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues( - lldb::DataBufferSP &data_sp) { - // libunwind frames can't handle this it doesn't always have all register - // values. This call should only be called on frame zero anyway so there - // shouldn't be any problem - return false; -} - -bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues( - const lldb::DataBufferSP &data_sp) { - // Since this class doesn't respond to "ReadAllRegisterValues()", it must not - // have been the one that saved all the register values. So we just let the - // thread's register context (the register context for frame zero) do the - // writing. - return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp); -} - -uint32_t -RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber( - kind, num); -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h deleted file mode 100644 index 36e5538daa8a5..0000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- RegisterContextMacOSXFrameBackchain.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_RegisterContextMacOSXFrameBackchain_h_ -#define lldb_RegisterContextMacOSXFrameBackchain_h_ - -#include "lldb/Target/RegisterContext.h" -#include "lldb/lldb-private.h" - -#include "UnwindMacOSXFrameBackchain.h" - -class RegisterContextMacOSXFrameBackchain - : public lldb_private::RegisterContext { -public: - RegisterContextMacOSXFrameBackchain( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - const UnwindMacOSXFrameBackchain::Cursor &cursor); - - ~RegisterContextMacOSXFrameBackchain() override; - - void InvalidateAllRegisters() override; - - size_t GetRegisterCount() override; - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; - - size_t GetRegisterSetCount() override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; - - bool ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value) override; - - bool WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value) override; - - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; - - bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; - - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - -private: - UnwindMacOSXFrameBackchain::Cursor m_cursor; - bool m_cursor_is_valid; - - DISALLOW_COPY_AND_ASSIGN(RegisterContextMacOSXFrameBackchain); -}; - -#endif // lldb_RegisterContextMacOSXFrameBackchain_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp index c7042ab5137a8..1394cb7f00a1e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_arm.cpp -----------------------------*- C++ -*-===// +//===-- RegisterContextMach_arm.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h index 8b2425a193bec..e7c180dbdd27e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_arm_h_ -#define liblldb_RegisterContextMach_arm_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H #include "RegisterContextDarwin_arm.h" @@ -37,4 +36,4 @@ protected: int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg); }; -#endif // liblldb_RegisterContextMach_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp index e631ab9bb26cb..b97166b6eebe7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_i386.cpp ----------------------------*- C++ -*-===// +//===-- RegisterContextMach_i386.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h index b8835561e98c9..09966be60c921 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_i386_h_ -#define liblldb_RegisterContextMach_i386_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H #include "RegisterContextDarwin_i386.h" @@ -32,4 +32,4 @@ protected: int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); }; -#endif // liblldb_RegisterContextMach_i386_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp index db17d7d88778e..8933f136789fb 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_x86_64.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextMach_x86_64.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index 688009aef8af8..2a8a2cca2f8a8 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_x86_64_h_ -#define liblldb_RegisterContextMach_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H #include "RegisterContextDarwin_x86_64.h" @@ -33,4 +33,4 @@ protected: int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); }; -#endif // liblldb_RegisterContextMach_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 946d4fa9f8e55..f2d230b540532 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===// +//===-- RegisterContextMemory.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index 68223eaeffd7d..764ee9b972117 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextMemory_h_ -#define lldb_RegisterContextMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H #include <vector> @@ -67,7 +67,9 @@ protected: // context that is stored in memmory private: - DISALLOW_COPY_AND_ASSIGN(RegisterContextMemory); + RegisterContextMemory(const RegisterContextMemory &) = delete; + const RegisterContextMemory & + operator=(const RegisterContextMemory &) = delete; }; -#endif // lldb_RegisterContextMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp new file mode 100644 index 0000000000000..bd7830e42b42a --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp @@ -0,0 +1,96 @@ +//===-- RegisterContextNetBSD_i386.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 "RegisterContextNetBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// this needs to match 'struct reg' +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct FPR_i386 { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes + uint32_t padding[56]; +}; + +struct UserArea { + GPR gpr; + FPR_i386 i387; + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). + uint32_t tlsbase; +}; + +#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextNetBSD_i386::RegisterContextNetBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextNetBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextNetBSD_i386::GetRegisterInfo() const { + switch (m_target_arch.GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextNetBSD_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h new file mode 100644 index 0000000000000..742bb18b8306a --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextNetBSD_i386.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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextNetBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextNetBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp index e620ff66c9226..21aad92ecda8b 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextNetBSD_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextNetBSD_x86_64.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RegisterContextNetBSD_x86_64.h" +#include "RegisterContextNetBSD_i386.h" #include "RegisterContextPOSIX_x86.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" @@ -83,9 +84,40 @@ struct UserArea { #include "RegisterInfos_x86_64.h" #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT +static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() { + static std::vector<lldb_private::RegisterInfo> g_register_infos; + return g_register_infos; +} + +static const RegisterInfo * +GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { + std::vector<lldb_private::RegisterInfo> &g_register_infos = + GetPrivateRegisterInfoVector(); + + // Allocate RegisterInfo only once + if (g_register_infos.empty()) { + // Copy the register information from base class + std::unique_ptr<RegisterContextNetBSD_i386> reg_interface( + new RegisterContextNetBSD_i386(arch)); + const RegisterInfo *base_info = reg_interface->GetRegisterInfo(); + g_register_infos.insert(g_register_infos.end(), &base_info[0], + &base_info[k_num_registers_i386]); + +// Include RegisterInfos_x86_64 to update the g_register_infos structure +// with x86_64 offsets. +#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS +#include "RegisterInfos_x86_64.h" +#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + } + + return &g_register_infos[0]; +} + static const RegisterInfo * PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfo_i386(target_arch); case llvm::Triple::x86_64: return g_register_infos_x86_64; default: @@ -97,6 +129,11 @@ PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { static uint32_t PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { + case llvm::Triple::x86: { + assert(!GetPrivateRegisterInfoVector().empty() && + "i386 register info not yet filled."); + return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size()); + } case llvm::Triple::x86_64: return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[0])); @@ -106,11 +143,25 @@ PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { } } +static uint32_t +PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return static_cast<uint32_t>(k_num_user_registers_i386); + case llvm::Triple::x86_64: + return static_cast<uint32_t>(k_num_user_registers_x86_64); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64( const ArchSpec &target_arch) : lldb_private::RegisterInfoInterface(target_arch), m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), - m_register_count(PrivateGetRegisterCount(target_arch)) {} + m_register_count(PrivateGetRegisterCount(target_arch)), + m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {} size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } @@ -121,3 +172,7 @@ const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const { uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const { return m_register_count; } + +uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const { + return m_user_register_count; +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h index 4820ef8d17ba7..b7b8d33b7c379 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextNetBSD_x86_64_H_ -#define liblldb_RegisterContextNetBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H #include "RegisterInfoInterface.h" @@ -22,9 +22,12 @@ public: uint32_t GetRegisterCount() const override; + uint32_t GetUserRegisterCount() const override; + private: const lldb_private::RegisterInfo *m_register_info_p; const uint32_t m_register_count; + const uint32_t m_user_register_count; }; #endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp index 06eac6f7f9910..7183ffcfd0f62 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextOpenBSD_i386.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextOpenBSD_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h index 992ce0959fdfe..e6e24525b7fd9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextOpenBSD_i386_H_ -#define liblldb_RegisterContextOpenBSD_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp index e210196d921d4..05c1f83efded7 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextOpenBSD_x86_64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextOpenBSD_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h index 9c76e7211132b..b399c721546a9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextOpenBSD_x86_64_H_ -#define liblldb_RegisterContextOpenBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 821e2aa73b5b1..617893b6b3b04 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_arm.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_arm.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -178,35 +178,6 @@ const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_arm::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; - lldb_private::Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) { return set_index < k_num_register_sets; } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < lldb::kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const lldb_private::RegisterInfo *reg_info = - GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h index 603ba76430e6d..d6967f05ed487 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_arm_h_ -#define liblldb_RegisterContextPOSIX_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H #include "RegisterInfoInterface.h" #include "lldb-arm-register-enums.h" @@ -44,9 +44,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: struct RegInfo { uint32_t num_registers; @@ -95,12 +92,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index db1aa1b8b0931..8ef587f13e3ae 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_arm64.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_arm64.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,105 +25,25 @@ using namespace lldb; using namespace lldb_private; -// ARM64 general purpose registers. -const uint32_t g_gpr_regnums_arm64[] = { - gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, - gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, - gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, - gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, - gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, - gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, - gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, - gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, - gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, - gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, - gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, - gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, - gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, - gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, - gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, - gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - - 1) == k_num_gpr_registers_arm64, - "g_gpr_regnums_arm64 has wrong number of register infos"); - -// ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = { - fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, - fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, - fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, - fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, - fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, - fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, - fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, - fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, - fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, - fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, - fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, - fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, - fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, - fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, - fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, - fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, - - fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, - fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, - fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, - fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, - fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, - fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, - fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, - fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, - fpu_fpsr_arm64, fpu_fpcr_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - - 1) == k_num_fpr_registers_arm64, - "g_fpu_regnums_arm64 has wrong number of register infos"); - -// Number of register sets provided by this context. -enum { k_num_register_sets = 2 }; - -// Register sets for ARM64. -static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, - g_gpr_regnums_arm64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, - g_fpu_regnums_arm64}}; - bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) { - return reg <= m_reg_info.last_gpr; // GPR's come first. + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::GPRegSet) + return true; + return false; } bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::FPRegSet) + return true; + return false; } RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : lldb_private::RegisterContext(thread, concrete_frame_idx) { - m_register_info_up.reset(register_info); - - switch (register_info->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_arm64> register_info) + : lldb_private::RegisterContext(thread, 0), + m_register_info_up(std::move(register_info)) { ::memset(&m_fpr, 0, sizeof m_fpr); } @@ -135,19 +55,15 @@ void RegisterContextPOSIX_arm64::Invalidate() {} void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_offset; + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; } unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_size; + return m_register_info_up->GetRegisterInfo()[reg].byte_size; } size_t RegisterContextPOSIX_arm64::GetRegisterCount() { - size_t num_registers = - m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; - return num_registers; + return m_register_info_up->GetRegisterCount(); } size_t RegisterContextPOSIX_arm64::GetGPRSize() { @@ -164,71 +80,23 @@ RegisterContextPOSIX_arm64::GetRegisterInfo() { const lldb_private::RegisterInfo * RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) { - if (reg < m_reg_info.num_registers) + if (reg < GetRegisterCount()) return &GetRegisterInfo()[reg]; else return nullptr; } size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() { - size_t sets = 0; - for (size_t set = 0; set < k_num_register_sets; ++set) { - if (IsRegisterSetAvailable(set)) - ++sets; - } - - return sets; + return m_register_info_up->GetRegisterSetCount(); } const lldb_private::RegisterSet * RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) { - if (IsRegisterSetAvailable(set)) { - switch (m_register_info_up->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - return &g_reg_sets_arm64[set]; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } - } - return nullptr; + return m_register_info_up->GetRegisterSet(set); } const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register offset."); - return GetRegisterInfo()[reg].name; -} - -lldb::ByteOrder RegisterContextPOSIX_arm64::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; - lldb_private::Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - -bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) { - return set_index < k_num_register_sets; -} - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < lldb::kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const lldb_private::RegisterInfo *reg_info = - GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; + if (reg < GetRegisterCount()) + return GetRegisterInfo()[reg].name; + return nullptr; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index 49a49b69da6b3..c2d5aee7f73c9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_arm64_h_ -#define liblldb_RegisterContextPOSIX_arm64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H #include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_arm64.h" #include "lldb-arm64-register-enums.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" @@ -19,8 +20,8 @@ class ProcessMonitor; class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext { public: RegisterContextPOSIX_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); + lldb_private::Thread &thread, + std::unique_ptr<RegisterInfoPOSIX_arm64> register_info); ~RegisterContextPOSIX_arm64() override; @@ -44,50 +45,15 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_fpr_v; - uint32_t last_fpr_v; - - uint32_t gpr_flags; - }; - - // based on RegisterContextDarwin_arm64.h - struct VReg { - uint8_t bytes[16]; - }; - - // based on RegisterContextDarwin_arm64.h - struct FPU { - VReg v[32]; - uint32_t fpsr; - uint32_t fpcr; - }; - uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit // general // purpose // registers. - RegInfo m_reg_info; - struct RegisterContextPOSIX_arm64::FPU - m_fpr; // floating-point registers including extended register sets. - std::unique_ptr<lldb_private::RegisterInfoInterface> - m_register_info_up; // Register Info Interface (FreeBSD or Linux) - // Determines if an extended register set is supported on the processor - // running the inferior process. - virtual bool IsRegisterSetAvailable(size_t set_index); + struct RegisterInfoPOSIX_arm64::FPU + m_fpr; // floating-point registers including extended register sets. + std::unique_ptr<RegisterInfoPOSIX_arm64> m_register_info_up; virtual const lldb_private::RegisterInfo *GetRegisterInfo(); @@ -95,7 +61,7 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); + size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); } virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; @@ -103,4 +69,4 @@ protected: virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index f1fa3035b2ef7..c41c4bd7a7ea4 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_mips64.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_mips64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -149,17 +149,6 @@ const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = GetRegisterSetCount(); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h index c507e14bd5b69..1843a2a6aff32 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_mips64_h_ -#define liblldb_RegisterContextPOSIX_mips64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H #include "RegisterContext_mips.h" #include "RegisterInfoInterface.h" @@ -73,12 +73,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_mips64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index a78e9ed37947d..cd65b96d373e8 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -//-*-===// +//===-- RegisterContextPOSIX_powerpc.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -158,36 +157,8 @@ const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_powerpc::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = k_num_register_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h index 1a21a717b22b2..e2c33461c8f18 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_powerpc_h_ -#define liblldb_RegisterContextPOSIX_powerpc_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H #include "RegisterContext_powerpc.h" #include "RegisterInfoInterface.h" @@ -165,9 +165,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. @@ -189,8 +186,6 @@ protected: bool IsVMX(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool ReadVMX() = 0; @@ -199,4 +194,4 @@ protected: virtual bool WriteVMX() = 0; }; -#endif // liblldb_RegisterContextPOSIX_powerpc_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index 02546c0ed16fa..f670be2ef3c43 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===// +//===-- RegisterContextPOSIX_ppc64le.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -176,36 +176,8 @@ const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = k_num_register_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h index 37079775a3c73..66794ec9e9cab 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_ppc64le_h_ -#define liblldb_RegisterContextPOSIX_ppc64le_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "RegisterInfoInterface.h" @@ -39,9 +39,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: // 64-bit general purpose registers. uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le]; @@ -71,7 +68,6 @@ protected: bool IsVSX(unsigned reg); - lldb::ByteOrder GetByteOrder(); }; -#endif // liblldb_RegisterContextPOSIX_ppc64le_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index e040e5075721e..e746ec642b385 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_s390x.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -161,31 +161,3 @@ const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) { } return nullptr; } - -lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h index 54993ce6c3ec7..7df732d13ffa5 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_s390x_h_ -#define liblldb_RegisterContextPOSIX_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H #include "RegisterContext_s390x.h" #include "RegisterInfoInterface.h" @@ -43,9 +43,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: struct RegInfo { uint32_t num_registers; @@ -68,12 +65,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_s390x_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 4d5991f08f1d9..ac271a90d6a16 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_x86.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -456,17 +456,6 @@ const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - // Parse ymm registers and into xmm.bytes and ymmh.bytes. bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order) { @@ -509,20 +498,3 @@ bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) { ++num_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index 932f97bb567fa..c4886ae618a2f 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_x86_h_ -#define liblldb_RegisterContextPOSIX_x86_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" @@ -47,9 +47,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - // Note: prefer kernel definitions over user-land enum FPRType { eNotValid = 0, @@ -160,8 +157,6 @@ protected: bool IsAVX(unsigned reg); - lldb::ByteOrder GetByteOrder(); - bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order); bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order); bool IsFPR(unsigned reg, FPRType fpr_type); @@ -173,4 +168,4 @@ protected: virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_x86_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index bcf60cc7a3384..31e2944084ed3 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextThreadMemory.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 09a679ab2c9f4..40688a502a66e 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextThreadMemory_h_ -#define lldb_RegisterContextThreadMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H #include <vector> @@ -92,9 +92,11 @@ protected: uint32_t m_stop_id; private: - DISALLOW_COPY_AND_ASSIGN(RegisterContextThreadMemory); + RegisterContextThreadMemory(const RegisterContextThreadMemory &) = delete; + const RegisterContextThreadMemory & + operator=(const RegisterContextThreadMemory &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextThreadMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp index 916d3233cde5b..11556e802e33b 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_i386.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextWindows_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h index 7779cc3575260..6a5d3524300dc 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextWindows_i386_H_ -#define liblldb_RegisterContextWindows_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp index e90584de1a444..4ffc4d25781c5 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_x86_64.cpp -----------------------*- C++ -*-===// +//===-- RegisterContextWindows_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h index 18198b5b25b30..c29acf284841f 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextWindows_x86_64_H_ -#define liblldb_RegisterContextWindows_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H #include "RegisterInfoInterface.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h b/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h index 7780be51baad6..15081f974c667 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_mips64_H_ -#define liblldb_RegisterContext_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H #include <cstddef> #include <cstdint> @@ -371,4 +371,4 @@ struct UserArea { MSA_linux_mips msa; // MSA registers. }; -#endif // liblldb_RegisterContext_mips64_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h index 1ffcbeb5ec48c..7407e2f402e08 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_powerpc_H_ -#define liblldb_RegisterContext_powerpc_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H // eh_frame and DWARF Register numbers (eRegisterKindEHFrame & // eRegisterKindDWARF) @@ -120,4 +120,4 @@ enum { dwarf_v31_powerpc, }; -#endif // liblldb_RegisterContext_powerpc_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h index 2cf39e9eb8e2a..248b3bd0beacb 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_s390x_h_ -#define liblldb_RegisterContext_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H // SystemZ ehframe, dwarf regnums diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h index 2b79f778aa563..27a1bad4d53fa 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_x86_H_ -#define liblldb_RegisterContext_x86_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H #include <cstddef> #include <cstdint> diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h new file mode 100644 index 0000000000000..7e569dc9ba784 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h @@ -0,0 +1,36 @@ +//===-- RegisterInfoAndSetInterface.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_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H + +#include "RegisterInfoInterface.h" + +#include "lldb/Utility/ArchSpec.h" +#include "lldb/lldb-private-types.h" +#include <vector> + +namespace lldb_private { + +class RegisterInfoAndSetInterface : public RegisterInfoInterface { +public: + RegisterInfoAndSetInterface(const lldb_private::ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + + virtual size_t GetFPRSize() const = 0; + + virtual const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const = 0; + + virtual size_t GetRegisterSetCount() const = 0; + + virtual size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const = 0; +}; +} // namespace lldb_private + +#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h index 4b58e749adce6..88c2ae7c50107 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterInfoInterface_h -#define lldb_RegisterInfoInterface_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H #include "lldb/Utility/ArchSpec.h" #include "lldb/lldb-private-types.h" @@ -61,7 +61,6 @@ public: return nullptr; } -public: // FIXME make private. lldb_private::ArchSpec m_target_arch; }; diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index d392d3be1c41c..8fc4d5282b06a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_arm.cpp ------------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h index 39c2047600aa4..1cf896e3decfd 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterInfoPOSIX_arm_h_ -#define liblldb_RegisterInfoPOSIX_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" @@ -58,4 +58,4 @@ private: uint32_t m_register_info_count; }; -#endif // liblldb_RegisterInfoPOSIX_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index 8b367bdc64489..4537cee42ad96 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_arm64.cpp ----------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm64.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -65,6 +65,82 @@ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { } } +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, + k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, + k_num_register_sets = 2 +}; + +// ARM64 general purpose registers. +static const uint32_t g_gpr_regnums_arm64[] = { + gpr_x0, gpr_x1, gpr_x2, gpr_x3, + gpr_x4, gpr_x5, gpr_x6, gpr_x7, + gpr_x8, gpr_x9, gpr_x10, gpr_x11, + gpr_x12, gpr_x13, gpr_x14, gpr_x15, + gpr_x16, gpr_x17, gpr_x18, gpr_x19, + gpr_x20, gpr_x21, gpr_x22, gpr_x23, + gpr_x24, gpr_x25, gpr_x26, gpr_x27, + gpr_x28, gpr_fp, gpr_lr, gpr_sp, + gpr_pc, gpr_cpsr, gpr_w0, gpr_w1, + gpr_w2, gpr_w3, gpr_w4, gpr_w5, + gpr_w6, gpr_w7, gpr_w8, gpr_w9, + gpr_w10, gpr_w11, gpr_w12, gpr_w13, + gpr_w14, gpr_w15, gpr_w16, gpr_w17, + gpr_w18, gpr_w19, gpr_w20, gpr_w21, + gpr_w22, gpr_w23, gpr_w24, gpr_w25, + gpr_w26, gpr_w27, gpr_w28, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_arm64 has wrong number of register infos"); + +// ARM64 floating point registers. +static const uint32_t g_fpu_regnums_arm64[] = { + fpu_v0, fpu_v1, fpu_v2, + fpu_v3, fpu_v4, fpu_v5, + fpu_v6, fpu_v7, fpu_v8, + fpu_v9, fpu_v10, fpu_v11, + fpu_v12, fpu_v13, fpu_v14, + fpu_v15, fpu_v16, fpu_v17, + fpu_v18, fpu_v19, fpu_v20, + fpu_v21, fpu_v22, fpu_v23, + fpu_v24, fpu_v25, fpu_v26, + fpu_v27, fpu_v28, fpu_v29, + fpu_v30, fpu_v31, fpu_s0, + fpu_s1, fpu_s2, fpu_s3, + fpu_s4, fpu_s5, fpu_s6, + fpu_s7, fpu_s8, fpu_s9, + fpu_s10, fpu_s11, fpu_s12, + fpu_s13, fpu_s14, fpu_s15, + fpu_s16, fpu_s17, fpu_s18, + fpu_s19, fpu_s20, fpu_s21, + fpu_s22, fpu_s23, fpu_s24, + fpu_s25, fpu_s26, fpu_s27, + fpu_s28, fpu_s29, fpu_s30, + fpu_s31, fpu_d0, fpu_d1, + fpu_d2, fpu_d3, fpu_d4, + fpu_d5, fpu_d6, fpu_d7, + fpu_d8, fpu_d9, fpu_d10, + fpu_d11, fpu_d12, fpu_d13, + fpu_d14, fpu_d15, fpu_d16, + fpu_d17, fpu_d18, fpu_d19, + fpu_d20, fpu_d21, fpu_d22, + fpu_d23, fpu_d24, fpu_d25, + fpu_d26, fpu_d27, fpu_d28, + fpu_d29, fpu_d30, fpu_d31, + fpu_fpsr, fpu_fpcr, LLDB_INVALID_REGNUM}; +static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - + 1) == k_num_fpr_registers, + "g_fpu_regnums_arm64 has wrong number of register infos"); +// clang-format on +// Register sets for ARM64. +static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers, + g_gpr_regnums_arm64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers, + g_fpu_regnums_arm64}}; + static uint32_t GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { @@ -80,19 +156,60 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( const lldb_private::ArchSpec &target_arch) - : lldb_private::RegisterInfoInterface(target_arch), + : lldb_private::RegisterInfoAndSetInterface(target_arch), m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)) {} + m_register_info_count(GetRegisterInfoCount(target_arch)) { + + switch (target_arch.GetMachine()) { + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + num_registers = k_num_gpr_registers + k_num_fpr_registers; + num_gpr_registers = k_num_gpr_registers; + num_fpr_registers = k_num_fpr_registers; + last_gpr = gpr_w28; + first_fpr = fpu_v0; + last_fpr = fpu_fpcr; + break; + default: + assert(false && "Unhandled target architecture."); + break; + } +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { + return num_gpr_registers + num_fpr_registers; +} size_t RegisterInfoPOSIX_arm64::GetGPRSize() const { return sizeof(struct RegisterInfoPOSIX_arm64::GPR); } +size_t RegisterInfoPOSIX_arm64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_arm64::FPU); +} + const lldb_private::RegisterInfo * RegisterInfoPOSIX_arm64::GetRegisterInfo() const { return m_register_info_p; } -uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { - return m_register_info_count; +size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + if (reg_index <= last_gpr) + return GPRegSet; + else if (reg_index <= last_fpr) + return FPRegSet; + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { + if (set_index < k_num_register_sets) + return &g_reg_sets_arm64[set_index]; + + return nullptr; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h index ace179a818140..2da6a531a6b60 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -6,15 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_arm64_H_ -#define liblldb_RegisterContextLinux_arm64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H -#include "RegisterInfoInterface.h" +#include "RegisterInfoAndSetInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" -class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface { +class RegisterInfoPOSIX_arm64 + : public lldb_private::RegisterInfoAndSetInterface { public: + enum { GPRegSet = 0, FPRegSet }; + // based on RegisterContextDarwin_arm64.h struct GPR { uint64_t x[29]; // x0-x28 @@ -57,11 +60,28 @@ public: size_t GetGPRSize() const override; + size_t GetFPRSize() const override; + const lldb_private::RegisterInfo *GetRegisterInfo() const override; uint32_t GetRegisterCount() const override; + const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const override; + + size_t GetRegisterSetCount() const override; + + size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; + private: + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; }; diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp index 35051a3ce095f..3461d38a3901a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_ppc64le.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h index c4d4d3b546e2a..98549ac0dda40 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_ppc64le_H_ -#define liblldb_RegisterContextLinux_ppc64le_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index 68c12aa6e5295..4aee55e7afba0 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -456,37 +456,26 @@ static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM}; static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM}; static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; -// Generates register kinds array for 64-bit general purpose registers -#define GPR64_KIND(reg, generic_kind) \ +// Generates register kinds array with DWARF, EH frame and generic kind +#define MISC_KIND(reg, type, generic_kind) \ { \ arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \ - gpr_##reg \ + type##_##reg \ } -// Generates register kinds array for registers with lldb kind -#define MISC_KIND(lldb_kind) \ +// Generates register kinds array for registers with only lldb kind +#define LLDB_KIND(lldb_kind) \ { \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_kind \ } // Generates register kinds array for vector registers -#define VREG_KIND(reg) \ - { \ - LLDB_INVALID_REGNUM, arm64_dwarf::reg, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, fpu_##reg \ - } - -// Generates register kinds array for cpsr -#define CPSR_KIND(lldb_kind) \ - { \ - arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, \ - LLDB_INVALID_REGNUM, lldb_kind \ - } - -#define MISC_GPR_KIND(lldb_kind) CPSR_KIND(lldb_kind) -#define MISC_FPU_KIND(lldb_kind) MISC_KIND(lldb_kind) -#define MISC_EXC_KIND(lldb_kind) MISC_KIND(lldb_kind) +#define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind) +#define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM) +#define MISC_GPR_KIND(lldb_kind) MISC_KIND(cpsr, gpr, LLDB_REGNUM_GENERIC_FLAGS) +#define MISC_FPU_KIND(lldb_kind) LLDB_KIND(lldb_kind) +#define MISC_EXC_KIND(lldb_kind) LLDB_KIND(lldb_kind) // Defines a 64-bit general purpose register #define DEFINE_GPR64(reg, generic_kind) \ @@ -509,7 +498,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #wreg, nullptr, 4, \ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ - lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \ + lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \ g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \ } @@ -521,11 +510,11 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; 0 \ } -// Defines S and D pseudo registers mapping over correspondig vector register +// Defines S and D pseudo registers mapping over corresponding vector register #define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \ { \ #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ - lldb::eEncodingIEEE754, lldb::eFormatFloat, MISC_KIND(fpu_##reg), \ + lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \ g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \ } diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index 72ff904520adc..343579cd26578 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -145,7 +145,7 @@ DR_OFFSET(i), eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM }, \ + lldb_##reg##i##_i386 }, \ nullptr, nullptr, nullptr, 0 \ } diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 6d03bd534f37f..2d8e8ef21612a 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -1,4 +1,4 @@ -//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===// +//===-- StopInfoMachException.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,7 @@ #include "StopInfoMachException.h" +#include "lldb/lldb-forward.h" #if defined(__APPLE__) // Needed for the EXC_RESOURCE interpretation macros @@ -289,10 +290,48 @@ const char *StopInfoMachException::GetDescription() { if (m_exc_data_count > 0) strm.PutChar(')'); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); return m_description.c_str(); } +static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target, + uint32_t exc_data_count, + uint64_t exc_sub_code, + uint64_t exc_sub_sub_code) { + // Try hardware watchpoint. + if (target) { + // The exc_sub_code indicates the data break address. + lldb::WatchpointSP wp_sp = + target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired watchpoint + // in the exception data. Set the hardware index if that's the case. + if (exc_data_count >= 3) + wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); + } + } + + // Try hardware breakpoint. + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + // The exc_sub_code indicates the data break address. + lldb::BreakpointSiteSP bp_sp = + process_sp->GetBreakpointSiteList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (bp_sp && bp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired breakpoint + // in the exception data. Set the hardware index if that's the case. + if (exc_data_count >= 3) + bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithBreakpointSiteID(thread, + bp_sp->GetID()); + } + } + + return nullptr; +} + StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, @@ -350,22 +389,10 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( is_actual_breakpoint = true; is_trace_if_actual_breakpoint_missing = true; } else { - - // It's a watchpoint, then. - // The exc_sub_code indicates the data break address. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress( - (lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) { - // Debugserver may piggyback the hardware index of the fired - // watchpoint in the exception data. Set the hardware index if - // that's the case. - if (exc_data_count >= 3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, - wp_sp->GetID()); - } + if (StopInfoSP stop_info = + GetStopInfoForHardwareBP(thread, target, exc_data_count, + exc_sub_code, exc_sub_sub_code)) + return stop_info; } } else if (exc_code == 2 || // EXC_I386_BPT exc_code == 3) // EXC_I386_BPTFLT diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h index 74c05812ab002..d9c1886d70964 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StopInfoMachException_h_ -#define liblldb_StopInfoMachException_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H #include <string> @@ -48,4 +48,4 @@ protected: } // namespace lldb_private -#endif // liblldb_StopInfoMachException_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp index 80b04bb14f77a..7469e7633e71d 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp @@ -1,5 +1,4 @@ -//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -//-*-===// +//===-- ThreadMemory.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +29,8 @@ ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, llvm::StringRef name, llvm::StringRef queue, lldb::addr_t register_data_addr) : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(), - m_name(name), m_queue(queue), m_register_data_addr(register_data_addr) {} + m_name(std::string(name)), m_queue(std::string(queue)), + m_register_data_addr(register_data_addr) {} ThreadMemory::~ThreadMemory() { DestroyThread(); } @@ -54,20 +54,14 @@ RegisterContextSP ThreadMemory::GetRegisterContext() { RegisterContextSP ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) { - RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); - if (concrete_frame_idx == 0) { - reg_ctx_sp = GetRegisterContext(); - } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); - } - return reg_ctx_sp; + if (concrete_frame_idx == 0) + return GetRegisterContext(); + return GetUnwinder().CreateRegisterContextForFrame(frame); } bool ThreadMemory::CalculateStopInfo() { diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h index 85bc1451e4a0e..d124f5780ea9b 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadMemory_h_ -#define liblldb_ThreadMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H #include <string> @@ -100,7 +100,8 @@ protected: lldb::addr_t m_register_data_addr; private: - DISALLOW_COPY_AND_ASSIGN(ThreadMemory); + ThreadMemory(const ThreadMemory &) = delete; + const ThreadMemory &operator=(const ThreadMemory &) = delete; }; -#endif // liblldb_ThreadMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp deleted file mode 100644 index 74fc90e885472..0000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ /dev/null @@ -1,519 +0,0 @@ -//===-- UnwindLLDB.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 "lldb/Core/Module.h" -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/ABI.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/Log.h" - -#include "RegisterContextLLDB.h" -#include "UnwindLLDB.h" - -using namespace lldb; -using namespace lldb_private; - -UnwindLLDB::UnwindLLDB(Thread &thread) - : Unwind(thread), m_frames(), m_unwind_complete(false), - m_user_supplied_trap_handler_functions() { - ProcessSP process_sp(thread.GetProcess()); - if (process_sp) { - Args args; - process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); - size_t count = args.GetArgumentCount(); - for (size_t i = 0; i < count; i++) { - const char *func_name = args.GetArgumentAtIndex(i); - m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); - } - } -} - -uint32_t UnwindLLDB::DoGetFrameCount() { - if (!m_unwind_complete) { -//#define DEBUG_FRAME_SPEED 1 -#if DEBUG_FRAME_SPEED -#define FRAME_COUNT 10000 - using namespace std::chrono; - auto time_value = steady_clock::now(); -#endif - if (!AddFirstFrame()) - return 0; - - ProcessSP process_sp(m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; - - while (AddOneMoreFrame(abi)) { -#if DEBUG_FRAME_SPEED - if ((m_frames.size() % FRAME_COUNT) == 0) { - const auto now = steady_clock::now(); - const auto delta_t = now - time_value; - printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, - duration<double, std::milli>(delta_t).count(), - (float)FRAME_COUNT / duration<double>(delta_t).count()); - time_value = now; - } -#endif - } - } - return m_frames.size(); -} - -bool UnwindLLDB::AddFirstFrame() { - if (m_frames.size() > 0) - return true; - - ProcessSP process_sp(m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; - - // First, set up the 0th (initial) frame - CursorSP first_cursor_sp(new Cursor()); - RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( - m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); - if (reg_ctx_sp.get() == nullptr) - goto unwind_done; - - if (!reg_ctx_sp->IsValid()) - goto unwind_done; - - if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) - goto unwind_done; - - if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) - goto unwind_done; - - // Everything checks out, so release the auto pointer value and let the - // cursor own it in its shared pointer - first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - m_frames.push_back(first_cursor_sp); - - // Update the Full Unwind Plan for this frame if not valid - UpdateUnwindPlanForFirstFrameIfInvalid(abi); - - return true; - -unwind_done: - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - if (log) { - LLDB_LOGF(log, "th%d Unwind of this thread is complete.", - m_thread.GetIndexID()); - } - m_unwind_complete = true; - return false; -} - -UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { - assert(m_frames.size() != 0 && - "Get one more frame called with empty frame list"); - - // If we've already gotten to the end of the stack, don't bother to try - // again... - if (m_unwind_complete) - return nullptr; - - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - - CursorSP prev_frame = m_frames.back(); - uint32_t cur_idx = m_frames.size(); - - CursorSP cursor_sp(new Cursor()); - RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( - m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); - - uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); - - // We want to detect an unwind that cycles erroneously and stop backtracing. - // Don't want this maximum unwind limit to be too low -- if you have a - // backtrace with an "infinitely recursing" bug, it will crash when the stack - // blows out and the first 35,000 frames are uninteresting - it's the top - // most 5 frames that you actually care about. So you can't just cap the - // unwind at 10,000 or something. Realistically anything over around 200,000 - // is going to blow out the stack space. If we're still unwinding at that - // point, we're probably never going to finish. - if (cur_idx >= max_stack_depth) { - LLDB_LOGF(log, - "%*sFrame %d unwound too many frames, assuming unwind has " - "gone astray, stopping.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - - if (reg_ctx_sp.get() == nullptr) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to - // that and return true. Subsequent calls to TryFallbackUnwindPlan() will - // return false. - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame - // still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - - if (!reg_ctx_sp->IsValid()) { - // We failed to get a valid RegisterContext. See if the regctx below this - // on the stack has a fallback unwind plan it can use. Subsequent calls to - // TryFallbackUnwindPlan() will return false. - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame - // still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, - "%*sFrame %d invalid RegisterContext for this frame, " - "stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to - // that and return true. Subsequent calls to TryFallbackUnwindPlan() will - // return false. - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame - // still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, - "%*sFrame %d did not get CFA for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { - // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not - // have its (constructed) CFA aligned correctly -- don't do the abi - // alignment check for these. - if (!reg_ctx_sp->IsTrapHandlerFrame()) { - // See if we can find a fallback unwind plan for THIS frame. It may be - // that the UnwindPlan we're using for THIS frame was bad and gave us a - // bad CFA. If that's not it, then see if we can change the UnwindPlan - // for the frame below us ("NEXT") -- see if using that other UnwindPlan - // gets us a better unwind state. - if (!reg_ctx_sp->TryFallbackUnwindPlan() || - !reg_ctx_sp->GetCFA(cursor_sp->cfa) || - !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of - // prev_frame still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, - "%*sFrame %d did not get a valid CFA for this frame, " - "stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } else { - LLDB_LOGF(log, - "%*sFrame %d had a bad CFA value but we switched the " - "UnwindPlan being used and got one that looks more " - "realistic.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - } - } - if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to - // that and return true. Subsequent calls to TryFallbackUnwindPlan() will - // return false. - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame - // still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, - "%*sFrame %d did not get PC for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to - // that and return true. Subsequent calls to TryFallbackUnwindPlan() will - // return false. - if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // TryFallbackUnwindPlan for prev_frame succeeded and updated - // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame - // still needs to be updated. Hence updating it. - if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) - return nullptr; - - return GetOneMoreFrame(abi); - } - - LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - return nullptr; - } - // Infinite loop where the current cursor is the same as the previous one... - if (prev_frame->start_pc == cursor_sp->start_pc && - prev_frame->cfa == cursor_sp->cfa) { - LLDB_LOGF(log, - "th%d pc of this frame is the same as the previous frame and " - "CFAs for both frames are identical -- stopping unwind", - m_thread.GetIndexID()); - return nullptr; - } - - cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - return cursor_sp; -} - -void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { - // This function is called for First Frame only. - assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); - - bool old_m_unwind_complete = m_unwind_complete; - CursorSP old_m_candidate_frame = m_candidate_frame; - - // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan - // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update - // the cfa of Frame 0 (if required). - AddOneMoreFrame(abi); - - // Remove all the frames added by above function as the purpose of using - // above function was just to check whether Unwinder of Frame 0 works or not. - for (uint32_t i = 1; i < m_frames.size(); i++) - m_frames.pop_back(); - - // Restore status after calling AddOneMoreFrame - m_unwind_complete = old_m_unwind_complete; - m_candidate_frame = old_m_candidate_frame; - return; -} - -bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); - - // Frame zero is a little different - if (m_frames.empty()) - return false; - - // If we've already gotten to the end of the stack, don't bother to try - // again... - if (m_unwind_complete) - return false; - - CursorSP new_frame = m_candidate_frame; - if (new_frame == nullptr) - new_frame = GetOneMoreFrame(abi); - - if (new_frame == nullptr) { - LLDB_LOGF(log, "th%d Unwind of this thread is complete.", - m_thread.GetIndexID()); - m_unwind_complete = true; - return false; - } - - m_frames.push_back(new_frame); - - // If we can get one more frame further then accept that we get back a - // correct frame. - m_candidate_frame = GetOneMoreFrame(abi); - if (m_candidate_frame) - return true; - - // We can't go further from the frame returned by GetOneMore frame. Lets try - // to get a different frame with using the fallback unwind plan. - if (!m_frames[m_frames.size() - 2] - ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { - // We don't have a valid fallback unwind plan. Accept the frame as it is. - // This is a valid situation when we are at the bottom of the stack. - return true; - } - - // Remove the possibly incorrect frame from the frame list and try to add a - // different one with the newly selected fallback unwind plan. - m_frames.pop_back(); - CursorSP new_frame_v2 = GetOneMoreFrame(abi); - if (new_frame_v2 == nullptr) { - // We haven't got a new frame from the fallback unwind plan. Accept the - // frame from the original unwind plan. This is a valid situation when we - // are at the bottom of the stack. - m_frames.push_back(new_frame); - return true; - } - - // Push the new frame to the list and try to continue from this frame. If we - // can get a new frame then accept it as the correct one. - m_frames.push_back(new_frame_v2); - m_candidate_frame = GetOneMoreFrame(abi); - if (m_candidate_frame) { - // If control reached here then TryFallbackUnwindPlan had succeeded for - // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next - // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For - // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already - // updated during TryFallbackUnwindPlan call above. However, cfa field - // still needs to be updated. Hence updating it here and then returning. - return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( - m_frames[m_frames.size() - 2]->cfa); - } - - // The new frame hasn't helped in unwinding. Fall back to the original one as - // the default unwind plan is usually more reliable then the fallback one. - m_frames.pop_back(); - m_frames.push_back(new_frame); - return true; -} - -bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, - bool &behaves_like_zeroth_frame) { - if (m_frames.size() == 0) { - if (!AddFirstFrame()) - return false; - } - - ProcessSP process_sp(m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; - - while (idx >= m_frames.size() && AddOneMoreFrame(abi)) - ; - - if (idx < m_frames.size()) { - cfa = m_frames[idx]->cfa; - pc = m_frames[idx]->start_pc; - if (idx == 0) { - // Frame zero always behaves like it. - behaves_like_zeroth_frame = true; - } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { - // This could be an asynchronous signal, thus the - // pc might point to the interrupted instruction rather - // than a post-call instruction - behaves_like_zeroth_frame = true; - } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { - // This frame may result from signal processing installing - // a pointer to the first byte of a signal-return trampoline - // in the return address slot of the frame below, so this - // too behaves like the zeroth frame (i.e. the pc might not - // be pointing just past a call in it) - behaves_like_zeroth_frame = true; - } else { - behaves_like_zeroth_frame = false; - } - return true; - } - return false; -} - -lldb::RegisterContextSP -UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { - lldb::RegisterContextSP reg_ctx_sp; - uint32_t idx = frame->GetConcreteFrameIndex(); - - if (idx == 0) { - return m_thread.GetRegisterContext(); - } - - if (m_frames.size() == 0) { - if (!AddFirstFrame()) - return reg_ctx_sp; - } - - ProcessSP process_sp(m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; - - while (idx >= m_frames.size()) { - if (!AddOneMoreFrame(abi)) - break; - } - - const uint32_t num_frames = m_frames.size(); - if (idx < num_frames) { - Cursor *frame_cursor = m_frames[idx].get(); - reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; - } - return reg_ctx_sp; -} - -UnwindLLDB::RegisterContextLLDBSP -UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { - RegisterContextLLDBSP reg_ctx_sp; - if (frame_num < m_frames.size()) - reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; - return reg_ctx_sp; -} - -bool UnwindLLDB::SearchForSavedLocationForRegister( - uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, - uint32_t starting_frame_num, bool pc_reg) { - int64_t frame_num = starting_frame_num; - if (static_cast<size_t>(frame_num) >= m_frames.size()) - return false; - - // Never interrogate more than one level while looking for the saved pc - // value. If the value isn't saved by frame_num, none of the frames lower on - // the stack will have a useful value. - if (pc_reg) { - UnwindLLDB::RegisterSearchResult result; - result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( - lldb_regnum, regloc); - return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - while (frame_num >= 0) { - UnwindLLDB::RegisterSearchResult result; - result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( - lldb_regnum, regloc); - - // We descended down to the live register context aka stack frame 0 and are - // reading the value out of a live register. - if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && - regloc.type == - UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { - return true; - } - - // If we have unwind instructions saying that register N is saved in - // register M in the middle of the stack (and N can equal M here, meaning - // the register was not used in this function), then change the register - // number we're looking for to M and keep looking for a concrete location - // down the stack, or an actual value from a live RegisterContext at frame - // 0. - if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && - regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && - frame_num > 0) { - result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; - lldb_regnum = regloc.location.register_number; - } - - if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) - return true; - if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) - return false; - frame_num--; - } - return false; -} diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h deleted file mode 100644 index ff5db39730b51..0000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ /dev/null @@ -1,158 +0,0 @@ -//===-- UnwindLLDB.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_UnwindLLDB_h_ -#define lldb_UnwindLLDB_h_ - -#include <vector> - -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Unwind.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/lldb-public.h" - -namespace lldb_private { - -class RegisterContextLLDB; - -class UnwindLLDB : public lldb_private::Unwind { -public: - UnwindLLDB(lldb_private::Thread &thread); - - ~UnwindLLDB() override = default; - - enum RegisterSearchResult { - eRegisterFound = 0, - eRegisterNotFound, - eRegisterIsVolatile - }; - -protected: - friend class lldb_private::RegisterContextLLDB; - - struct RegisterLocation { - enum RegisterLocationTypes { - eRegisterNotSaved = 0, // register was not preserved by callee. If - // volatile reg, is unavailable - eRegisterSavedAtMemoryLocation, // register is saved at a specific word of - // target mem (target_memory_location) - eRegisterInRegister, // register is available in a (possible other) - // register (register_number) - eRegisterSavedAtHostMemoryLocation, // register is saved at a word in - // lldb's address space - eRegisterValueInferred, // register val was computed (and is in - // inferred_value) - eRegisterInLiveRegisterContext // register value is in a live (stack frame - // #0) register - }; - int type; - union { - lldb::addr_t target_memory_location; - uint32_t - register_number; // in eRegisterKindLLDB register numbering system - void *host_memory_location; - uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == - // cfa + offset - } location; - }; - - void DoClear() override { - m_frames.clear(); - m_candidate_frame.reset(); - m_unwind_complete = false; - } - - uint32_t DoGetFrameCount() override; - - bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &start_pc, - bool &behaves_like_zeroth_frame) override; - - lldb::RegisterContextSP - DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; - - typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP; - - // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame - // 1's RegisterContextLLDB) - // The RegisterContext for frame_num must already exist or this returns an - // empty shared pointer. - RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num); - - // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the - // first one that - // has a saved location for this reg. - bool SearchForSavedLocationForRegister( - uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, - uint32_t starting_frame_num, bool pc_register); - - /// Provide the list of user-specified trap handler functions - /// - /// The Platform is one source of trap handler function names; that - /// may be augmented via a setting. The setting needs to be converted - /// into an array of ConstStrings before it can be used - we only want - /// to do that once per thread so it's here in the UnwindLLDB object. - /// - /// \return - /// Vector of ConstStrings of trap handler function names. May be - /// empty. - const std::vector<ConstString> &GetUserSpecifiedTrapHandlerFunctionNames() { - return m_user_supplied_trap_handler_functions; - } - -private: - struct Cursor { - lldb::addr_t start_pc; // The start address of the function/symbol for this - // frame - current pc if unknown - lldb::addr_t cfa; // The canonical frame address for this stack frame - lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & - // provide to the StackFrame creation - RegisterContextLLDBSP - reg_ctx_lldb_sp; // These are all RegisterContextLLDB's - - Cursor() - : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(), - reg_ctx_lldb_sp() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Cursor); - }; - - typedef std::shared_ptr<Cursor> CursorSP; - std::vector<CursorSP> m_frames; - CursorSP m_candidate_frame; - bool m_unwind_complete; // If this is true, we've enumerated all the frames in - // the stack, and m_frames.size() is the - // number of frames, etc. Otherwise we've only gone as far as directly asked, - // and m_frames.size() - // is how far we've currently gone. - - std::vector<ConstString> m_user_supplied_trap_handler_functions; - - // Check if Full UnwindPlan of First frame is valid or not. - // If not then try Fallback UnwindPlan of the frame. If Fallback - // UnwindPlan succeeds then update the Full UnwindPlan with the - // Fallback UnwindPlan. - void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi); - - CursorSP GetOneMoreFrame(ABI *abi); - - bool AddOneMoreFrame(ABI *abi); - - bool AddFirstFrame(); - - // For UnwindLLDB only - DISALLOW_COPY_AND_ASSIGN(UnwindLLDB); -}; - -} // namespace lldb_private - -#endif // lldb_UnwindLLDB_h_ diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp deleted file mode 100644 index 558edeec1a37f..0000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ /dev/null @@ -1,247 +0,0 @@ -//===-- UnwindMacOSXFrameBackchain.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 "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/ArchSpec.h" - -#include "RegisterContextMacOSXFrameBackchain.h" - -#include <memory> - -using namespace lldb; -using namespace lldb_private; - -UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread) - : Unwind(thread), m_cursors() {} - -uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() { - if (m_cursors.empty()) { - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) { - const ArchSpec &target_arch = target->GetArchitecture(); - // Frame zero should always be supplied by the thread... - exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0)); - - if (target_arch.GetAddressByteSize() == 8) - GetStackFrameData_x86_64(exe_ctx); - else - GetStackFrameData_i386(exe_ctx); - } - } - return m_cursors.size(); -} - -bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex( - uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) { - const uint32_t frame_count = GetFrameCount(); - if (idx < frame_count) { - if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS) - return false; - if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS) - return false; - - pc = m_cursors[idx].pc; - cfa = m_cursors[idx].fp; - behaves_like_zeroth_frame = (idx == 0); - - return true; - } - return false; -} - -lldb::RegisterContextSP -UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) { - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_idx = frame->GetConcreteFrameIndex(); - const uint32_t frame_count = GetFrameCount(); - if (concrete_idx < frame_count) - reg_ctx_sp = std::make_shared<RegisterContextMacOSXFrameBackchain>( - m_thread, concrete_idx, m_cursors[concrete_idx]); - return reg_ctx_sp; -} - -size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386( - const ExecutionContext &exe_ctx) { - m_cursors.clear(); - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == nullptr) - return 0; - - struct Frame_i386 { - uint32_t fp; - uint32_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert(reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP(0); - - Frame_i386 frame = {static_cast<uint32_t>(cursor.fp), - static_cast<uint32_t>(cursor.pc)}; - - m_cursors.push_back(cursor); - - const size_t k_frame_size = sizeof(frame); - Status error; - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) { - // Read both the FP and PC (8 bytes) - if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) != - k_frame_size) - break; - if (frame.pc >= 0x1000) { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back(cursor); - } - } - if (!m_cursors.empty()) { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const SymbolContextItem resolve_scope = - eSymbolContextModule | eSymbolContextCompUnit | - eSymbolContextFunction | eSymbolContextSymbol; - - SymbolContext first_frame_sc( - first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = nullptr; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize(first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) { - if (first_frame->GetFrameCodeAddress() == - addr_range_ptr->GetBaseAddress()) { - // We are at the first instruction, so we can recover the previous PC - // by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); - // Read the real second frame return address into frame.pc - if (first_frame_sp && - process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc), - error) == sizeof(frame.pc)) { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin() + 1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } - } - } - // uint32_t i=0; - // printf(" PC FP\n"); - // printf(" ------------------ ------------------ \n"); - // for (i=0; i<m_cursors.size(); ++i) - // { - // printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, - // m_cursors[i].pc, m_cursors[i].fp); - // } - return m_cursors.size(); -} - -size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64( - const ExecutionContext &exe_ctx) { - m_cursors.clear(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == nullptr) - return 0; - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - struct Frame_x86_64 { - uint64_t fp; - uint64_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert(reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP(0); - - Frame_x86_64 frame = {cursor.fp, cursor.pc}; - - m_cursors.push_back(cursor); - Status error; - const size_t k_frame_size = sizeof(frame); - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) { - // Read both the FP and PC (16 bytes) - if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) != - k_frame_size) - break; - - if (frame.pc >= 0x1000) { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back(cursor); - } - } - if (!m_cursors.empty()) { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const SymbolContextItem resolve_scope = - eSymbolContextModule | eSymbolContextCompUnit | - eSymbolContextFunction | eSymbolContextSymbol; - - SymbolContext first_frame_sc( - first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = nullptr; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize(first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) { - if (first_frame->GetFrameCodeAddress() == - addr_range_ptr->GetBaseAddress()) { - // We are at the first instruction, so we can recover the previous PC - // by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); - // Read the real second frame return address into frame.pc - if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc), - error) == sizeof(frame.pc)) { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin() + 1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } - } - } - return m_cursors.size(); -} diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h deleted file mode 100644 index f0bde90a53be7..0000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h +++ /dev/null @@ -1,54 +0,0 @@ -//===-- UnwindMacOSXFrameBackchain.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_UnwindMacOSXFrameBackchain_h_ -#define lldb_UnwindMacOSXFrameBackchain_h_ - -#include <vector> - -#include "lldb/Target/Unwind.h" -#include "lldb/lldb-private.h" - -class UnwindMacOSXFrameBackchain : public lldb_private::Unwind { -public: - UnwindMacOSXFrameBackchain(lldb_private::Thread &thread); - - ~UnwindMacOSXFrameBackchain() override = default; - -protected: - void DoClear() override { m_cursors.clear(); } - - uint32_t DoGetFrameCount() override; - - bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc, - bool &behaves_like_zeroth_frame) override; - - lldb::RegisterContextSP - DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; - - friend class RegisterContextMacOSXFrameBackchain; - - struct Cursor { - lldb::addr_t pc; // Program counter - lldb::addr_t fp; // Frame pointer for us with backchain - }; - -private: - std::vector<Cursor> m_cursors; - - size_t GetStackFrameData_i386(const lldb_private::ExecutionContext &exe_ctx); - - size_t - GetStackFrameData_x86_64(const lldb_private::ExecutionContext &exe_ctx); - - // For UnwindMacOSXFrameBackchain only - DISALLOW_COPY_AND_ASSIGN(UnwindMacOSXFrameBackchain); -}; - -#endif // lldb_UnwindMacOSXFrameBackchain_h_ diff --git a/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h index 39cbf01ea9d27..8f0eed4f02c90 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_arm_register_enums_h -#define lldb_arm_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -196,4 +196,4 @@ enum { }; } -#endif // #ifndef lldb_arm64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h index cc414dcde3cfe..39d47b8801ccf 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_arm64_register_enums_h -#define lldb_arm64_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -261,4 +261,4 @@ enum { }; } -#endif // #ifndef lldb_arm64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h index d97f771224267..e6a7efd00f678 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_mips_freebsd_register_enums_h -#define lldb_mips_freebsd_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -62,4 +62,4 @@ enum { k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1 }; } -#endif // #ifndef lldb_mips_freebsd_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h index 2f68b8022c9ae..348af27d28090 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_mips_linux_register_enums_h -#define lldb_mips_linux_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -357,4 +357,4 @@ enum { }; } -#endif // #ifndef lldb_mips_linux_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h index 6edf7ee3864d9..40a75c006d843 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ppc64_register_enums_h -#define lldb_ppc64_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -133,4 +133,4 @@ enum { k_num_vmx_registers_ppc64 = k_last_vmx_ppc64 - k_first_vmx_ppc64 + 1, }; -#endif // #ifndef lldb_ppc64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h index 0c381a5f39182..a7b5bc5ad9e34 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ppc64le_register_enums_h -#define lldb_ppc64le_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -204,4 +204,4 @@ enum { k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1, }; -#endif // #ifndef lldb_ppc64le_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h index bd66261082904..23c441e1c8038 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_s390x_register_enums_h -#define lldb_s390x_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -87,4 +87,4 @@ enum { }; } -#endif // #ifndef lldb_s390x_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h index bfdd586d9ded7..35f1a4075d09b 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_x86_register_enums_h -#define lldb_x86_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -113,7 +113,8 @@ enum { lldb_bndstatus_i386, k_last_mpxc_i386 = lldb_bndstatus_i386, - lldb_dr0_i386, + k_first_dbr_i386, + lldb_dr0_i386 = k_first_dbr_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, @@ -121,6 +122,7 @@ enum { lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, + k_last_dbr_i386 = lldb_dr7_i386, k_num_registers_i386, k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, @@ -131,6 +133,7 @@ enum { k_num_fpr_registers_i386 + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + k_num_dbr_registers_i386 = k_last_dbr_i386 - k_first_dbr_i386 + 1, }; // Internal codes for all x86_64 registers. @@ -318,4 +321,4 @@ enum { }; } -#endif // #ifndef lldb_x86_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H |