diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /source/Plugins/Process | |
parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) |
Notes
Diffstat (limited to 'source/Plugins/Process')
180 files changed, 3801 insertions, 1626 deletions
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp index 3505443abcb0a..70d9a5248fd9d 100644 --- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp +++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp @@ -19,10 +19,10 @@ // C++ includes // LLDB includes -#include "lldb/Core/State.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "CFBundle.h" @@ -63,12 +63,13 @@ Status NativeProcessProtocol::Launch( // Verify the working directory is valid if one was specified. FileSpec working_dir(launch_info.GetWorkingDirectory()); - if (working_dir && - (!working_dir.ResolvePath() || - !llvm::sys::fs::is_directory(working_dir.GetPath())) { - error.SetErrorStringWithFormat("No such file or directory: %s", + if (working_dir) { + FileInstance::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir)) { + error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); - return error; + return error; + } } // Launch the inferior. diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h index 0b186fd7d80cd..9abdd5360eba5 100644 --- a/source/Plugins/Process/Darwin/NativeProcessDarwin.h +++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h @@ -21,7 +21,6 @@ #include <mutex> #include <unordered_set> -// Other libraries and framework includes #include "lldb/Host/Debug.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Pipe.h" diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 3576a7f26f869..fce0be22678eb 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <errno.h> #include <pthread.h> #include <pthread_np.h> @@ -16,12 +15,9 @@ #include <sys/types.h> #include <sys/user.h> -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/State.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/State.h" -// Project includes #include "FreeBSDThread.h" #include "POSIXStopInfo.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -42,7 +38,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThread.h" @@ -50,6 +45,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" using namespace lldb; diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/source/Plugins/Process/FreeBSD/FreeBSDThread.h index c93cc4fbfd739..a8559fe8b2ca9 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.h +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.h @@ -10,11 +10,9 @@ #ifndef liblldb_FreeBSDThread_H_ #define liblldb_FreeBSDThread_H_ -// C++ Includes #include <memory> #include <string> -// Other libraries and framework includes #include "RegisterContextPOSIX.h" #include "lldb/Target/Thread.h" diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index fa0bcea8f6bde..a13d4bcc4ecb5 100644 --- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -8,7 +8,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <errno.h> #include <pthread.h> #include <pthread_np.h> @@ -18,18 +17,17 @@ #include <sys/user.h> #include <machine/elf.h> -// C++ Includes #include <mutex> #include <unordered_map> -// Other libraries and framework includes #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "FreeBSDThread.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -38,13 +36,11 @@ #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" -// Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" @@ -52,6 +48,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/State.h" #include "lldb/Host/posix/Fcntl.h" @@ -287,7 +284,7 @@ bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module ModuleSP exe_module_sp(target_sp->GetExecutableModule()); if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); // If there is no executable module, we return true since we might be // preparing to attach. return true; @@ -335,7 +332,7 @@ ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid, GetTarget().SetArchitecture(module_arch); // Initialize the target module list - GetTarget().SetExecutableModule(exe_module_sp, true); + GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes); SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); @@ -373,12 +370,13 @@ Status ProcessFreeBSD::DoLaunch(Module *module, assert(m_monitor == NULL); FileSpec working_dir = launch_info.GetWorkingDirectory(); - namespace fs = llvm::sys::fs; - if (working_dir && (!working_dir.ResolvePath() || - !fs::is_directory(working_dir.GetPath()))) { - error.SetErrorStringWithFormat("No such file or directory: %s", + if (working_dir) { + FileSystem::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) { + error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); - return error; + return error; + } } SetPrivateState(eStateLaunching); @@ -390,8 +388,7 @@ Status ProcessFreeBSD::DoLaunch(Module *module, FileSpec stdout_file_spec{}; FileSpec stderr_file_spec{}; - const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0), - false}; + const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)}; file_action = launch_info.GetFileActionForFD(STDIN_FILENO); stdin_file_spec = @@ -519,7 +516,7 @@ void ProcessFreeBSD::DoDidExec() { executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) return; - target->SetExecutableModule(exe_module_sp, true); + target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); } } } diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 51fdf2e5ef33e..617ae3030f105 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <errno.h> #include <poll.h> #include <signal.h> @@ -19,16 +18,14 @@ #include <sys/wait.h> #include <unistd.h> -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Host/Host.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "llvm/Support/Errno.h" diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 1d3e2d746fa96..ca7c4e03966c8 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -10,14 +10,11 @@ #ifndef liblldb_ProcessMonitor_H_ #define liblldb_ProcessMonitor_H_ -// C Includes #include <semaphore.h> #include <signal.h> -// C++ Includes #include <mutex> -// Other libraries and framework includes #include "lldb/Host/HostThread.h" #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-types.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h index b1b44e71de460..32973abd9207a 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h @@ -10,9 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_H_ #define liblldb_RegisterContextPOSIX_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/ArchSpec.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp index 8ddc253aea5d6..0642a30ade700 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp index 93ffeb5ea79ba..b35ee18d6a965 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "ProcessFreeBSD.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp index 734167e1fc98f..17df44cf85ee0 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "ProcessFreeBSD.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp index 5cc6cd2906291..a8d75963ea6b0 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp index 7db7f803b371a..68fd5ac13bb0b 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" #include "Plugins/Process/FreeBSD/ProcessMonitor.h" diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 3fb886e1c7a3a..8c6c95380e814 100644 --- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -9,29 +9,23 @@ #include "NativeProcessLinux.h" -// C Includes #include <errno.h> #include <stdint.h> #include <string.h> #include <unistd.h> -// C++ Includes #include <fstream> #include <mutex> #include <sstream> #include <string> #include <unordered_map> -// Other libraries and framework includes #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/ThreadLauncher.h" -#include "lldb/Host/common/NativeBreakpoint.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/linux/Ptrace.h" #include "lldb/Host/linux/Uio.h" @@ -41,6 +35,8 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringExtractor.h" #include "llvm/Support/Errno.h" @@ -49,6 +45,7 @@ #include "NativeThreadLinux.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" +#include "Plugins/Process/Utility/LinuxProcMaps.h" #include "Procfs.h" #include <linux/unistd.h> @@ -759,9 +756,7 @@ void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) { // Mark the thread as stopped at breakpoint. thread.SetStoppedByBreakpoint(); - Status error = FixupBreakpointPCAsNeeded(thread); - if (error.Fail()) - LLDB_LOG(log, "pid = {0} fixup: {1}", thread.GetID(), error); + FixupBreakpointPCAsNeeded(thread); if (m_threads_stepping_with_breakpoint.find(thread.GetID()) != m_threads_stepping_with_breakpoint.end()) @@ -1238,90 +1233,6 @@ Status NativeProcessLinux::Kill() { return error; } -static Status -ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef &maps_line, - MemoryRegionInfo &memory_region_info) { - memory_region_info.Clear(); - - StringExtractor line_extractor(maps_line); - - // Format: {address_start_hex}-{address_end_hex} perms offset dev inode - // pathname perms: rwxp (letter is present if set, '-' if not, final - // character is p=private, s=shared). - - // Parse out the starting address - lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0); - - // Parse out hyphen separating start and end address from range. - if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-')) - return Status( - "malformed /proc/{pid}/maps entry, missing dash between address range"); - - // Parse out the ending address - lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address); - - // Parse out the space after the address. - if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' ')) - return Status( - "malformed /proc/{pid}/maps entry, missing space after range"); - - // Save the range. - memory_region_info.GetRange().SetRangeBase(start_address); - memory_region_info.GetRange().SetRangeEnd(end_address); - - // Any memory region in /proc/{pid}/maps is by definition mapped into the - // process. - memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); - - // Parse out each permission entry. - if (line_extractor.GetBytesLeft() < 4) - return Status("malformed /proc/{pid}/maps entry, missing some portion of " - "permissions"); - - // Handle read permission. - const char read_perm_char = line_extractor.GetChar(); - if (read_perm_char == 'r') - memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); - else if (read_perm_char == '-') - memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); - else - return Status("unexpected /proc/{pid}/maps read permission char"); - - // Handle write permission. - const char write_perm_char = line_extractor.GetChar(); - if (write_perm_char == 'w') - memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); - else if (write_perm_char == '-') - memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); - else - return Status("unexpected /proc/{pid}/maps write permission char"); - - // Handle execute permission. - const char exec_perm_char = line_extractor.GetChar(); - if (exec_perm_char == 'x') - memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); - else if (exec_perm_char == '-') - memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); - else - return Status("unexpected /proc/{pid}/maps exec permission char"); - - line_extractor.GetChar(); // Read the private bit - line_extractor.SkipSpaces(); // Skip the separator - line_extractor.GetHexMaxU64(false, 0); // Read the offset - line_extractor.GetHexMaxU64(false, 0); // Read the major device number - line_extractor.GetChar(); // Read the device id separator - line_extractor.GetHexMaxU64(false, 0); // Read the major device number - line_extractor.SkipSpaces(); // Skip the separator - line_extractor.GetU64(0, 10); // Read the inode number - - line_extractor.SkipSpaces(); - const char *name = line_extractor.Peek(); - if (name) - memory_region_info.SetName(name); - - return Status(); -} - Status NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) { // FIXME review that the final memory region returned extends to the end of @@ -1407,22 +1318,23 @@ Status NativeProcessLinux::PopulateMemoryRegionCache() { m_supports_mem_region = LazyBool::eLazyBoolNo; return BufferOrError.getError(); } - StringRef Rest = BufferOrError.get()->getBuffer(); - while (! Rest.empty()) { - StringRef Line; - std::tie(Line, Rest) = Rest.split('\n'); - MemoryRegionInfo info; - const Status parse_error = - ParseMemoryRegionInfoFromProcMapsLine(Line, info); - if (parse_error.Fail()) { - LLDB_LOG(log, "failed to parse proc maps line '{0}': {1}", Line, - parse_error); - m_supports_mem_region = LazyBool::eLazyBoolNo; - return parse_error; - } - m_mem_region_cache.emplace_back( - info, FileSpec(info.GetName().GetCString(), true)); - } + Status Result; + ParseLinuxMapRegions(BufferOrError.get()->getBuffer(), + [&](const MemoryRegionInfo &Info, const Status &ST) { + if (ST.Success()) { + FileSpec file_spec(Info.GetName().GetCString()); + FileSystem::Instance().Resolve(file_spec); + m_mem_region_cache.emplace_back(Info, file_spec); + return true; + } else { + m_supports_mem_region = LazyBool::eLazyBoolNo; + LLDB_LOG(log, "failed to parse proc maps: {0}", ST); + Result = ST; + return false; + } + }); + if (Result.Fail()) + return Result; if (m_mem_region_cache.empty()) { // No entries after attempting to read them. This shouldn't happen if @@ -1502,40 +1414,6 @@ size_t NativeProcessLinux::UpdateThreads() { return m_threads.size(); } -Status NativeProcessLinux::GetSoftwareBreakpointPCOffset( - uint32_t &actual_opcode_size) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. - static const uint8_t g_i386_opcode[] = {0xCC}; - static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; - - switch (m_arch.GetMachine()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode)); - return Status(); - - case llvm::Triple::systemz: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode)); - return Status(); - - case llvm::Triple::arm: - case llvm::Triple::aarch64: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::ppc64le: - // On these architectures the PC don't get updated for breakpoint hits - actual_opcode_size = 0; - return Status(); - - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - Status NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) { if (hardware) @@ -1551,74 +1429,26 @@ Status NativeProcessLinux::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { return NativeProcessProtocol::RemoveBreakpoint(addr); } -Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode( - size_t trap_opcode_size_hint, size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) { - // FIXME put this behind a breakpoint protocol class that can be set per - // architecture. Need MIPS support here. - static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4}; +llvm::Expected<llvm::ArrayRef<uint8_t>> +NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the // linux kernel does otherwise. - static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; - static const uint8_t g_i386_opcode[] = {0xCC}; - static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d}; - static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00}; - static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; - static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; - static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap - - switch (m_arch.GetMachine()) { - case llvm::Triple::aarch64: - trap_opcode_bytes = g_aarch64_opcode; - actual_opcode_size = sizeof(g_aarch64_opcode); - return Status(); + static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; + static const uint8_t g_thumb_opcode[] = {0x01, 0xde}; + switch (GetArchitecture().GetMachine()) { case llvm::Triple::arm: - switch (trap_opcode_size_hint) { + switch (size_hint) { case 2: - trap_opcode_bytes = g_thumb_breakpoint_opcode; - actual_opcode_size = sizeof(g_thumb_breakpoint_opcode); - return Status(); + return llvm::makeArrayRef(g_thumb_opcode); case 4: - trap_opcode_bytes = g_arm_breakpoint_opcode; - actual_opcode_size = sizeof(g_arm_breakpoint_opcode); - return Status(); + return llvm::makeArrayRef(g_arm_opcode); default: - assert(false && "Unrecognised trap opcode size hint!"); - return Status("Unrecognised trap opcode size hint!"); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unrecognised trap opcode size hint!"); } - - case llvm::Triple::x86: - case llvm::Triple::x86_64: - trap_opcode_bytes = g_i386_opcode; - actual_opcode_size = sizeof(g_i386_opcode); - return Status(); - - case llvm::Triple::mips: - case llvm::Triple::mips64: - trap_opcode_bytes = g_mips64_opcode; - actual_opcode_size = sizeof(g_mips64_opcode); - return Status(); - - case llvm::Triple::mipsel: - case llvm::Triple::mips64el: - trap_opcode_bytes = g_mips64el_opcode; - actual_opcode_size = sizeof(g_mips64el_opcode); - return Status(); - - case llvm::Triple::systemz: - trap_opcode_bytes = g_s390x_opcode; - actual_opcode_size = sizeof(g_s390x_opcode); - return Status(); - - case llvm::Triple::ppc64le: - trap_opcode_bytes = g_ppc64le_opcode; - actual_opcode_size = sizeof(g_ppc64le_opcode); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); + return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint); } } @@ -1677,15 +1507,6 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return Status(); } -Status NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, - size_t size, - size_t &bytes_read) { - Status error = ReadMemory(addr, buf, size, bytes_read); - if (error.Fail()) - return error; - return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size); -} - Status NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { const unsigned char *src = static_cast<const unsigned char *>(buf); @@ -1810,90 +1631,14 @@ NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) { return static_cast<NativeThreadLinux &>(*m_threads.back()); } -Status -NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); - - Status error; - - // Find out the size of a breakpoint (might depend on where we are in the - // code). - NativeRegisterContext &context = thread.GetRegisterContext(); - - uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointPCOffset(breakpoint_size); - if (error.Fail()) { - LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error); - return error; - } else - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); - - // First try probing for a breakpoint at a software breakpoint location: PC - - // breakpoint size. - const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation(); - lldb::addr_t breakpoint_addr = initial_pc_addr; - if (breakpoint_size > 0) { - // Do not allow breakpoint probe to wrap around. - if (breakpoint_addr >= breakpoint_size) - breakpoint_addr -= breakpoint_size; - } - - // Check if we stopped because of a breakpoint. - NativeBreakpointSP breakpoint_sp; - error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); - if (!error.Success() || !breakpoint_sp) { - // We didn't find one at a software probe location. Nothing to do. - LLDB_LOG(log, - "pid {0} no lldb breakpoint found at current pc with " - "adjustment: {1}", - GetID(), breakpoint_addr); - return Status(); - } - - // If the breakpoint is not a software breakpoint, nothing to do. - if (!breakpoint_sp->IsSoftwareBreakpoint()) { - LLDB_LOG( - log, - "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", - GetID(), breakpoint_addr); - return Status(); - } - - // - // We have a software breakpoint and need to adjust the PC. - // - - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - - // Change the program counter. - LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), - thread.GetID(), initial_pc_addr, breakpoint_addr); - - error = context.SetPC(breakpoint_addr); - if (error.Fail()) { - LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), - thread.GetID(), error); - return error; - } - - return error; -} - Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) { Status error = PopulateMemoryRegionCache(); if (error.Fail()) return error; - FileSpec module_file_spec(module_path, true); + FileSpec module_file_spec(module_path); + FileSystem::Instance().Resolve(module_file_spec); file_spec.Clear(); for (const auto &it : m_mem_region_cache) { @@ -1913,7 +1658,7 @@ Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name, if (error.Fail()) return error; - FileSpec file(file_name, false); + FileSpec file(file_name); for (const auto &it : m_mem_region_cache) { if (it.second == file) { load_addr = it.first.GetRange().GetRangeBase(); diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h index 1c2f786e8d697..69f2b528d3300 100644 --- a/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -71,9 +71,6 @@ public: Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; - Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, - size_t &bytes_read) override; - Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; @@ -134,13 +131,8 @@ public: bool SupportHardwareSingleStepping() const; protected: - // --------------------------------------------------------------------- - // NativeProcessProtocol protected interface - // --------------------------------------------------------------------- - Status - GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, - size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) override; + llvm::Expected<llvm::ArrayRef<uint8_t>> + GetSoftwareBreakpointTrapOpcode(size_t size_hint) override; private: MainLoop::SignalHandleUP m_sigchld_handle; @@ -190,10 +182,6 @@ private: NativeThreadLinux &AddThread(lldb::tid_t thread_id); - Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); - - Status FixupBreakpointPCAsNeeded(NativeThreadLinux &thread); - /// Writes a siginfo_t structure corresponding to the given thread ID to the /// memory region pointed to by @p siginfo. Status GetSignalInfo(lldb::tid_t tid, void *siginfo); diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp index c8a8355f9cb99..79f635c88985b 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp @@ -9,10 +9,10 @@ #include "NativeRegisterContextLinux.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Host/linux/Ptrace.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index 7492916846209..09d3a12942f05 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -15,9 +15,9 @@ #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include <elf.h> diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 41fe446f728c7..9a392edbe9ef3 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -12,14 +12,11 @@ #include "NativeRegisterContextLinux_arm.h" #include "NativeRegisterContextLinux_arm64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp index 69194b3c06630..d641056a04401 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -11,22 +11,19 @@ #include "NativeRegisterContextLinux_mips64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/RegisterContextLinux_mips.h" #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp index 6aa4af64ab51b..da51fda1c80b3 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp @@ -14,10 +14,10 @@ #include "NativeRegisterContextLinux_ppc64le.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp index 36da2b001054b..1bc916b69bcd1 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextLinux_s390x.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp index 87f4b8da053ee..50bf29b094df0 100755 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextLinux_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp index 4ab2a9ae62454..b64689c9d17b0 100644 --- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -16,12 +16,12 @@ #include "NativeRegisterContextLinux.h" #include "SingleStepCheck.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostNativeThread.h" #include "lldb/Host/linux/Ptrace.h" #include "lldb/Host/linux/Support.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/SmallString.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index 116155d9a2324..8908108eff4bd 100644 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -9,25 +9,21 @@ #include "CommunicationKDP.h" -// C Includes #include <errno.h> #include <limits.h> #include <string.h> -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Target/Process.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/UUID.h" -// Project includes #include "ProcessKDPLog.h" using namespace lldb; @@ -467,19 +463,13 @@ lldb_private::UUID CommunicationKDP::GetUUID() { bool CommunicationKDP::RemoteIsEFI() { if (GetKernelVersion() == NULL) return false; - if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0) - return true; - else - return false; + return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0; } bool CommunicationKDP::RemoteIsDarwinKernel() { if (GetKernelVersion() == NULL) return false; - if (m_kernel_version.find("Darwin Kernel") != std::string::npos) - return true; - else - return false; + return m_kernel_version.find("Darwin Kernel") != std::string::npos; } lldb::addr_t CommunicationKDP::GetLoadAddress() { @@ -1262,9 +1252,7 @@ bool CommunicationKDP::SendRequestResume() { request_packet.PutHex32(GetCPUMask()); DataExtractor reply_packet; - if (SendRequestAndGetReply(command, request_packet, reply_packet)) - return true; - return false; + return SendRequestAndGetReply(command, request_packet, reply_packet); } bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) { @@ -1297,7 +1285,5 @@ bool CommunicationKDP::SendRequestSuspend() { const uint32_t command_length = 8; MakeRequestPacketHeader(command, request_packet, command_length); DataExtractor reply_packet; - if (SendRequestAndGetReply(command, request_packet, reply_packet)) - return true; - return false; + return SendRequestAndGetReply(command, request_packet, reply_packet); } diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index afac6601a56b2..64bfe55147350 100644 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -10,18 +10,14 @@ #ifndef liblldb_CommunicationKDP_h_ #define liblldb_CommunicationKDP_h_ -// C Includes -// C++ Includes #include <list> #include <mutex> #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Core/Communication.h" -#include "lldb/Core/Listener.h" #include "lldb/Core/StreamBuffer.h" -#include "lldb/Host/Predicate.h" +#include "lldb/Utility/Listener.h" +#include "lldb/Utility/Predicate.h" #include "lldb/lldb-private.h" class CommunicationKDP : public lldb_private::Communication { diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 2e707ab2e3633..c1c3678617c09 100644 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -7,20 +7,15 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <errno.h> #include <stdlib.h> -// C++ Includes #include <mutex> -// Other libraries and framework includes #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Utility/UUID.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" @@ -37,13 +32,14 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StringExtractor.h" +#include "lldb/Utility/UUID.h" #include "llvm/Support/Threading.h" #define USEC_PER_SEC 1000000 -// Project includes #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" #include "ProcessKDP.h" @@ -55,10 +51,9 @@ using namespace lldb_private; namespace { -static PropertyDefinition g_properties[] = { - {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, NULL, - "Specify the default packet timeout in seconds."}, - {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; +static constexpr PropertyDefinition g_properties[] = { + {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {}, + "Specify the default packet timeout in seconds."}}; enum { ePropertyPacketTimeout }; @@ -301,7 +296,8 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { if (module_spec.GetSymbolFileSpec()) { ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile(module_spec); - if (executable_module_spec.GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists( + executable_module_spec.GetFileSpec())) { module_spec.GetFileSpec() = executable_module_spec.GetFileSpec(); } @@ -310,7 +306,7 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { !module_spec.GetSymbolFileSpec()) Symbols::DownloadObjectAndSymbolFile(module_spec, true); - if (module_spec.GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { ModuleSP module_sp(new Module(module_spec)); if (module_sp.get() && module_sp->GetObjectFile()) { // Get the current target executable @@ -319,7 +315,7 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { // Make sure you don't already have the right module loaded // and they will be uniqued if (exe_module_sp.get() != module_sp.get()) - target.SetExecutableModule(module_sp, false); + target.SetExecutableModule(module_sp, eLoadDependentsNo); } } } diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index b4eae58af83cc..f9102442de935 100644 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -10,19 +10,16 @@ #ifndef liblldb_ProcessKDP_h_ #define liblldb_ProcessKDP_h_ -// C Includes -// C++ Includes #include <list> #include <vector> -// Other libraries and framework includes -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp index 159a046b617d9..0f9e62ce355a0 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp @@ -9,10 +9,6 @@ #include "RegisterContextKDP_arm.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "ProcessKDP.h" #include "ThreadKDP.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h index fe02b0648221d..1532f23207f42 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h @@ -10,11 +10,7 @@ #ifndef liblldb_RegisterContextKDP_arm_h_ #define liblldb_RegisterContextKDP_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" class ThreadKDP; diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp index 44534a252568b..e13a7f3ad9079 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp @@ -10,10 +10,6 @@ #include "RegisterContextKDP_arm64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "ProcessKDP.h" #include "ThreadKDP.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h index 0922654de2ccc..be4038ba96eaf 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h @@ -11,11 +11,7 @@ #ifndef liblldb_RegisterContextKDP_arm64_h_ #define liblldb_RegisterContextKDP_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h" class ThreadKDP; diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp index e48232ad8ddac..096aa0f95d009 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextKDP_i386.h" #include "ProcessKDP.h" #include "ThreadKDP.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h index 5803670a08b4d..699d5fabe1570 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextKDP_i386_h_ #define liblldb_RegisterContextKDP_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" class ThreadKDP; diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp index 50e11f381925a..9d85145f2eaf2 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextKDP_x86_64.h" #include "ProcessKDP.h" #include "ThreadKDP.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h index 7a40bb6263853..9841ad77b0044 100644 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h +++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextKDP_x86_64_h_ #define liblldb_RegisterContextKDP_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h" class ThreadKDP; diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp index 7fca0fc24fdbf..6f26acd0b8aa7 100644 --- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp @@ -9,10 +9,9 @@ #include "ThreadKDP.h" -#include "lldb/Utility/SafeMachO.h" +#include "lldb/Host/SafeMachO.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" @@ -20,6 +19,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "Plugins/Process/Utility/StopInfoMachException.h" diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt index 92a6014ced07a..e131e6d70468b 100644 --- a/source/Plugins/Process/NetBSD/CMakeLists.txt +++ b/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -5,7 +5,6 @@ add_lldb_library(lldbPluginProcessNetBSD PLUGIN NativeThreadNetBSD.cpp LINK_LIBS - lldbCore lldbHost lldbSymbol lldbTarget diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 1a4cb21d000e0..a1b7d7df4553c 100644 --- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -9,18 +9,14 @@ #include "NativeProcessNetBSD.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostProcess.h" -#include "lldb/Host/common/NativeBreakpoint.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/posix/ProcessLauncherPosixFork.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/State.h" #include "llvm/Support/Errno.h" // System includes - They have to be included after framework includes because @@ -322,100 +318,6 @@ Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, return error; } -Status NativeProcessNetBSD::GetSoftwareBreakpointPCOffset( - uint32_t &actual_opcode_size) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. - static const uint8_t g_i386_opcode[] = {0xCC}; - switch (m_arch.GetMachine()) { - case llvm::Triple::x86_64: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode)); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - -Status -NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); - Status error; - // Find out the size of a breakpoint (might depend on where we are in the - // code). - NativeRegisterContext& context = thread.GetRegisterContext(); - uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointPCOffset(breakpoint_size); - if (error.Fail()) { - LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error); - return error; - } else - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); - // First try probing for a breakpoint at a software breakpoint location: PC - - // breakpoint size. - const lldb::addr_t initial_pc_addr = - context.GetPCfromBreakpointLocation(); - lldb::addr_t breakpoint_addr = initial_pc_addr; - if (breakpoint_size > 0) { - // Do not allow breakpoint probe to wrap around. - if (breakpoint_addr >= breakpoint_size) - breakpoint_addr -= breakpoint_size; - } - // Check if we stopped because of a breakpoint. - NativeBreakpointSP breakpoint_sp; - error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); - if (!error.Success() || !breakpoint_sp) { - // We didn't find one at a software probe location. Nothing to do. - LLDB_LOG(log, - "pid {0} no lldb breakpoint found at current pc with " - "adjustment: {1}", - GetID(), breakpoint_addr); - return Status(); - } - // If the breakpoint is not a software breakpoint, nothing to do. - if (!breakpoint_sp->IsSoftwareBreakpoint()) { - LLDB_LOG( - log, - "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // Change the program counter. - LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), - thread.GetID(), initial_pc_addr, breakpoint_addr); - error = context.SetPC(breakpoint_addr); - if (error.Fail()) { - LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), - thread.GetID(), error); - return error; - } - return error; -} - Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); LLDB_LOG(log, "pid {0}", GetID()); @@ -637,7 +539,7 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() { info.SetName(vm[i].kve_path); m_mem_region_cache.emplace_back( - info, FileSpec(info.GetName().GetCString(), true)); + info, FileSpec(info.GetName().GetCString())); } free(vm); @@ -682,23 +584,6 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size, return SetSoftwareBreakpoint(addr, size); } -Status NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode( - size_t trap_opcode_size_hint, size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) { - static const uint8_t g_i386_opcode[] = {0xCC}; - - switch (m_arch.GetMachine()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - trap_opcode_bytes = g_i386_opcode; - actual_opcode_size = sizeof(g_i386_opcode); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) { return Status("Unimplemented"); @@ -824,15 +709,6 @@ Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, return Status(); } -Status NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, - size_t size, - size_t &bytes_read) { - Status error = ReadMemory(addr, buf, size, bytes_read); - if (error.Fail()) - return error; - return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size); -} - Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { const unsigned char *src = static_cast<const unsigned char *>(buf); diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 142f74ecf1947..a3f1c4c6a06a3 100644 --- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -58,9 +58,6 @@ public: Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; - Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, - size_t &bytes_read) override; - Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; @@ -93,16 +90,6 @@ public: static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, int data = 0, int *result = nullptr); -protected: - // --------------------------------------------------------------------- - // NativeProcessProtocol protected interface - // --------------------------------------------------------------------- - - Status - GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, - size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) override; - private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; @@ -125,8 +112,6 @@ private: void MonitorSIGTRAP(lldb::pid_t pid); void MonitorSignal(lldb::pid_t pid, int signal); - Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); - Status FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread); Status PopulateMemoryRegionCache(); void SigchldHandler(); diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index 16b6f2c52dd5e..78da3527122f8 100644 --- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextNetBSD_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index 83f1da78d01d0..6f5d1120e40da 100644 --- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -14,9 +14,9 @@ #include "Plugins/Process/POSIX/CrashReason.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include <sstream> diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index 134013517a110..3ac798b3d4b3d 100644 --- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -11,11 +11,7 @@ #ifndef liblldb_ProcessPOSIXLog_h_ #define liblldb_ProcessPOSIXLog_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define POSIX_LOG_PROCESS (1u << 1) diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h index 2bbd519b246a4..2c14dc936cbc2 100644 --- a/source/Plugins/Process/Utility/ARMUtils.h +++ b/source/Plugins/Process/Utility/ARMUtils.h @@ -12,7 +12,7 @@ #include "ARMDefines.h" #include "InstructionUtils.h" -#include "llvm/Support/MathExtras.h" // for SignExtend64 template function +#include "llvm/Support/MathExtras.h" // Common utilities for the ARM/Thumb Instruction Set Architecture. diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt index b43756acea634..e36ce4dec98a8 100644 --- a/source/Plugins/Process/Utility/CMakeLists.txt +++ b/source/Plugins/Process/Utility/CMakeLists.txt @@ -5,6 +5,7 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN HistoryThread.cpp HistoryUnwind.cpp InferiorCallPOSIX.cpp + LinuxProcMaps.cpp LinuxSignals.cpp MipsLinuxSignals.cpp NativeRegisterContextRegisterInfo.cpp diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 5f34e9915edee..dcbf474fa55ab 100644 --- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -464,7 +464,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { end = m_value_regs_map.end(); pos != end; ++pos) { if (pos->second.size() > 1) { - std::sort(pos->second.begin(), pos->second.end()); + llvm::sort(pos->second.begin(), pos->second.end()); reg_num_collection::iterator unique_end = std::unique(pos->second.begin(), pos->second.end()); if (unique_end != pos->second.end()) @@ -514,7 +514,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { end = m_invalidate_regs_map.end(); pos != end; ++pos) { if (pos->second.size() > 1) { - std::sort(pos->second.begin(), pos->second.end()); + llvm::sort(pos->second.begin(), pos->second.end()); reg_num_collection::iterator unique_end = std::unique(pos->second.begin(), pos->second.end()); if (unique_end != pos->second.end()) diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h index acb3e3eb8a84e..68f3902e0c961 100644 --- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -10,13 +10,9 @@ #ifndef lldb_DynamicRegisterInfo_h_ #define lldb_DynamicRegisterInfo_h_ -// C Includes -// C++ Includes #include <map> #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp index f695a11c97590..0b56b6093559b 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "FreeBSDSignals.h" using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h index 8ec96e824f7a1..174025cabb82a 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -10,7 +10,6 @@ #ifndef liblldb_FreeBSDSignals_H_ #define liblldb_FreeBSDSignals_H_ -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp index abcc8a38669a3..cc0537c2a8b34 100644 --- a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "GDBRemoteSignals.h" using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h index 5900fa75d6f21..79d8ec3fbbafa 100644 --- a/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -10,10 +10,6 @@ #ifndef liblldb_GDBRemoteSignals_H_ #define liblldb_GDBRemoteSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h index 7675a95246a7e..dc24922e7c17e 100644 --- a/source/Plugins/Process/Utility/HistoryThread.h +++ b/source/Plugins/Process/Utility/HistoryThread.h @@ -10,18 +10,14 @@ #ifndef liblldb_HistoryThread_h_ #define liblldb_HistoryThread_h_ -// C Includes -// C++ Includes #include <mutex> -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Event.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrameList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h index 3b64e38bfaa70..2cbfb680ef49c 100644 --- a/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/source/Plugins/Process/Utility/HistoryUnwind.h @@ -10,12 +10,8 @@ #ifndef liblldb_HistoryUnwind_h_ #define liblldb_HistoryUnwind_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Unwind.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/source/Plugins/Process/Utility/LinuxProcMaps.cpp new file mode 100644 index 0000000000000..d45bf6dcd84fc --- /dev/null +++ b/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -0,0 +1,113 @@ +//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LinuxProcMaps.h" +#include "llvm/ADT/StringRef.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StringExtractor.h" + +using namespace lldb_private; + +static Status +ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line, + MemoryRegionInfo &memory_region_info) { + memory_region_info.Clear(); + + StringExtractor line_extractor(maps_line); + + // Format: {address_start_hex}-{address_end_hex} perms offset dev inode + // pathname perms: rwxp (letter is present if set, '-' if not, final + // character is p=private, s=shared). + + // Parse out the starting address + lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0); + + // Parse out hyphen separating start and end address from range. + if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-')) + return Status( + "malformed /proc/{pid}/maps entry, missing dash between address range"); + + // Parse out the ending address + lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address); + + // Parse out the space after the address. + if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' ')) + return Status( + "malformed /proc/{pid}/maps entry, missing space after range"); + + // Save the range. + memory_region_info.GetRange().SetRangeBase(start_address); + memory_region_info.GetRange().SetRangeEnd(end_address); + + // Any memory region in /proc/{pid}/maps is by definition mapped into the + // process. + memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); + + // Parse out each permission entry. + if (line_extractor.GetBytesLeft() < 4) + return Status("malformed /proc/{pid}/maps entry, missing some portion of " + "permissions"); + + // Handle read permission. + const char read_perm_char = line_extractor.GetChar(); + if (read_perm_char == 'r') + memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); + else if (read_perm_char == '-') + memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps read permission char"); + + // Handle write permission. + const char write_perm_char = line_extractor.GetChar(); + if (write_perm_char == 'w') + memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); + else if (write_perm_char == '-') + memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps write permission char"); + + // Handle execute permission. + const char exec_perm_char = line_extractor.GetChar(); + if (exec_perm_char == 'x') + memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); + else if (exec_perm_char == '-') + memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps exec permission char"); + + line_extractor.GetChar(); // Read the private bit + line_extractor.SkipSpaces(); // Skip the separator + line_extractor.GetHexMaxU64(false, 0); // Read the offset + line_extractor.GetHexMaxU64(false, 0); // Read the major device number + line_extractor.GetChar(); // Read the device id separator + line_extractor.GetHexMaxU64(false, 0); // Read the major device number + line_extractor.SkipSpaces(); // Skip the separator + line_extractor.GetU64(0, 10); // Read the inode number + + line_extractor.SkipSpaces(); + const char *name = line_extractor.Peek(); + if (name) + memory_region_info.SetName(name); + + return Status(); +} + +void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map, + LinuxMapCallback const &callback) { + llvm::StringRef lines(linux_map); + llvm::StringRef line; + while (!lines.empty()) { + std::tie(line, lines) = lines.split('\n'); + MemoryRegionInfo region; + Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region); + if (!callback(region, error)) + break; + } +} diff --git a/source/Plugins/Process/Utility/LinuxProcMaps.h b/source/Plugins/Process/Utility/LinuxProcMaps.h new file mode 100644 index 0000000000000..e6eabb28fc825 --- /dev/null +++ b/source/Plugins/Process/Utility/LinuxProcMaps.h @@ -0,0 +1,28 @@ +//===-- LinuxProcMaps.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_LinuxProcMaps_H_ +#define liblldb_LinuxProcMaps_H_ + +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include <functional> + + +namespace lldb_private { + +typedef std::function<bool(const lldb_private::MemoryRegionInfo &, + const lldb_private::Status &)> LinuxMapCallback; + +void ParseLinuxMapRegions(llvm::StringRef linux_map, + LinuxMapCallback const &callback); + +} // namespace lldb_private + +#endif // liblldb_LinuxProcMaps_H_ diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp index eb01075ed1332..6f1f67ac35706 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LinuxSignals.h" using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h index e41126225cee1..f93a9d2e36d19 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.h +++ b/source/Plugins/Process/Utility/LinuxSignals.h @@ -10,10 +10,6 @@ #ifndef liblldb_LinuxSignals_H_ #define liblldb_LinuxSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index 36231023aa3a4..b6f3b34893bf2 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -8,9 +8,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "MipsLinuxSignals.h" using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h index e48ea5943f2be..2796f6b8e4d7e 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -11,10 +11,6 @@ #ifndef liblldb_MipsLinuxSignals_H_ #define liblldb_MipsLinuxSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/NetBSDSignals.cpp b/source/Plugins/Process/Utility/NetBSDSignals.cpp index 7ed7189d80489..a4baab9ac85f9 100644 --- a/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "NetBSDSignals.h" using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/NetBSDSignals.h b/source/Plugins/Process/Utility/NetBSDSignals.h index 4338f881645e8..7bb57fa0c0d66 100644 --- a/source/Plugins/Process/Utility/NetBSDSignals.h +++ b/source/Plugins/Process/Utility/NetBSDSignals.h @@ -10,7 +10,6 @@ #ifndef liblldb_NetBSDSignals_H_ #define liblldb_NetBSDSignals_H_ -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 5d9ff02fafdd2..9ad896abd0b4c 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -10,14 +10,12 @@ #include "RegisterContextDarwin_arm.h" #include "RegisterContextDarwinConstants.h" -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "Plugins/Process/Utility/InstructionUtils.h" @@ -28,7 +26,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "Utility/ARM_DWARF_Registers.h" #include "Utility/ARM_ehframe_Registers.h" @@ -1673,7 +1670,7 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr, return LLDB_INVALID_INDEX32; // We must watch for either read or write - if (read == false && write == false) + if (!read && !write) return LLDB_INVALID_INDEX32; // Can't watch more than 4 bytes per WVR/WCR pair diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index cdf3479dff690..b46946d608bc2 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_arm_h_ #define liblldb_RegisterContextDarwin_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 03ce7ef9f5240..b478645e035df 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -11,16 +11,14 @@ #include "RegisterContextDarwin_arm64.h" #include "RegisterContextDarwinConstants.h" -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -32,7 +30,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "Utility/ARM64_DWARF_Registers.h" using namespace lldb; @@ -341,12 +338,22 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, case gpr_x26: case gpr_x27: case gpr_x28: + value.SetUInt64(gpr.x[reg - gpr_x0]); + break; case gpr_fp: + value.SetUInt64(gpr.fp); + break; case gpr_sp: + value.SetUInt64(gpr.sp); + break; case gpr_lr: + value.SetUInt64(gpr.lr); + break; case gpr_pc: + value.SetUInt64(gpr.pc); + break; case gpr_cpsr: - value.SetUInt64(gpr.x[reg - gpr_x0]); + value.SetUInt64(gpr.cpsr); break; case gpr_w0: @@ -949,7 +956,7 @@ uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr, return LLDB_INVALID_INDEX32; // We must watch for either read or write - if (read == false && write == false) + if (!read && !write) return LLDB_INVALID_INDEX32; // Can't watch more than 4 bytes per WVR/WCR pair diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index 4a0e50947ee70..9e826d85af085 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextDarwin_arm64_h_ #define liblldb_RegisterContextDarwin_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 24414211d9aa8..c9e4b37a17f36 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -7,17 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes -#include <stddef.h> // offsetof +#include <stddef.h> -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -27,7 +24,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "RegisterContextDarwin_i386.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index aea8a29009116..ad6a1e48fc34a 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_i386_h_ #define liblldb_RegisterContextDarwin_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index ecad8240b2944..95460308857a9 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -7,19 +7,16 @@ // //===----------------------------------------------------------------------===// -// C Includes -#include <inttypes.h> // PRIx64 +#include <inttypes.h> #include <stdarg.h> -#include <stddef.h> // offsetof +#include <stddef.h> -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -29,7 +26,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "RegisterContextDarwin_x86_64.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index fdd5e8036dee1..6d94bf75aad4b 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_x86_64_h_ #define liblldb_RegisterContextDarwin_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/source/Plugins/Process/Utility/RegisterContextDummy.cpp index dd6ca92a74ee2..c51c30f45a5de 100644 --- a/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #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 "RegisterContextDummy.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.h b/source/Plugins/Process/Utility/RegisterContextDummy.h index ea70288f3d691..d5608616c896c 100644 --- a/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextDummy_h_ #define lldb_RegisterContextDummy_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h index c9a65b1cacceb..b74d0ea75469f 100644 --- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h +++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextFreeBSD_powerpc_h_ #define liblldb_RegisterContextFreeBSD_powerpc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" class RegisterContextFreeBSD_powerpc diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp index cc0d696b338a5..c9b77663a8038 100644 --- a/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #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 "RegisterContextHistory.h" diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.h b/source/Plugins/Process/Utility/RegisterContextHistory.h index acaf8fe5c04a1..01b3624f8c5b8 100644 --- a/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextHistory_h_ #define lldb_RegisterContextHistory_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index ba9a8071bcfbc..8c420a87e1b03 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -10,7 +10,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ArmUnwindInfo.h" @@ -31,6 +30,7 @@ #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" @@ -54,7 +54,8 @@ RegisterContextLLDB::RegisterContextLLDB(Thread &thread, : 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_start_pc(), + 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) { @@ -150,7 +151,8 @@ void RegisterContextLLDB::InitializeZerothFrame() { // We require either a symbol or function in the symbols context to be // successfully filled in or this context is of no use to us. - const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + const SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress( m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope)) { @@ -227,7 +229,7 @@ void RegisterContextLLDB::InitializeZerothFrame() { return; } - if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) { + 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; @@ -255,12 +257,14 @@ void RegisterContextLLDB::InitializeZerothFrame() { 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 - " using %s UnwindPlan", + " 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()); } @@ -320,7 +324,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { above_trap_handler = true; if (pc == 0 || pc == 0x1) { - if (above_trap_handler == false) { + if (!above_trap_handler) { m_frame_type = eNotAValidFrame; UnwindLogMsg("this frame has a pc of 0x0"); return; @@ -378,7 +382,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); if (row.get()) { - if (!ReadCFAValueForRow(row_register_kind, row, m_cfa)) { + if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) { UnwindLogMsg("failed to get cfa value"); if (m_frame_type != eSkipFrame) // don't override eSkipFrame { @@ -387,6 +391,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { 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"); @@ -419,7 +425,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { } } - UnwindLogMsg("initialized frame cfa is 0x%" PRIx64, (uint64_t)m_cfa); + UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, + (uint64_t)m_cfa, (uint64_t)m_afa); return; } m_frame_type = eNotAValidFrame; @@ -436,7 +443,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { // then we might not find the correct unwind information later. Instead, let // ResolveSymbolContextForAddress fail, and handle the case via // decr_pc_and_recompute_addr_range below. - const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + const SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress( m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address); @@ -466,7 +474,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { bool decr_pc_and_recompute_addr_range = false; // If the symbol lookup failed... - if (m_sym_ctx_valid == false) + if (!m_sym_ctx_valid) decr_pc_and_recompute_addr_range = true; // Or if we're in the middle of the stack (and not "above" an asynchronous @@ -494,7 +502,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); m_sym_ctx.Clear(false); m_sym_ctx_valid = false; - uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; ModuleSP temporary_module_sp = temporary_pc.GetModule(); if (temporary_module_sp && @@ -581,13 +590,15 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { return; } - if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) { + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { UnwindLogMsg("failed to get cfa"); m_frame_type = eNotAValidFrame; return; } - UnwindLogMsg("m_cfa = 0x%" PRIx64, m_cfa); + 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(); @@ -600,9 +611,10 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { } UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 - " cfa 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_cfa, + (uint64_t)m_afa); } bool RegisterContextLLDB::CheckIfLoopingStack() { @@ -1238,7 +1250,7 @@ RegisterContextLLDB::SavedLocationForRegister( // 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 == false && return_address_reg.IsValid() && + if (!have_unwindplan_regloc && return_address_reg.IsValid() && IsFrameZero()) { if (return_address_reg.GetAsKind(eRegisterKindLLDB) != LLDB_INVALID_REGNUM) { @@ -1311,17 +1323,13 @@ RegisterContextLLDB::SavedLocationForRegister( unwindplan_regloc)) { can_fetch_pc_value = true; } - if (ReadCFAValueForRow(unwindplan_registerkind, active_row, - cfa_value)) { + if (ReadFrameAddress(unwindplan_registerkind, + active_row->GetCFAValue(), cfa_value)) { can_fetch_cfa = true; } } - if (can_fetch_pc_value && can_fetch_cfa) { - have_unwindplan_regloc = true; - } else { - have_unwindplan_regloc = false; - } + 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; @@ -1332,7 +1340,7 @@ RegisterContextLLDB::SavedLocationForRegister( ExecutionContext exe_ctx(m_thread.shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); - if (have_unwindplan_regloc == false) { + 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, @@ -1351,7 +1359,7 @@ RegisterContextLLDB::SavedLocationForRegister( } } - if (have_unwindplan_regloc == false) { + if (!have_unwindplan_regloc) { if (IsFrameZero()) { // This is frame 0 - we should return the actual live register context // value @@ -1397,7 +1405,7 @@ RegisterContextLLDB::SavedLocationForRegister( } if (unwindplan_regloc.IsSame()) { - if (IsFrameZero() == false && + 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 " @@ -1441,6 +1449,36 @@ RegisterContextLLDB::SavedLocationForRegister( 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, @@ -1555,7 +1593,6 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; - addr_t old_this_frame_cfa_value = m_cfa; UnwindLLDB::RegisterLocation regloc; if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), regloc) == @@ -1585,6 +1622,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { // 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(); @@ -1595,19 +1633,21 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { if (active_row && active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::CFAValue::unspecified) { + UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; - if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row, 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; - m_cfa = old_cfa; 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) { @@ -1628,19 +1668,18 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { 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 != LLDB_INVALID_ADDRESS) { - if (old_caller_pc_value == new_caller_pc_value && - new_cfa == old_this_frame_cfa_value) { - 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; - m_cfa = old_cfa; - 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' " @@ -1674,16 +1713,19 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { if (active_row && active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::CFAValue::unspecified) { + UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; - if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row, 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(); @@ -1698,18 +1740,18 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { return false; } -bool RegisterContextLLDB::ReadCFAValueForRow( - lldb::RegisterKind row_register_kind, const UnwindPlan::RowSP &row, - addr_t &cfa_value) { +bool RegisterContextLLDB::ReadFrameAddress( + lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, + addr_t &address) { RegisterValue reg_value; - cfa_value = LLDB_INVALID_ADDRESS; + address = LLDB_INVALID_ADDRESS; addr_t cfa_reg_contents; - switch (row->GetCFAValue().GetValueType()) { - case UnwindPlan::Row::CFAValue::isRegisterDereferenced: { + switch (fa.GetValueType()) { + case UnwindPlan::Row::FAValue::isRegisterDereferenced: { RegisterNumber cfa_reg(m_thread, row_register_kind, - row->GetCFAValue().GetRegisterNumber()); + fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); @@ -1718,12 +1760,12 @@ bool RegisterContextLLDB::ReadCFAValueForRow( Status error = ReadRegisterValueFromMemory( reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); if (error.Success()) { - cfa_value = reg_value.GetAsUInt64(); + 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, cfa_value); + cfa_reg_contents, address); return true; } else { UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64 @@ -1735,9 +1777,9 @@ bool RegisterContextLLDB::ReadCFAValueForRow( } break; } - case UnwindPlan::Row::CFAValue::isRegisterPlusOffset: { + case UnwindPlan::Row::FAValue::isRegisterPlusOffset: { RegisterNumber cfa_reg(m_thread, row_register_kind, - row->GetCFAValue().GetRegisterNumber()); + fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1) { @@ -1748,35 +1790,35 @@ bool RegisterContextLLDB::ReadCFAValueForRow( cfa_reg_contents = LLDB_INVALID_ADDRESS; return false; } - cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset(); + address = cfa_reg_contents + fa.GetOffset(); UnwindLogMsg( "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d", - cfa_value, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents, row->GetCFAValue().GetOffset()); + address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), + cfa_reg_contents, fa.GetOffset()); return true; } break; } - case UnwindPlan::Row::CFAValue::isDWARFExpression: { + case UnwindPlan::Row::FAValue::isDWARFExpression: { ExecutionContext exe_ctx(m_thread.shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); - DataExtractor dwarfdata(row->GetCFAValue().GetDWARFExpressionBytes(), - row->GetCFAValue().GetDWARFExpressionLength(), + DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(), + fa.GetDWARFExpressionLength(), process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0, - row->GetCFAValue().GetDWARFExpressionLength()); + fa.GetDWARFExpressionLength()); dwarfexpr.SetRegisterKind(row_register_kind); Value result; Status error; if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result, &error)) { - cfa_value = result.GetScalar().ULongLong(); + address = result.GetScalar().ULongLong(); UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, - cfa_value); + address); return true; } UnwindLogMsg("Failed to set CFA value via DWARF expression: %s", @@ -2005,12 +2047,8 @@ bool RegisterContextLLDB::ReadPC(addr_t &pc) { pc = abi->FixCodeAddress(pc); } - if (m_all_registers_available == false && above_trap_handler == false && - (pc == 0 || pc == 1)) { - return false; - } - - return true; + return !(m_all_registers_available == false && + above_trap_handler == false && (pc == 0 || pc == 1)); } else { return false; } diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h index 7e9e77dcf06d9..50f12c6f8541a 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextLLDB_h_ #define lldb_RegisterContextLLDB_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "UnwindLLDB.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/UnwindPlan.h" @@ -192,9 +188,9 @@ private: bool ReadGPRValue(const RegisterNumber ®_num, lldb::addr_t &value); - // Get the CFA register for a given frame. - bool ReadCFAValueForRow(lldb::RegisterKind register_kind, - const UnwindPlan::RowSP &row, 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(); @@ -225,6 +221,7 @@ private: 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; diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 77c1bea348515..c0a6084cd7237 100644 --- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -9,16 +9,12 @@ #include "RegisterContextMacOSXFrameBackchain.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.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" -// Project includes #include "lldb/Utility/StringExtractorGDBRemote.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h index 4f5816aa49098..69e23c2782fd6 100644 --- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h @@ -10,10 +10,6 @@ #ifndef lldb_RegisterContextMacOSXFrameBackchain_h_ #define lldb_RegisterContextMacOSXFrameBackchain_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp index 71d35bbd3938e..69522ace1a684 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -11,13 +11,9 @@ #include "RegisterContextMach_arm.h" -// C Includes #include <mach/mach_types.h> #include <mach/thread_act.h> -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/source/Plugins/Process/Utility/RegisterContextMach_arm.h index a2cf6bfcbe4ad..5ea47f214e258 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -10,11 +10,7 @@ #ifndef liblldb_RegisterContextMach_arm_h_ #define liblldb_RegisterContextMach_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_arm.h" class RegisterContextMach_arm : public RegisterContextDarwin_arm { diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp index 5a260d5de1d55..94138605239ee 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -9,12 +9,8 @@ #if defined(__APPLE__) -// C Includes #include <mach/thread_act.h> -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextMach_i386.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/source/Plugins/Process/Utility/RegisterContextMach_i386.h index 8ac693a555848..a7e29e96b267d 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextMach_i386_h_ #define liblldb_RegisterContextMach_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_i386.h" class RegisterContextMach_i386 : public RegisterContextDarwin_i386 { diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp index 0180879d51eee..e523b95ee9743 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -9,12 +9,8 @@ #if defined(__APPLE__) -// C Includes #include <mach/thread_act.h> -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextMach_x86_64.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index cd425046b08e9..c73bdda79713e 100644 --- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextMach_x86_64_h_ #define liblldb_RegisterContextMach_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_x86_64.h" class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 { diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 76189ea781dee..f05c07f6c8e13 100644 --- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -9,15 +9,11 @@ #include "RegisterContextMemory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "DynamicRegisterInfo.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.h b/source/Plugins/Process/Utility/RegisterContextMemory.h index cad1592af5ba1..cdf2a5446e1e6 100644 --- a/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -10,12 +10,8 @@ #ifndef lldb_RegisterContextMemory_h_ #define lldb_RegisterContextMemory_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 352e251e3b647..b0e53cfcc91fc 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h index 8c5fe9d2c2de4..4b5a8fe95a4f8 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_arm_h_ #define liblldb_RegisterContextPOSIX_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" #include "lldb-arm-register-enums.h" #include "lldb/Target/RegisterContext.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 3ff93cde23473..8b00dfc81eab3 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm64.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index 27251da2a9af0..603c12d830d9d 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_arm64_h_ #define liblldb_RegisterContextPOSIX_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" #include "lldb-arm64-register-enums.h" #include "lldb/Target/RegisterContext.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index 98d1e6fa8817a..9270d09f7293e 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_mips64.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h index 1695ec9a0bab9..09cfd42b9c519 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_mips64_h_ #define liblldb_RegisterContextPOSIX_mips64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_mips.h" #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index 9f0552539723f..47a8e2c3f9e90 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -12,14 +12,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_powerpc.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h index 50f234680ca0a..3260cb1ce8bc1 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_powerpc_h_ #define liblldb_RegisterContextPOSIX_powerpc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_powerpc.h" #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index 41ae5ec6b51a7..ef221c963dc48 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_ppc64le.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h index 1070b4dea4051..9159819f17c4f 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_ppc64le_h_ #define liblldb_RegisterContextPOSIX_ppc64le_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "RegisterInfoInterface.h" #include "Utility/PPC64LE_DWARF_Registers.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index 662ac38405ef9..24f131099be4e 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_s390x.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h index d5337630c32dd..7a7b6bddd6aa6 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_s390x_h_ #define liblldb_RegisterContextPOSIX_s390x_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_s390x.h" #include "RegisterInfoInterface.h" #include "lldb-s390x-register-enums.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index d2a06e1b7897f..78f561a0f04fc 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_x86.h" @@ -376,7 +376,7 @@ RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() { if (m_fpr_type == eNotValid) { // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx m_fpr_type = eXSAVE; // extended floating-point registers, if available - if (false == ReadFPR()) + if (!ReadFPR()) m_fpr_type = eFXSAVE; // assume generic floating-point registers } return m_fpr_type; diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index ca71a6f272f80..b6db45e55bbf8 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_x86_h_ #define liblldb_RegisterContextPOSIX_x86_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" #include "lldb-x86-register-enums.h" diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 3b3b0856a4ca3..0d50c73a31a95 100644 --- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -10,12 +10,8 @@ #ifndef lldb_RegisterContextThreadMemory_h_ #define lldb_RegisterContextThreadMemory_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h index 6146dcaf7e5a2..e3ff492d707ae 100644 --- a/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -341,7 +341,7 @@ LLVM_PACKED_END // x86 extensions to FXSAVE (i.e. for AVX and MPX processors) LLVM_PACKED_START -struct LLVM_ALIGNAS(64) XSAVE { +struct LLVM_ALIGNAS(16) XSAVE { FXSAVE i387; // floating point registers typical in i387_fxsave_struct XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the // following extensions are usable diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm.h b/source/Plugins/Process/Utility/RegisterInfos_arm.h index 74d3226c8a523..ec951ea8a391b 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_arm.h +++ b/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -9,12 +9,8 @@ #ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT -// C Includes #include <stddef.h> -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h index b996533791ff3..039d98ecdd2d6 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -9,12 +9,8 @@ #ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT -// C Includes #include <stddef.h> -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h index ffdc4d0d116b0..f8947876d15f4 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -11,7 +11,6 @@ #include <cstddef> #include <cstdint> -// Project includes #ifdef DECLARE_REGISTER_INFOS_I386_STRUCT diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h index b116b99b3f81c..36483c068d266 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_mips.h +++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h @@ -7,15 +7,11 @@ // //===---------------------------------------------------------------------===// -// C Includes #include <stddef.h> -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/source/Plugins/Process/Utility/RegisterInfos_mips64.h index 3c3912fa69782..0194074f34f25 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ b/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -7,15 +7,11 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <stddef.h> -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h index 69f00e4ba8852..dbd87ad71a45c 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_ppc64.h +++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -9,7 +9,6 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT -// C Includes #include <stddef.h> // Computes the offset of the given GPR_PPC64 in the user data area. diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index bffa7a1d8b635..e6fa17b607587 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -9,7 +9,6 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT -// C Includes #include <stddef.h> // Computes the offset of the given GPR in the user data area. diff --git a/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/source/Plugins/Process/Utility/RegisterInfos_s390x.h index 0bbf422405ee7..b750be4116a5e 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_s390x.h +++ b/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <stddef.h> -// C++ Includes -// Other libraries and framework includes #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp index 3dbfe611e7133..de0821eb42530 100644 --- a/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -9,10 +9,12 @@ #include "StopInfoMachException.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes + +#if defined(__APPLE__) +// Needed for the EXC_RESOURCE interpretation macros +#include <kern/exc_resource.h> +#endif + #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/DynamicLoader.h" @@ -41,6 +43,12 @@ const char *StopInfoMachException::GetDescription() { const char *code_desc = NULL; const char *subcode_label = "subcode"; const char *subcode_desc = NULL; + +#if defined(__APPLE__) + char code_desc_buf[32]; + char subcode_desc_buf[32]; +#endif + switch (m_value) { case 1: // EXC_BAD_ACCESS exc_desc = "EXC_BAD_ACCESS"; @@ -275,6 +283,47 @@ const char *StopInfoMachException::GetDescription() { break; case 11: exc_desc = "EXC_RESOURCE"; +#if defined(__APPLE__) + { + int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code); + + code_label = "limit"; + code_desc = code_desc_buf; + subcode_label = "observed"; + subcode_desc = subcode_desc_buf; + + switch (resource_type) { + case RESOURCE_TYPE_CPU: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode)); + break; + case RESOURCE_TYPE_WAKEUPS: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode)); + break; + case RESOURCE_TYPE_MEMORY: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code)); + subcode_desc = nullptr; + subcode_label = "unused"; + break; + case RESOURCE_TYPE_IO: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));; + break; + } + } +#endif break; case 12: exc_desc = "EXC_GUARD"; diff --git a/source/Plugins/Process/Utility/StopInfoMachException.h b/source/Plugins/Process/Utility/StopInfoMachException.h index 94516454105ef..027ed80e8a984 100644 --- a/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/source/Plugins/Process/Utility/StopInfoMachException.h @@ -10,12 +10,8 @@ #ifndef liblldb_StopInfoMachException_h_ #define liblldb_StopInfoMachException_h_ -// C Includes -// C++ Includes #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Target/StopInfo.h" namespace lldb_private { diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h index 89229710da4db..c966ca03a017a 100644 --- a/source/Plugins/Process/Utility/ThreadMemory.h +++ b/source/Plugins/Process/Utility/ThreadMemory.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadMemory_h_ #define liblldb_ThreadMemory_h_ -// C Includes -// C++ Includes #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" class ThreadMemory : public lldb_private::Thread { diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 55559f07f1e5a..b34c87230bd15 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -130,6 +130,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { 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 @@ -138,7 +140,7 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // 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 > 300000) { + if (cur_idx >= max_stack_depth) { if (log) log->Printf("%*sFrame %d unwound too many frames, assuming unwind has " "gone astray, stopping.", @@ -210,15 +212,15 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // 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() == false) { + 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() == false || - reg_ctx_sp->GetCFA(cursor_sp->cfa) == false || - abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { + 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 @@ -383,10 +385,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { // 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. - if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( - m_frames[m_frames.size() - 2]->cfa))) - return false; - return true; + 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 @@ -468,10 +468,7 @@ bool UnwindLLDB::SearchForSavedLocationForRegister( UnwindLLDB::RegisterSearchResult result; result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( lldb_regnum, regloc); - if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) - return true; - else - return false; + return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; } while (frame_num >= 0) { UnwindLLDB::RegisterSearchResult result; diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h index 3d1f85a3dec3f..aec7b66d93540 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/source/Plugins/Process/Utility/UnwindLLDB.h @@ -10,12 +10,8 @@ #ifndef lldb_UnwindLLDB_h_ #define lldb_UnwindLLDB_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/UnwindPlan.h" diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp index 2115b4e179c08..ae0b9fb0a5269 100644 --- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp @@ -114,7 +114,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386( if (!m_cursors.empty()) { lldb::addr_t first_frame_pc = m_cursors.front().pc; if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const uint32_t resolve_scope = + const SymbolContextItem resolve_scope = eSymbolContextModule | eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextSymbol; @@ -205,7 +205,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64( if (!m_cursors.empty()) { lldb::addr_t first_frame_pc = m_cursors.front().pc; if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const uint32_t resolve_scope = + const SymbolContextItem resolve_scope = eSymbolContextModule | eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextSymbol; diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h index 328117a306ef5..9ee0b08ca09a3 100644 --- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h +++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h @@ -10,12 +10,8 @@ #ifndef lldb_UnwindMacOSXFrameBackchain_h_ #define lldb_UnwindMacOSXFrameBackchain_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Unwind.h" #include "lldb/lldb-private.h" diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp index ad43551a4c6db..81ec25871c577 100644 --- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp +++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp @@ -12,7 +12,6 @@ #include "IDebugDelegate.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/windows/HostProcessWindows.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -21,6 +20,7 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" @@ -50,7 +50,7 @@ struct DebugAttachContext { lldb::pid_t m_pid; ProcessAttachInfo m_attach_info; }; -} +} // namespace DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate) : m_debug_delegate(debug_delegate), m_pid_to_detach(0), @@ -191,7 +191,8 @@ Status DebuggerThread::StopDebugging(bool terminate) { handle, pid, terminate_suceeded); } else { LLDB_LOG(log, - "NOT calling TerminateProcess because the inferior is not valid ({0}, 0) (inferior={1})", + "NOT calling TerminateProcess because the inferior is not valid " + "({0}, 0) (inferior={1})", handle, pid); } } @@ -267,6 +268,8 @@ void DebuggerThread::DebugLoop() { if (wait_result) { DWORD continue_status = DBG_CONTINUE; switch (dbe.dwDebugEventCode) { + default: + llvm_unreachable("Unhandle debug event code!"); case EXCEPTION_DEBUG_EVENT: { ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId); @@ -330,7 +333,7 @@ void DebuggerThread::DebugLoop() { FreeProcessHandles(); LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting."); - SetEvent(m_debugging_ended_event); + ::SetEvent(m_debugging_ended_event); } ExceptionResult @@ -381,7 +384,7 @@ DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD); - LLDB_LOG(log, "Thread {0:x} spawned in process {1}", thread_id, + LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id, m_process.GetProcessId()); HostThread thread(info.hThread); thread.GetNativeThread().SetOwnsHandle(false); @@ -439,7 +442,6 @@ DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, m_debug_delegate->OnExitProcess(info.dwExitCode); - FreeProcessHandles(); return DBG_CONTINUE; } @@ -468,7 +470,7 @@ DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, if (path_str.startswith("\\\\?\\")) path += 4; - FileSpec file_spec(path, false); + FileSpec file_spec(path); ModuleSpec module_spec(file_spec); lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll); diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h index fcf36f7dec9bb..047d3ccb7296b 100644 --- a/source/Plugins/Process/Windows/Common/DebuggerThread.h +++ b/source/Plugins/Process/Windows/Common/DebuggerThread.h @@ -16,8 +16,8 @@ #include "ForwardDecl.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/Predicate.h" namespace lldb_private { diff --git a/source/Plugins/Process/Windows/Common/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h index cfe1b79cee114..ce2af3ca4111a 100644 --- a/source/Plugins/Process/Windows/Common/ForwardDecl.h +++ b/source/Plugins/Process/Windows/Common/ForwardDecl.h @@ -39,4 +39,4 @@ typedef std::shared_ptr<ExceptionRecord> ExceptionRecordSP; typedef std::unique_ptr<ExceptionRecord> ExceptionRecordUP; } -#endif
\ No newline at end of file +#endif diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index b14081f76617d..3fe5ab7804cba 100644 --- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -13,12 +13,11 @@ #include "lldb/Host/windows/windows.h" #include <psapi.h> -// Other libraries and framework includes #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostNativeProcessBase.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -28,6 +27,7 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/State.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Format.h" @@ -72,6 +72,20 @@ std::string GetProcessExecutableName(DWORD pid) { return file_name; } +DWORD ConvertLldbToWinApiProtect(uint32_t protect) { + // We also can process a read / write permissions here, but if the debugger + // will make later a write into the allocated memory, it will fail. To get + // around it is possible inside DoWriteMemory to remember memory permissions, + // allow write, write and restore permissions, but for now we process only + // the executable permission. + // + // TODO: Process permissions other than executable + if (protect & ePermissionsExecutable) + return PAGE_EXECUTE_READWRITE; + + return PAGE_READWRITE; +} + } // anonymous namespace namespace lldb_private { @@ -237,11 +251,13 @@ Status ProcessWindows::DoLaunch(Module *exe_module, FileSpec working_dir = launch_info.GetWorkingDirectory(); namespace fs = llvm::sys::fs; - if (working_dir && (!working_dir.ResolvePath() || - !fs::is_directory(working_dir.GetPath()))) { - result.SetErrorStringWithFormat("No such file or directory: %s", - working_dir.GetCString()); - return result; + if (working_dir) { + FileSystem::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir)) { + result.SetErrorStringWithFormat("No such file or directory: %s", + working_dir.GetCString()); + return result; + } } if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) { @@ -379,7 +395,7 @@ Status ProcessWindows::DoResume() { SetPrivateState(eStateRunning); } } else { - LLDB_LOG(log, "error: process %I64u is in state %u. Returning...", + LLDB_LOG(log, "error: process {0} is in state {1}. Returning...", m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState()); } @@ -577,7 +593,7 @@ bool ProcessWindows::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module ModuleSP exe_module_sp(target_sp->GetExecutableModule()); if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); // However, if there is no executable module, we return true since we might // be preparing to attach. return true; @@ -695,6 +711,58 @@ size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, return bytes_written; } +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) { + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size, + permissions); + + if (!m_session_data) { + LLDB_LOG(log, "cannot allocate, there is no active debugger connection."); + error.SetErrorString( + "cannot allocate, there is no active debugger connection"); + return LLDB_INVALID_ADDRESS; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + auto protect = ConvertLldbToWinApiProtect(permissions); + auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect); + if (!result) { + error.SetError(GetLastError(), eErrorTypeWin32); + LLDB_LOG(log, "allocating failed with error: {0}", error); + return LLDB_INVALID_ADDRESS; + } + + return reinterpret_cast<addr_t>(result); +} + +Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { + Status result; + + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr); + + if (!m_session_data) { + LLDB_LOG(log, "cannot deallocate, there is no active debugger connection."); + result.SetErrorString( + "cannot deallocate, there is no active debugger connection"); + return result; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + if (!VirtualFreeEx(handle, reinterpret_cast<LPVOID>(ptr), 0, MEM_RELEASE)) { + result.SetError(GetLastError(), eErrorTypeWin32); + LLDB_LOG(log, "deallocating failed with error: {0}", result); + return result; + } + + return result; +} + Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); @@ -812,6 +880,14 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) { SetProcessExitStatus(GetID(), true, 0, exit_code); SetPrivateState(eStateExited); + + // If the process exits before any initial stop then notify the debugger + // of the error otherwise WaitForDebuggerConnection() will be blocked. + // An example of this issue is when a process fails to load a dependent DLL. + if (m_session_data && !m_session_data->m_initial_stop_received) { + Status error(exit_code, eErrorTypeWin32); + OnDebuggerError(error, 0); + } } void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { @@ -829,7 +905,8 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { return; } - FileSpec executable_file(file_name, true); + FileSpec executable_file(file_name); + FileSystem::Instance().Resolve(executable_file); ModuleSpec module_spec(executable_file); Status error; module = GetTarget().GetSharedModule(module_spec, &error); @@ -837,7 +914,7 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { return; } - GetTarget().SetExecutableModule(module, false); + GetTarget().SetExecutableModule(module, eLoadDependentsNo); } bool load_addr_changed; @@ -880,8 +957,9 @@ ProcessWindows::OnDebugException(bool first_chance, } if (!first_chance) { - // Any second chance exception is an application crash by definition. - SetPrivateState(eStateCrashed); + // Not any second chance exception is an application crash by definition. + // It may be an expression evaluation crash. + SetPrivateState(eStateStopped); } ExceptionResult result = ExceptionResult::SendToApplication; diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h index ed3938beb347c..00e384f584080 100644 --- a/source/Plugins/Process/Windows/Common/ProcessWindows.h +++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -10,7 +10,6 @@ #ifndef liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ #define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ -// Other libraries and framework includes #include "lldb/Target/Process.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-forward.h" @@ -84,6 +83,9 @@ public: Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override; + lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) override; + Status DoDeallocateMemory(lldb::addr_t ptr) override; Status GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override; diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp index b3f507128f824..90d43b2cf8284 100644 --- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp +++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp @@ -40,12 +40,13 @@ void RegisterContextWindows::InvalidateAllRegisters() { bool RegisterContextWindows::ReadAllRegisterValues( lldb::DataBufferSP &data_sp) { + if (!CacheAllRegisterValues()) return false; - if (data_sp->GetByteSize() < sizeof(m_context)) { - data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); - } + + data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context)); + return true; } diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp index 3903280918cc8..b121dc7bf15ea 100644 --- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp +++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThreadBase.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -15,6 +14,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" +#include "lldb/Utility/State.h" #include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessWindows.h" diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp index 4aa6c785f83c4..584136a6e5bb4 100644 --- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" @@ -74,12 +74,12 @@ RegisterInfo g_register_infos[] = { nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ RegisterInfo g_register_infos[] = { nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp index fd486f3d08298..e012f9105f31a 100644 --- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp +++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 7bb7b72eaac18..7d66461c15bcb 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -7,25 +7,21 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <stdlib.h> -// C++ Includes #include <mutex> -// Other libraries and framework includes #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Threading.h" @@ -61,8 +57,8 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, // the header extension. const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); - auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), - header_size, 0); + auto data_sp = FileSystem::Instance().CreateDataBuffer( + crash_file->GetPath(), header_size, 0); if (data_sp && data_sp->GetByteSize() == header_size && elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) { elf::ELFHeader elf_header; @@ -81,7 +77,7 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) { // For now we are just making sure the file exists for a given module - if (!m_core_module_sp && m_core_file.Exists()) { + if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, NULL, NULL, NULL)); @@ -122,10 +118,10 @@ ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); } uint32_t ProcessElfCore::GetPluginVersion() { return 1; } lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( - const elf::ELFProgramHeader *header) { - const lldb::addr_t addr = header->p_vaddr; - FileRange file_range(header->p_offset, header->p_filesz); - VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range); + const elf::ELFProgramHeader &header) { + const lldb::addr_t addr = header.p_vaddr; + FileRange file_range(header.p_offset, header.p_filesz); + VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range); VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && @@ -140,12 +136,12 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( // Keep a separate map of permissions that that isn't coalesced so all ranges // are maintained. const uint32_t permissions = - ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | - ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | - ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); + ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | + ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | + ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); m_core_range_infos.Append( - VMRangeToPermissions::Entry(addr, header->p_memsz, permissions)); + VMRangeToPermissions::Entry(addr, header.p_memsz, permissions)); return addr; } @@ -166,8 +162,8 @@ Status ProcessElfCore::DoLoadCore() { return error; } - const uint32_t num_segments = core->GetProgramHeaderCount(); - if (num_segments == 0) { + llvm::ArrayRef<elf::ELFProgramHeader> segments = core->ProgramHeaders(); + if (segments.size() == 0) { error.SetErrorString("core file has no segments"); return error; } @@ -181,20 +177,17 @@ Status ProcessElfCore::DoLoadCore() { /// Walk through segments and Thread and Address Map information. /// PT_NOTE - Contains Thread and Register information /// PT_LOAD - Contains a contiguous range of Process Address Space - for (uint32_t i = 1; i <= num_segments; i++) { - const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i); - assert(header != NULL); - - DataExtractor data = core->GetSegmentDataByIndex(i); + for (const elf::ELFProgramHeader &H : segments) { + DataExtractor data = core->GetSegmentData(H); // Parse thread contexts and auxv structure - if (header->p_type == llvm::ELF::PT_NOTE) { - if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data)) + if (H.p_type == llvm::ELF::PT_NOTE) { + if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data)) return Status(std::move(error)); } // PT_LOAD segments contains address map - if (header->p_type == llvm::ELF::PT_LOAD) { - lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header); + if (H.p_type == llvm::ELF::PT_LOAD) { + lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(H); if (vm_addr > last_addr) ranges_are_sorted = false; vm_addr = last_addr; @@ -249,12 +242,11 @@ Status ProcessElfCore::DoLoadCore() { ModuleSpec exe_module_spec; exe_module_spec.GetArchitecture() = arch; exe_module_spec.GetFileSpec().SetFile( - m_nt_file_entries[0].path.GetCString(), false, - FileSpec::Style::native); + m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { exe_module_sp = GetTarget().GetSharedModule(exe_module_spec); if (exe_module_sp) - GetTarget().SetExecutableModule(exe_module_sp, false); + GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); } } } @@ -715,8 +707,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { /// A note segment consists of one or more NOTE entries, but their types and /// meaning differ depending on the OS. llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( - const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) { - assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE); + const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) { + assert(segment_header.p_type == llvm::ELF::PT_NOTE); auto notes_or_error = parseSegment(segment_data); if(!notes_or_error) @@ -744,8 +736,7 @@ uint32_t ProcessElfCore::GetNumThreadContexts() { } ArchSpec ProcessElfCore::GetArchitecture() { - ArchSpec arch; - m_core_module_sp->GetObjectFile()->GetArchitecture(arch); + ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture(); ArchSpec target_arch = GetTarget().GetArchitecture(); arch.MergeFrom(target_arch); diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h index 325c0152e0287..2c7268662fefa 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -17,13 +17,9 @@ #ifndef liblldb_ProcessElfCore_h_ #define liblldb_ProcessElfCore_h_ -// C Includes -// C++ Includes #include <list> #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -140,7 +136,7 @@ private: // For ProcessElfCore only //------------------------------------------------------------------ typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange; - typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> + typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset; typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions; @@ -170,7 +166,7 @@ private: // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment llvm::Error ParseThreadContextsFromNoteSegment( - const elf::ELFProgramHeader *segment_header, + const elf::ELFProgramHeader &segment_header, lldb_private::DataExtractor segment_data); // Returns number of thread contexts stored in the core file @@ -178,7 +174,7 @@ private: // Parse a contiguous address range of the process from LOAD segment lldb::addr_t - AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header); + AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader &header); llvm::Expected<std::vector<lldb_private::CoreNote>> parseSegment(const lldb_private::DataExtractor &segment); diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index 0d683153d9ed0..80c6c0207a1ea 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 919f8901d39a3..017646b44b5c2 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 532a1f5c0831c..beeb9b666ccdf 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_mips64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 8670e341a2777..d4f86b3547842 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_powerpc.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp index 2237e72353acf..8116a1c7ea57b 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_ppc64le.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index f0edbf1ea8548..875bb1647281c 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_s390x.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index a1f26d52444bb..27295492f43df 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt index 7ae25f83c5f8a..4eb5291d54d5a 100644 --- a/source/Plugins/Process/gdb-remote/CMakeLists.txt +++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt @@ -15,6 +15,8 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN GDBRemoteClientBase.cpp GDBRemoteCommunication.cpp GDBRemoteCommunicationClient.cpp + GDBRemoteCommunicationHistory.cpp + GDBRemoteCommunicationReplayServer.cpp GDBRemoteCommunicationServer.cpp GDBRemoteCommunicationServerCommon.cpp GDBRemoteCommunicationServerLLGS.cpp diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index 4e20b56fb111b..a3a4aa053261b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -379,7 +379,7 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) { log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03"); m_comm.m_interrupt_time = steady_clock::now(); } - m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; }); + m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; }); m_did_interrupt = true; } m_acquired = true; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index c335b60028619..72c1314a7c943 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -9,21 +9,22 @@ #include "GDBRemoteCommunication.h" -// C Includes +#include <future> #include <limits.h> #include <string.h> #include <sys/stat.h> -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/StreamFile.h" #include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/ThreadLauncher.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" @@ -33,7 +34,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/ScopedPrinter.h" -// Project includes #include "ProcessGDBRemoteLog.h" #if defined(__APPLE__) @@ -42,7 +42,8 @@ #define DEBUGSERVER_BASENAME "lldb-server" #endif -#if defined(HAVE_LIBCOMPRESSION) +#if defined(__APPLE__) +#define HAVE_LIBCOMPRESSION #include <compression.h> #endif @@ -54,78 +55,6 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; -GDBRemoteCommunication::History::History(uint32_t size) - : m_packets(), m_curr_idx(0), m_total_packet_count(0), - m_dumped_to_log(false) { - m_packets.resize(size); -} - -GDBRemoteCommunication::History::~History() {} - -void GDBRemoteCommunication::History::AddPacket(char packet_char, - PacketType type, - uint32_t bytes_transmitted) { - const size_t size = m_packets.size(); - if (size > 0) { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign(1, packet_char); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = llvm::get_threadid(); - } -} - -void GDBRemoteCommunication::History::AddPacket(const std::string &src, - uint32_t src_len, - PacketType type, - uint32_t bytes_transmitted) { - const size_t size = m_packets.size(); - if (size > 0) { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign(src, 0, src_len); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = llvm::get_threadid(); - } -} - -void GDBRemoteCommunication::History::Dump(Stream &strm) const { - const uint32_t size = GetNumPacketsInHistory(); - const uint32_t first_idx = GetFirstSavedPacketIndex(); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) { - const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } -} - -void GDBRemoteCommunication::History::Dump(Log *log) const { - if (log && !m_dumped_to_log) { - m_dumped_to_log = true; - const uint32_t size = GetNumPacketsInHistory(); - const uint32_t first_idx = GetFirstSavedPacketIndex(); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) { - const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } - } -} - //---------------------------------------------------------------------- // GDBRemoteCommunication constructor //---------------------------------------------------------------------- @@ -139,7 +68,10 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, #endif m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512), m_send_acks(true), m_compression_type(CompressionType::None), - m_listen_url() { + m_listen_url(), m_decompression_scratch_type(CompressionType::None), + m_decompression_scratch(nullptr) { + // Unused unless HAVE_LIBCOMPRESSION is defined. + (void)m_decompression_scratch_type; } //---------------------------------------------------------------------- @@ -150,6 +82,9 @@ GDBRemoteCommunication::~GDBRemoteCommunication() { Disconnect(); } + if (m_decompression_scratch) + free (m_decompression_scratch); + // Stop the communications read thread which is used to parse all incoming // packets. This function will block until the read thread returns. if (m_read_thread_enabled) @@ -172,7 +107,8 @@ size_t GDBRemoteCommunication::SendAck() { const size_t bytes_written = Write(&ch, 1, status, NULL); if (log) log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written); + m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); return bytes_written; } @@ -183,26 +119,31 @@ size_t GDBRemoteCommunication::SendNack() { const size_t bytes_written = Write(&ch, 1, status, NULL); if (log) log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written); + m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); return bytes_written; } GDBRemoteCommunication::PacketResult GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { - if (IsConnected()) { StreamString packet(0, 4, eByteOrderBig); - packet.PutChar('$'); packet.Write(payload.data(), payload.size()); packet.PutChar('#'); packet.PutHex8(CalculcateChecksum(payload)); + std::string packet_str = packet.GetString(); + + return SendRawPacketNoLock(packet_str); +} +GDBRemoteCommunication::PacketResult +GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, + bool skip_ack) { + if (IsConnected()) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; - // TODO: Don't shimmy through a std::string, just use StringRef. - std::string packet_str = packet.GetString(); - const char *packet_data = packet_str.c_str(); - const size_t packet_length = packet.GetSize(); + const char *packet_data = packet.data(); + const size_t packet_length = packet.size(); size_t bytes_written = Write(packet_data, packet_length, status, NULL); if (log) { size_t binary_start_offset = 0; @@ -241,11 +182,12 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { (int)packet_length, packet_data); } - m_history.AddPacket(packet.GetString(), packet_length, - History::ePacketTypeSend, bytes_written); + m_history.AddPacket(packet.str(), packet_length, + GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); if (bytes_written == packet_length) { - if (GetSendAcks()) + if (!skip_ack && GetSendAcks()) return GetAck(); else return PacketResult::Success; @@ -597,7 +539,7 @@ bool GDBRemoteCommunication::DecompressPacket() { size_t decompressed_bytes = 0; if (decompressed_bufsize != ULONG_MAX) { - decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1); + decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize); if (decompressed_buffer == nullptr) { m_bytes.erase(0, size_of_first_packet); return false; @@ -605,11 +547,10 @@ bool GDBRemoteCommunication::DecompressPacket() { } #if defined(HAVE_LIBCOMPRESSION) - // libcompression is weak linked so check that compression_decode_buffer() is - // available if (m_compression_type == CompressionType::ZlibDeflate || m_compression_type == CompressionType::LZFSE || - m_compression_type == CompressionType::LZ4) { + m_compression_type == CompressionType::LZ4 || + m_compression_type == CompressionType::LZMA) { compression_algorithm compression_type; if (m_compression_type == CompressionType::LZFSE) compression_type = COMPRESSION_LZFSE; @@ -620,16 +561,33 @@ bool GDBRemoteCommunication::DecompressPacket() { else if (m_compression_type == CompressionType::LZMA) compression_type = COMPRESSION_LZMA; - // If we have the expected size of the decompressed payload, we can - // allocate the right-sized buffer and do it. If we don't have that - // information, we'll need to try decoding into a big buffer and if the - // buffer wasn't big enough, increase it and try again. + if (m_decompression_scratch_type != m_compression_type) { + if (m_decompression_scratch) { + free (m_decompression_scratch); + m_decompression_scratch = nullptr; + } + size_t scratchbuf_size = 0; + if (m_compression_type == CompressionType::LZFSE) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE); + else if (m_compression_type == CompressionType::LZ4) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZ4_RAW); + else if (m_compression_type == CompressionType::ZlibDeflate) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_ZLIB); + else if (m_compression_type == CompressionType::LZMA) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZMA); + else if (m_compression_type == CompressionType::LZFSE) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE); + if (scratchbuf_size > 0) { + m_decompression_scratch = (void*) malloc (scratchbuf_size); + m_decompression_scratch_type = m_compression_type; + } + } if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) { decompressed_bytes = compression_decode_buffer( - decompressed_buffer, decompressed_bufsize + 10, - (uint8_t *)unescaped_content.data(), unescaped_content.size(), NULL, - compression_type); + decompressed_buffer, decompressed_bufsize, + (uint8_t *)unescaped_content.data(), unescaped_content.size(), + m_decompression_scratch, compression_type); } } #endif @@ -721,7 +679,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, // Size of packet before it is decompressed, for logging purposes size_t original_packet_size = m_bytes.size(); if (CompressionIsEnabled()) { - if (DecompressPacket() == false) { + if (!DecompressPacket()) { packet.Clear(); return GDBRemoteCommunication::PacketType::Standard; } @@ -860,7 +818,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, } } - m_history.AddPacket(m_bytes, total_length, History::ePacketTypeRecv, + m_history.AddPacket(m_bytes, total_length, + GDBRemoteCommunicationHistory::ePacketTypeRecv, total_length); // Clear packet_str in case there is some existing data in it. @@ -997,7 +956,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess( // debugserver to use and use it if we do. const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); if (env_debugserver_path) { - debugserver_file_spec.SetFile(env_debugserver_path, false, + debugserver_file_spec.SetFile(env_debugserver_path, FileSpec::Style::native); if (log) log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set " @@ -1005,13 +964,14 @@ Status GDBRemoteCommunication::StartDebugserverProcess( __FUNCTION__, env_debugserver_path); } else debugserver_file_spec = g_debugserver_file_spec; - bool debugserver_exists = debugserver_file_spec.Exists(); + bool debugserver_exists = + FileSystem::Instance().Exists(debugserver_file_spec); if (!debugserver_exists) { // The debugserver binary is in the LLDB.framework/Resources directory. debugserver_file_spec = HostInfo::GetSupportExeDir(); if (debugserver_file_spec) { debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME); - debugserver_exists = debugserver_file_spec.Exists(); + debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec); if (debugserver_exists) { if (log) log->Printf( @@ -1074,7 +1034,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess( debugserver_args.AppendArgument(llvm::StringRef("--setsid")); } - llvm::SmallString<PATH_MAX> named_pipe_path; + llvm::SmallString<128> named_pipe_path; // socket_pipe is used by debug server to communicate back either // TCP port or domain socket name which it listens on. // The second purpose of the pipe to serve as a synchronization point - @@ -1114,9 +1074,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess( __FUNCTION__, error.AsCString()); return error; } - int write_fd = socket_pipe.GetWriteFileDescriptor(); + pipe_t write = socket_pipe.GetWritePipe(); debugserver_args.AppendArgument(llvm::StringRef("--pipe")); - debugserver_args.AppendArgument(llvm::to_string(write_fd)); + debugserver_args.AppendArgument(llvm::to_string(write)); launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor()); #endif } else { @@ -1304,6 +1264,42 @@ Status GDBRemoteCommunication::StartDebugserverProcess( void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); } +void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) { + m_history.SetStream(strm); +}; + +llvm::Error +GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client, + GDBRemoteCommunication &server) { + const bool child_processes_inherit = false; + const int backlog = 5; + TCPSocket listen_socket(true, child_processes_inherit); + if (llvm::Error error = + listen_socket.Listen("127.0.0.1:0", backlog).ToError()) + return error; + + Socket *accept_socket; + std::future<Status> accept_status = std::async( + std::launch::async, [&] { return listen_socket.Accept(accept_socket); }); + + llvm::SmallString<32> remote_addr; + llvm::raw_svector_ostream(remote_addr) + << "connect://localhost:" << listen_socket.GetLocalPortNumber(); + + std::unique_ptr<ConnectionFileDescriptor> conn_up( + new ConnectionFileDescriptor()); + if (conn_up->Connect(remote_addr, nullptr) != lldb::eConnectionStatusSuccess) + return llvm::make_error<llvm::StringError>("Unable to connect", + llvm::inconvertibleErrorCode()); + + client.SetConnection(conn_up.release()); + if (llvm::Error error = accept_status.get().ToError()) + return error; + + server.SetConnection(new ConnectionFileDescriptor(accept_socket)); + return llvm::Error::success(); +} + GDBRemoteCommunication::ScopedTimeout::ScopedTimeout( GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout) : m_gdb_comm(gdb_comm), m_timeout_modified(false) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 67796e4c61ef2..369eb25b1dfac 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -10,24 +10,21 @@ #ifndef liblldb_GDBRemoteCommunication_h_ #define liblldb_GDBRemoteCommunication_h_ -// C Includes -// C++ Includes +#include "GDBRemoteCommunicationHistory.h" + #include <condition_variable> #include <mutex> #include <queue> #include <string> #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Core/Communication.h" -#include "lldb/Core/Listener.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Predicate.h" #include "lldb/Utility/Args.h" -#include "lldb/lldb-public.h" - +#include "lldb/Utility/Listener.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "lldb/lldb-public.h" namespace lldb_private { namespace process_gdb_remote { @@ -140,86 +137,16 @@ public: // fork/exec to avoid having to connect/accept void DumpHistory(Stream &strm); + void SetHistoryStream(llvm::raw_ostream *strm); -protected: - class History { - public: - enum PacketType { - ePacketTypeInvalid = 0, - ePacketTypeSend, - ePacketTypeRecv - }; - - struct Entry { - Entry() - : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), - packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {} - - void Clear() { - packet.clear(); - type = ePacketTypeInvalid; - bytes_transmitted = 0; - packet_idx = 0; - tid = LLDB_INVALID_THREAD_ID; - } - std::string packet; - PacketType type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; - }; - - History(uint32_t size); - - ~History(); - - // For single char packets for ack, nack and /x03 - void AddPacket(char packet_char, PacketType type, - uint32_t bytes_transmitted); - - void AddPacket(const std::string &src, uint32_t src_len, PacketType type, - uint32_t bytes_transmitted); - - void Dump(Stream &strm) const; - - void Dump(Log *log) const; - - bool DidDumpToLog() const { return m_dumped_to_log; } - - protected: - uint32_t GetFirstSavedPacketIndex() const { - if (m_total_packet_count < m_packets.size()) - return 0; - else - return m_curr_idx + 1; - } - - uint32_t GetNumPacketsInHistory() const { - if (m_total_packet_count < m_packets.size()) - return m_total_packet_count; - else - return (uint32_t)m_packets.size(); - } - - uint32_t GetNextIndex() { - ++m_total_packet_count; - const uint32_t idx = m_curr_idx; - m_curr_idx = NormalizeIndex(idx + 1); - return idx; - } - - uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); } - - std::vector<Entry> m_packets; - uint32_t m_curr_idx; - uint32_t m_total_packet_count; - mutable bool m_dumped_to_log; - }; + static llvm::Error ConnectLocally(GDBRemoteCommunication &client, + GDBRemoteCommunication &server); +protected: std::chrono::seconds m_packet_timeout; uint32_t m_echo_number; LazyBool m_supports_qEcho; - History m_history; + GDBRemoteCommunicationHistory m_history; bool m_send_acks; bool m_is_platform; // Set to true if this class represents a platform, // false if this class represents a debug session for @@ -228,6 +155,8 @@ protected: CompressionType m_compression_type; PacketResult SendPacketNoLock(llvm::StringRef payload); + PacketResult SendRawPacketNoLock(llvm::StringRef payload, + bool skip_ack = false); PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout<std::micro> timeout, bool sync_on_timeout); @@ -289,6 +218,9 @@ private: HostThread m_listen_thread; std::string m_listen_url; + CompressionType m_decompression_scratch_type; + void *m_decompression_scratch; + DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication); }; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index c8b59d5d236b9..1e12ea6b2d566 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -9,17 +9,13 @@ #include "GDBRemoteCommunicationClient.h" -// C Includes #include <math.h> #include <sys/stat.h> -// C++ Includes #include <numeric> #include <sstream> -// Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/XML.h" #include "lldb/Symbol/Symbol.h" @@ -31,9 +27,9 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Host/Config.h" @@ -41,7 +37,8 @@ #include "llvm/ADT/StringSwitch.h" -#if defined(HAVE_LIBCOMPRESSION) +#if defined(__APPLE__) +#define HAVE_LIBCOMPRESSION #include <compression.h> #endif @@ -256,10 +253,7 @@ bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() { m_attach_or_wait_reply = eLazyBoolYes; } } - if (m_attach_or_wait_reply == eLazyBoolYes) - return true; - else - return false; + return m_attach_or_wait_reply == eLazyBoolYes; } bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() { @@ -273,14 +267,11 @@ bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() { m_prepare_for_reg_writing_reply = eLazyBoolYes; } } - if (m_prepare_for_reg_writing_reply == eLazyBoolYes) - return true; - else - return false; + return m_prepare_for_reg_writing_reply == eLazyBoolYes; } void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { - if (did_exec == false) { + if (!did_exec) { // Hard reset everything, this is when we first connect to a GDB server m_supports_not_sending_acks = eLazyBoolCalculate; m_supports_thread_suffix = eLazyBoolCalculate; @@ -749,7 +740,7 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { bool sequence_mutex_unavailable; size_t size; size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable); - if (size && sequence_mutex_unavailable == false) { + if (size && !sequence_mutex_unavailable) { m_curr_pid = thread_ids.front(); m_curr_pid_is_valid = eLazyBoolYes; return m_curr_pid; @@ -843,8 +834,8 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( if (name_equal_value && name_equal_value[0]) { StreamString packet; bool send_hex_encoding = false; - for (const char *p = name_equal_value; - *p != '\0' && send_hex_encoding == false; ++p) { + for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding; + ++p) { if (isprint(*p)) { switch (*p) { case '$': @@ -1134,6 +1125,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS)); if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) { + // host info computation can require DNS traffic and shelling out to external processes. + // Increase the timeout to account for that. + ScopedTimeout timeout(*this, seconds(10)); m_qHostInfo_is_valid = eLazyBoolNo; StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse("qHostInfo", response, false) == @@ -1686,12 +1680,17 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { m_supports_watchpoint_support_info = eLazyBoolYes; llvm::StringRef name; llvm::StringRef value; + bool found_num_field = false; while (response.GetNameColonValue(name, value)) { if (name.equals("num")) { value.getAsInteger(0, m_num_supported_hardware_watchpoints); num = m_num_supported_hardware_watchpoints; + found_num_field = true; } } + if (!found_num_field) { + m_supports_watchpoint_support_info = eLazyBoolNo; + } } else { m_supports_watchpoint_support_info = eLazyBoolNo; } @@ -1724,12 +1723,10 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction( // On targets like MIPS and ppc64le, watchpoint exceptions are always // generated before the instruction is executed. The connected target may // not support qHostInfo or qWatchpointSupportInfo packets. - if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || - atype == llvm::Triple::ppc64le) - after = false; - else - after = true; + after = + !(atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || + atype == llvm::Triple::ppc64le); } else { // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to // eLazyBoolNo if it is not calculated before. @@ -1815,7 +1812,7 @@ bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { return false; std::string cwd; response.GetHexByteString(cwd); - working_dir.SetFile(cwd, false, GetHostArchitecture().GetTriple()); + working_dir.SetFile(cwd, GetHostArchitecture().GetTriple()); return !cwd.empty(); } return false; @@ -1925,8 +1922,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( // characters in a process name std::string name; extractor.GetHexByteString(name); - process_info.GetExecutableFile().SetFile(name, false, - FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native); } else if (name.equals("cputype")) { value.getAsInteger(0, cpu); } else if (name.equals("cpusubtype")) { @@ -3559,7 +3555,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( StringExtractor extractor(value); std::string path; extractor.GetHexByteString(path); - module_spec.GetFileSpec() = FileSpec(path, false, arch_spec.GetTriple()); + module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple()); } } @@ -3595,8 +3591,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { if (!dict->GetValueForKeyAsString("file_path", string)) return llvm::None; - result.GetFileSpec() = - FileSpec(string, false, result.GetArchitecture().GetTriple()); + result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple()); return result; } @@ -3774,7 +3769,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( // Is this the initial qSymbol:: packet? bool first_qsymbol_query = true; - if (m_supports_qSymbol && m_qSymbol_requests_done == false) { + if (m_supports_qSymbol && !m_qSymbol_requests_done) { Lock lock(*this, false); if (lock) { StreamString packet; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index cf1d249768d7a..37d53ab425f59 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -12,8 +12,6 @@ #include "GDBRemoteClientBase.h" -// C Includes -// C++ Includes #include <chrono> #include <map> #include <mutex> diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp new file mode 100644 index 0000000000000..69b13f2a3acb6 --- /dev/null +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -0,0 +1,143 @@ +//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "GDBRemoteCommunicationHistory.h" + +// Other libraries and framework includes +#include "lldb/Core/StreamFile.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Log.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_gdb_remote; + +void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const { + yaml::Output yout(strm); + yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this); + strm.flush(); +} + +GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) + : m_packets(), m_curr_idx(0), m_total_packet_count(0), + m_dumped_to_log(false) { + if (size) + m_packets.resize(size); +} + +GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {} + +void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type, + uint32_t bytes_transmitted) { + const size_t size = m_packets.size(); + if (size == 0) + return; + + const uint32_t idx = GetNextIndex(); + m_packets[idx].packet.data.assign(1, packet_char); + m_packets[idx].type = type; + m_packets[idx].bytes_transmitted = bytes_transmitted; + m_packets[idx].packet_idx = m_total_packet_count; + m_packets[idx].tid = llvm::get_threadid(); + if (m_stream && type == ePacketTypeRecv) + m_packets[idx].Serialize(*m_stream); +} + +void GDBRemoteCommunicationHistory::AddPacket(const std::string &src, + uint32_t src_len, PacketType type, + uint32_t bytes_transmitted) { + const size_t size = m_packets.size(); + if (size == 0) + return; + + const uint32_t idx = GetNextIndex(); + m_packets[idx].packet.data.assign(src, 0, src_len); + m_packets[idx].type = type; + m_packets[idx].bytes_transmitted = bytes_transmitted; + m_packets[idx].packet_idx = m_total_packet_count; + m_packets[idx].tid = llvm::get_threadid(); + if (m_stream && type == ePacketTypeRecv) + m_packets[idx].Serialize(*m_stream); +} + +void GDBRemoteCommunicationHistory::Dump(Stream &strm) const { + const uint32_t size = GetNumPacketsInHistory(); + const uint32_t first_idx = GetFirstSavedPacketIndex(); + const uint32_t stop_idx = m_curr_idx + size; + for (uint32_t i = first_idx; i < stop_idx; ++i) { + const uint32_t idx = NormalizeIndex(i); + const Entry &entry = m_packets[idx]; + if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + break; + strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", + entry.packet_idx, entry.tid, entry.bytes_transmitted, + (entry.type == ePacketTypeSend) ? "send" : "read", + entry.packet.data.c_str()); + } +} + +void GDBRemoteCommunicationHistory::Dump(Log *log) const { + if (!log || m_dumped_to_log) + return; + + m_dumped_to_log = true; + const uint32_t size = GetNumPacketsInHistory(); + const uint32_t first_idx = GetFirstSavedPacketIndex(); + const uint32_t stop_idx = m_curr_idx + size; + for (uint32_t i = first_idx; i < stop_idx; ++i) { + const uint32_t idx = NormalizeIndex(i); + const Entry &entry = m_packets[idx]; + if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + break; + log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", + entry.packet_idx, entry.tid, entry.bytes_transmitted, + (entry.type == ePacketTypeSend) ? "send" : "read", + entry.packet.data.c_str()); + } +} + +void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>:: + enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) { + io.enumCase(value, "Invalid", + GDBRemoteCommunicationHistory::ePacketTypeInvalid); + io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend); + io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv); +} + +void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>:: + output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *, + raw_ostream &Out) { + Out << toHex(Val.data); +} + +StringRef +yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input( + StringRef Scalar, void *, + GDBRemoteCommunicationHistory::Entry::BinaryData &Val) { + Val.data = fromHex(Scalar); + return {}; +} + +void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping( + IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { + io.mapRequired("packet", Entry.packet); + io.mapRequired("type", Entry.type); + io.mapRequired("bytes", Entry.bytes_transmitted); + io.mapRequired("index", Entry.packet_idx); + io.mapRequired("tid", Entry.tid); +} + +StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate( + IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { + if (Entry.bytes_transmitted != Entry.packet.data.size()) + return "BinaryData size doesn't match bytes transmitted"; + + return {}; +} diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h new file mode 100644 index 0000000000000..d0ca6a0235c9b --- /dev/null +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -0,0 +1,156 @@ +//===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteCommunicationHistory_h_ +#define liblldb_GDBRemoteCommunicationHistory_h_ + +#include <string> +#include <vector> + +#include "lldb/lldb-public.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" + +namespace lldb_private { +namespace process_gdb_remote { + +/// The history keeps a circular buffer of GDB remote packets. The history is +/// used for logging and replaying GDB remote packets. +class GDBRemoteCommunicationHistory { +public: + friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>; + + enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; + + /// Entry in the ring buffer containing the packet data, its type, size and + /// index. Entries can be serialized to file. + struct Entry { + Entry() + : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), + packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {} + + void Clear() { + packet.data.clear(); + type = ePacketTypeInvalid; + bytes_transmitted = 0; + packet_idx = 0; + tid = LLDB_INVALID_THREAD_ID; + } + + struct BinaryData { + std::string data; + }; + + void Serialize(llvm::raw_ostream &strm) const; + + BinaryData packet; + PacketType type; + uint32_t bytes_transmitted; + uint32_t packet_idx; + lldb::tid_t tid; + }; + + GDBRemoteCommunicationHistory(uint32_t size = 0); + + ~GDBRemoteCommunicationHistory(); + + // For single char packets for ack, nack and /x03 + void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted); + + void AddPacket(const std::string &src, uint32_t src_len, PacketType type, + uint32_t bytes_transmitted); + + void Dump(Stream &strm) const; + void Dump(Log *log) const; + bool DidDumpToLog() const { return m_dumped_to_log; } + + void SetStream(llvm::raw_ostream *strm) { m_stream = strm; } + +private: + uint32_t GetFirstSavedPacketIndex() const { + if (m_total_packet_count < m_packets.size()) + return 0; + else + return m_curr_idx + 1; + } + + uint32_t GetNumPacketsInHistory() const { + if (m_total_packet_count < m_packets.size()) + return m_total_packet_count; + else + return (uint32_t)m_packets.size(); + } + + uint32_t GetNextIndex() { + ++m_total_packet_count; + const uint32_t idx = m_curr_idx; + m_curr_idx = NormalizeIndex(idx + 1); + return idx; + } + + uint32_t NormalizeIndex(uint32_t i) const { + return m_packets.empty() ? 0 : i % m_packets.size(); + } + + std::vector<Entry> m_packets; + uint32_t m_curr_idx; + uint32_t m_total_packet_count; + mutable bool m_dumped_to_log; + llvm::raw_ostream *m_stream = nullptr; +}; + +} // namespace process_gdb_remote +} // namespace lldb_private + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry) + +namespace llvm { +namespace yaml { + +template <> +struct ScalarEnumerationTraits<lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::PacketType> { + static void enumeration(IO &io, + lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::PacketType &value); +}; + +template <> +struct ScalarTraits<lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::Entry::BinaryData> { + static void output(const lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::Entry::BinaryData &, + void *, raw_ostream &); + + static StringRef + input(StringRef, void *, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry:: + BinaryData &); + + static QuotingType mustQuote(StringRef S) { return QuotingType::None; } +}; + +template <> +struct MappingTraits< + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> { + static void + mapping(IO &io, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry + &Entry); + + static StringRef validate( + IO &io, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &); +}; + +} // namespace yaml +} // namespace llvm + +#endif // liblldb_GDBRemoteCommunicationHistory_h_ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp new file mode 100644 index 0000000000000..6a78eb20992e0 --- /dev/null +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -0,0 +1,204 @@ +//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <errno.h> + +#include "lldb/Host/Config.h" + +#include "GDBRemoteCommunicationReplayServer.h" +#include "ProcessGDBRemoteLog.h" + +// C Includes +// C++ Includes +#include <cstring> + +// Project includes +#include "lldb/Host/ThreadLauncher.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StringExtractorGDBRemote.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_gdb_remote; + +GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer() + : GDBRemoteCommunication("gdb-remote.server", + "gdb-remote.server.rx_packet"), + m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"), + m_async_listener_sp( + Listener::MakeListener("lldb.gdb-remote.server.async-listener")), + m_async_thread_state_mutex(), m_skip_acks(false) { + m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, + "async thread continue"); + m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, + "async thread should exit"); + + const uint32_t async_event_mask = + eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit; + m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, + async_event_mask); +} + +GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() { + StopAsyncThread(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( + Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) { + StringExtractorGDBRemote packet; + PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false); + + if (packet_result != PacketResult::Success) { + if (!IsConnected()) { + error.SetErrorString("lost connection"); + quit = true; + } else { + error.SetErrorString("timeout"); + } + return packet_result; + } + + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + + if (m_skip_acks) { + const StringExtractorGDBRemote::ServerPacketType packet_type = + packet.GetServerPacketType(); + switch (packet_type) { + case StringExtractorGDBRemote::eServerPacketType_nack: + case StringExtractorGDBRemote::eServerPacketType_ack: + return PacketResult::Success; + default: + break; + } + } else if (packet.GetStringRef() == "QStartNoAckMode") { + m_skip_acks = true; + m_send_acks = false; + } + + while (!m_packet_history.empty()) { + // Pop last packet from the history. + GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back(); + m_packet_history.pop_back(); + + // We only care about what we received from the server. Skip everything + // the client sent. + if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv) + continue; + + return SendRawPacketNoLock(entry.packet.data, true); + } + + quit = true; + + return packet_result; +} + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( + std::vector< + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>) + +llvm::Error +GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) { + auto error_or_file = MemoryBuffer::getFile(path.GetPath()); + if (auto err = error_or_file.getError()) + return errorCodeToError(err); + + yaml::Input yin((*error_or_file)->getBuffer()); + yin >> m_packet_history; + + if (auto err = yin.error()) + return errorCodeToError(err); + + // We want to manipulate the vector like a stack so we need to reverse the + // order of the packets to have the oldest on at the back. + std::reverse(m_packet_history.begin(), m_packet_history.end()); + + return Error::success(); +} + +bool GDBRemoteCommunicationReplayServer::StartAsyncThread() { + std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex); + if (!m_async_thread.IsJoinable()) { + // Create a thread that watches our internal state and controls which + // events make it to clients (into the DCProcess event queue). + m_async_thread = ThreadLauncher::LaunchThread( + "<lldb.gdb-remote.server.async>", + GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr); + } + + // Wait for handshake. + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + + return m_async_thread.IsJoinable(); +} + +void GDBRemoteCommunicationReplayServer::StopAsyncThread() { + std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex); + + if (!m_async_thread.IsJoinable()) + return; + + // Request thread to stop. + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit); + + // Disconnect client. + Disconnect(); + + // Stop the thread. + m_async_thread.Join(nullptr); + m_async_thread.Reset(); +} + +void GDBRemoteCommunicationReplayServer::ReceivePacket( + GDBRemoteCommunicationReplayServer &server, bool &done) { + Status error; + bool interrupt; + auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1), + error, interrupt, done); + if (packet_result != GDBRemoteCommunication::PacketResult::Success && + packet_result != + GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) { + done = true; + } else { + server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + } +} + +thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { + GDBRemoteCommunicationReplayServer *server = + (GDBRemoteCommunicationReplayServer *)arg; + + EventSP event_sp; + bool done = false; + + while (true) { + if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { + const uint32_t event_type = event_sp->GetType(); + if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) { + switch (event_type) { + case eBroadcastBitAsyncContinue: + ReceivePacket(*server, done); + if (done) + return {}; + break; + case eBroadcastBitAsyncThreadShouldExit: + default: + return {}; + } + } + } + } + + return {}; +} diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h new file mode 100644 index 0000000000000..5b840c8459b71 --- /dev/null +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -0,0 +1,83 @@ +//===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteCommunicationReplayServer_h_ +#define liblldb_GDBRemoteCommunicationReplayServer_h_ + +// Other libraries and framework includes +#include "GDBRemoteCommunication.h" +#include "GDBRemoteCommunicationHistory.h" + +// Project includes +#include "lldb/Host/HostThread.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/lldb-private-forward.h" +#include "llvm/Support/Error.h" + +// C Includes +// C++ Includes +#include <functional> +#include <map> +#include <thread> + +class StringExtractorGDBRemote; + +namespace lldb_private { +namespace process_gdb_remote { + +class ProcessGDBRemote; + +/// Dummy GDB server that replays packets from the GDB Remote Communication +/// history. This is used to replay GDB packets. +class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication { +public: + GDBRemoteCommunicationReplayServer(); + + ~GDBRemoteCommunicationReplayServer() override; + + PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout, + Status &error, bool &interrupt, + bool &quit); + + bool HandshakeWithClient() { return GetAck() == PacketResult::Success; } + + llvm::Error LoadReplayHistory(const FileSpec &path); + + bool StartAsyncThread(); + void StopAsyncThread(); + +protected: + enum { + eBroadcastBitAsyncContinue = (1 << 0), + eBroadcastBitAsyncThreadShouldExit = (1 << 1), + }; + + static void ReceivePacket(GDBRemoteCommunicationReplayServer &server, + bool &done); + static lldb::thread_result_t AsyncThread(void *arg); + + /// Replay history with the oldest packet at the end. + std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history; + + /// Server thread. + Broadcaster m_async_broadcaster; + lldb::ListenerSP m_async_listener_sp; + HostThread m_async_thread; + std::recursive_mutex m_async_thread_state_mutex; + + bool m_skip_acks; + +private: + DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer); +}; + +} // namespace process_gdb_remote +} // namespace lldb_private + +#endif // liblldb_GDBRemoteCommunicationReplayServer_h_ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 4fc1fc7a1964e..026f78117a0c4 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -13,11 +13,8 @@ #include "GDBRemoteCommunicationServer.h" -// C Includes -// C++ Includes #include <cstring> -// Project includes #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractorGDBRemote.h" diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 880caacd64149..082fb0d854243 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -10,13 +10,9 @@ #ifndef liblldb_GDBRemoteCommunicationServer_h_ #define liblldb_GDBRemoteCommunicationServer_h_ -// C Includes -// C++ Includes #include <functional> #include <map> -// Other libraries and framework includes -// Project includes #include "GDBRemoteCommunication.h" #include "lldb/lldb-private-forward.h" diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index c5b478378faa4..f11ef4f1bbf84 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -11,23 +11,21 @@ #include <errno.h> -// C Includes #ifdef __APPLE__ #include <TargetConditionals.h> #endif -// C++ Includes #include <chrono> #include <cstring> -// Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Config.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/SafeMachO.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/FileAction.h" @@ -36,12 +34,10 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/SafeMachO.h" #include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/Triple.h" -// Project includes #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" @@ -353,7 +349,7 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( std::string file; extractor.GetHexByteString(file); match_info.GetProcessInfo().GetExecutableFile().SetFile( - file, false, FileSpec::Style::native); + file, FileSpec::Style::native); } else if (key.equals("name_match")) { NameMatch name_match = llvm::StringSwitch<NameMatch>(value) .Case("equals", NameMatch::Equals) @@ -520,7 +516,8 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); Status error; - const FileSpec path_spec{path, true}; + FileSpec path_spec(path); + FileSystem::Instance().Resolve(path_spec); int fd = ::open(path_spec.GetCString(), flags, mode); const int save_errno = fd == -1 ? errno : 0; StreamString response; @@ -659,12 +656,14 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - Status error; - const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error); + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); + std::error_code ec; + const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); StreamString response; response.Printf("F%u", mode); - if (mode == 0 || error.Fail()) - response.Printf(",%i", (int)error.GetError()); + if (mode == 0 || ec) + response.Printf(",%i", (int)Status(ec).GetError()); return SendPacketNoLock(response.GetString()); } return SendErrorResponse(23); @@ -698,7 +697,11 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( packet.GetHexByteStringTerminatedBy(dst, ','); packet.GetChar(); // Skip ',' char packet.GetHexByteString(src); - Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false}); + + FileSpec src_spec(src); + FileSystem::Instance().Resolve(src_spec); + Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); + StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); @@ -731,9 +734,11 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( packet.GetHexByteString(working_dir); int status, signo; std::string output; - Status err = Host::RunShellCommand( - path.c_str(), FileSpec{working_dir, true}, &status, &signo, &output, - std::chrono::seconds(10)); + FileSpec working_spec(working_dir); + FileSystem::Instance().Resolve(working_spec); + Status err = + Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, + &output, std::chrono::seconds(10)); StreamGDBRemote response; if (err.Fail()) { response.PutCString("F,"); @@ -884,7 +889,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( packet.GetHexByteString(path); const bool read = true; const bool write = false; - if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -900,7 +905,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -916,7 +921,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -1024,7 +1029,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { if (success) { if (arg_idx == 0) m_process_launch_info.GetExecutableFile().SetFile( - arg, false, FileSpec::Style::native); + arg, FileSpec::Style::native); m_process_launch_info.GetArguments().AppendArgument(arg); if (log) log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"", @@ -1263,7 +1268,9 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); #else - return FileSpec(module_path, true); + FileSpec file_spec(module_path); + FileSystem::Instance().Resolve(file_spec); + return file_spec; #endif } @@ -1272,7 +1279,9 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - const FileSpec req_module_path_spec(module_path, true); + FileSpec req_module_path_spec(module_path); + FileSystem::Instance().Resolve(req_module_path_spec); + const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); const ModuleSpec module_spec(module_path_spec, arch); diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index e9ab8f1a11deb..f3825bb367917 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -10,12 +10,8 @@ #ifndef liblldb_GDBRemoteCommunicationServerCommon_h_ #define liblldb_GDBRemoteCommunicationServerCommon_h_ -// C Includes -// C++ Includes #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/lldb-private-forward.h" diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 50392fa389562..cdb63e72f6bdb 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -14,15 +14,10 @@ #include "GDBRemoteCommunicationServerLLGS.h" #include "lldb/Utility/StreamGDBRemote.h" -// C Includes -// C++ Includes #include <chrono> #include <cstring> #include <thread> -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" #include "lldb/Host/File.h" @@ -41,12 +36,13 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ScopedPrinter.h" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" @@ -222,8 +218,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { m_process_launch_info.SetLaunchInSeparateProcessGroup(true); m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); - const bool default_to_use_pty = true; - m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty); + if (should_forward_stdio) { + if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) + return Status(std::move(Err)); + } { std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); @@ -1333,7 +1331,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( packet.SetFilePos(::strlen("QSetWorkingDir:")); std::string path; packet.GetHexByteString(path); - m_process_launch_info.SetWorkingDirectory(FileSpec{path, true}); + m_process_launch_info.SetWorkingDirectory(FileSpec(path)); return SendOKResponse(); } @@ -3220,7 +3218,7 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, if (m_debugged_process_up ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) .Success()) { - if (file_spec.Exists()) + if (FileSystem::Instance().Exists(file_spec)) return file_spec; } } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 5a74d1acaa237..a085a3cc17dd1 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -10,18 +10,14 @@ #ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_ #define liblldb_GDBRemoteCommunicationServerLLGS_h_ -// C Includes -// C++ Includes #include <mutex> #include <unordered_map> -// Other libraries and framework includes #include "lldb/Core/Communication.h" #include "lldb/Host/MainLoop.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/lldb-private-forward.h" -// Project includes #include "GDBRemoteCommunicationServerCommon.h" class StringExtractorGDBRemote; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 26e28a900320a..3521ddafbb166 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -11,15 +11,12 @@ #include <errno.h> -// C Includes -// C++ Includes #include <chrono> #include <csignal> #include <cstring> #include <mutex> #include <sstream> -// Other libraries and framework includes #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" @@ -38,7 +35,6 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UriParser.h" -// Project includes #include "lldb/Utility/StringExtractorGDBRemote.h" using namespace lldb; @@ -168,9 +164,6 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( StringExtractorGDBRemote &packet) { -#ifdef _WIN32 - return SendErrorResponse(9); -#else // Spawn a local debugserver as a platform so we can then attach or launch a // process... @@ -221,10 +214,9 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( PacketResult packet_result = SendPacketNoLock(response.GetString()); if (packet_result != PacketResult::Success) { if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - ::kill(debugserver_pid, SIGINT); + Host::Kill(debugserver_pid, SIGINT); } return packet_result; -#endif } GDBRemoteCommunication::PacketResult @@ -532,7 +524,7 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { const char *domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); if (domainsocket_dir_env != nullptr) - g_domainsocket_dir = FileSpec(domainsocket_dir_env, false); + g_domainsocket_dir = FileSpec(domainsocket_dir_env); else g_domainsocket_dir = HostInfo::GetProcessTempDir(); }); @@ -542,15 +534,15 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { FileSpec GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) { - llvm::SmallString<PATH_MAX> socket_path; - llvm::SmallString<PATH_MAX> socket_name( + llvm::SmallString<128> socket_path; + llvm::SmallString<128> socket_name( (llvm::StringRef(prefix) + ".%%%%%%").str()); FileSpec socket_path_spec(GetDomainSocketDir()); socket_path_spec.AppendPathComponent(socket_name.c_str()); llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path); - return FileSpec(socket_path.c_str(), false); + return FileSpec(socket_path.c_str()); } void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index aed5106272d1b..df51e0367d1d2 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -10,14 +10,10 @@ #ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_ #define liblldb_GDBRemoteCommunicationServerPlatform_h_ -// C Includes -// C++ Includes #include <map> #include <mutex> #include <set> -// Other libraries and framework includes -// Project includes #include "GDBRemoteCommunicationServerCommon.h" #include "lldb/Host/Socket.h" diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 07dab751f4b90..e58f47f4befef 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -9,17 +9,13 @@ #include "GDBRemoteRegisterContext.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.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" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "ThreadGDBRemote.h" @@ -462,7 +458,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( ((ProcessGDBRemote *)process)->GetGDBRemote()); const bool use_g_packet = - gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; + !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { @@ -525,7 +521,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( ((ProcessGDBRemote *)process)->GetGDBRemote()); const bool use_g_packet = - gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; + !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 8ef91af55e0f8..6e8f3306669f3 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -10,12 +10,8 @@ #ifndef lldb_GDBRemoteRegisterContext_h_ #define lldb_GDBRemoteRegisterContext_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/DynamicRegisterInfo.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/ConstString.h" diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b3d33b19bd666..797f63d537a17 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -9,12 +9,11 @@ #include "lldb/Host/Config.h" -// C Includes #include <errno.h> #include <stdlib.h> #ifndef LLDB_DISABLE_POSIX #include <netinet/in.h> -#include <sys/mman.h> // for mmap +#include <sys/mman.h> #include <sys/socket.h> #include <unistd.h> #endif @@ -22,7 +21,6 @@ #include <sys/types.h> #include <time.h> -// C++ Includes #include <algorithm> #include <csignal> #include <map> @@ -34,7 +32,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/DataFormatters/FormatManager.h" @@ -68,10 +65,11 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/CleanUp.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" -// Project includes #include "GDBRemoteRegisterContext.h" #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" #include "Plugins/Process/Utility/GDBRemoteSignals.h" @@ -88,6 +86,7 @@ #include "llvm/Support/raw_ostream.h" #define DEBUGSERVER_BASENAME "debugserver" +using namespace llvm; using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; @@ -101,21 +100,21 @@ namespace lldb { // and get the packet history dumped to a file. void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { StreamFile strm; - Status error(strm.GetFile().Open(path, File::eOpenOptionWrite | - File::eOpenOptionCanCreate)); + Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path), + File::eOpenOptionWrite | + File::eOpenOptionCanCreate); if (error.Success()) ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm); } -} +} // namespace lldb namespace { -static PropertyDefinition g_properties[] = { - {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, NULL, +static constexpr PropertyDefinition g_properties[] = { + {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, {}, "Specify the default packet timeout in seconds."}, - {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, NULL, - "The file that provides the description for remote target registers."}, - {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; + {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, {}, + "The file that provides the description for remote target registers."}}; enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile }; @@ -158,7 +157,42 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { return g_settings_sp; } -} // anonymous namespace end +class ProcessGDBRemoteProvider + : public repro::Provider<ProcessGDBRemoteProvider> { +public: + ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) { + m_info.name = "gdb-remote"; + m_info.files.push_back("gdb-remote.yaml"); + } + + raw_ostream *GetHistoryStream() { + FileSpec history_file = + GetRoot().CopyByAppendingPathComponent("gdb-remote.yaml"); + + std::error_code EC; + m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC, + sys::fs::OpenFlags::F_None); + return m_stream_up.get(); + } + + void SetCallback(std::function<void()> callback) { + m_callback = std::move(callback); + } + + void Keep() override { m_callback(); } + + void Discard() override { m_callback(); } + + static char ID; + +private: + std::function<void()> m_callback; + std::unique_ptr<raw_fd_ostream> m_stream_up; +}; + +char ProcessGDBRemoteProvider::ID = 0; + +} // namespace // TODO Randomly assigning a port is unsafe. We should get an unused // ephemeral port from the kernel and make sure we reserve it before passing it @@ -234,7 +268,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, case ObjectFile::eTypeUnknown: break; } - return exe_module->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module->GetFileSpec()); } // However, if there is no executable module, we return true since we might // be preparing to attach. @@ -259,8 +293,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_addr_to_mmap_size(), m_thread_create_bp_sp(), m_waiting_for_attach(false), m_destroy_tried_resuming(false), m_command_sp(), m_breakpoint_pc_offset(0), - m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false), - m_erased_flash_ranges() { + m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false), + m_allow_flash_writes(false), m_erased_flash_ranges() { m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, @@ -268,6 +302,15 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit"); + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + ProcessGDBRemoteProvider &provider = + g->GetOrCreate<ProcessGDBRemoteProvider>(); + // Set the history stream to the stream owned by the provider. + m_gdb_comm.SetHistoryStream(provider.GetHistoryStream()); + // Make sure to clear the stream again when we're finished. + provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); }); + } + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC)); const uint32_t async_event_mask = @@ -440,10 +483,10 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile(); - if (!target_definition_fspec.Exists()) { + if (!FileSystem::Instance().Exists(target_definition_fspec)) { // If the filename doesn't exist, it may be a ~ not having been expanded - // try to resolve it. - target_definition_fspec.ResolvePath(); + FileSystem::Instance().Resolve(target_definition_fspec); } if (target_definition_fspec) { // See if we can get register definitions from a python file @@ -640,7 +683,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { m_register_info.Finalize(GetTarget().GetArchitecture()); } -Status ProcessGDBRemote::WillLaunch(Module *module) { +Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) { return WillLaunchOrAttach(); } @@ -689,7 +732,9 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm, if (m_gdb_comm.GetProcessArchitecture().IsValid()) { target.SetArchitecture(m_gdb_comm.GetProcessArchitecture()); } else { - target.SetArchitecture(m_gdb_comm.GetHostArchitecture()); + if (m_gdb_comm.GetHostArchitecture().IsValid()) { + target.SetArchitecture(m_gdb_comm.GetHostArchitecture()); + } } } @@ -754,7 +799,7 @@ Status ProcessGDBRemote::WillLaunchOrAttach() { //---------------------------------------------------------------------- // Process Control //---------------------------------------------------------------------- -Status ProcessGDBRemote::DoLaunch(Module *exe_module, +Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, ProcessLaunchInfo &launch_info) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error; @@ -824,13 +869,13 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module, if (disable_stdio) { // set to /dev/null unless redirected to a file above if (!stdin_file_spec) - stdin_file_spec.SetFile(FileSystem::DEV_NULL, false, + stdin_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); if (!stdout_file_spec) - stdout_file_spec.SetFile(FileSystem::DEV_NULL, false, + stdout_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); if (!stderr_file_spec) - stderr_file_spec.SetFile(FileSystem::DEV_NULL, false, + stderr_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); } else if (platform_sp && platform_sp->IsHost()) { // If the debugserver is local and we aren't disabling STDIO, lets use @@ -839,7 +884,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module, // does a lot of output. if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) { - FileSpec slave_name{pty.GetSlaveName(NULL, 0), false}; + FileSpec slave_name{pty.GetSlaveName(NULL, 0)}; if (!stdin_file_spec) stdin_file_spec = slave_name; @@ -1058,9 +1103,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, " "using %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : "<null>"); @@ -1069,9 +1115,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s gdb-remote did not have process " "architecture, using gdb-remote host architecture %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : "<null>"); @@ -1083,9 +1130,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf( "ProcessGDBRemote::%s analyzing target arch, currently %s %s", - __FUNCTION__, target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "<null>", target_arch.GetTriple().getTriple().c_str() ? target_arch.GetTriple().getTriple().c_str() : "<null>"); @@ -1105,9 +1153,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, " "setting target arch to %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : "<null>"); @@ -1135,9 +1184,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s final target arch after " "adjustments for remote architecture: %s %s", - __FUNCTION__, target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "<null>", target_arch.GetTriple().getTriple().c_str() ? target_arch.GetTriple().getTriple().c_str() : "<null>"); @@ -1478,7 +1528,7 @@ Status ProcessGDBRemote::DoResume() { new EventDataBytes(continue_packet.GetString().data(), continue_packet.GetSize())); - if (listener_sp->GetEvent(event_sp, std::chrono::seconds(5)) == false) { + if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) { error.SetErrorString("Resume timed out."); if (log) log->Printf("ProcessGDBRemote::DoResume: Resume timed out."); @@ -1832,7 +1882,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( bool handled = false; bool did_exec = false; if (!reason.empty()) { - if (reason.compare("trace") == 0) { + if (reason == "trace") { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess() ->GetBreakpointSiteList() @@ -1850,7 +1900,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo( StopInfo::CreateStopReasonToTrace(*thread_sp)); handled = true; - } else if (reason.compare("breakpoint") == 0) { + } else if (reason == "breakpoint") { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess() ->GetBreakpointSiteList() @@ -1871,9 +1921,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo(invalid_stop_info_sp); } } - } else if (reason.compare("trap") == 0) { + } else if (reason == "trap") { // Let the trap just use the standard signal stop reason below... - } else if (reason.compare("watchpoint") == 0) { + } else if (reason == "watchpoint") { StringExtractor desc_extractor(description.c_str()); addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32); @@ -1905,11 +1955,11 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID( *thread_sp, watch_id, wp_hit_addr)); handled = true; - } else if (reason.compare("exception") == 0) { + } else if (reason == "exception") { thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException( *thread_sp, description.c_str())); handled = true; - } else if (reason.compare("exec") == 0) { + } else if (reason == "exec") { did_exec = true; thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithExec(*thread_sp)); @@ -1934,7 +1984,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( } } - if (!handled && signo && did_exec == false) { + if (!handled && signo && !did_exec) { if (signo == SIGTRAP) { // Currently we are going to assume SIGTRAP means we are either // hitting a breakpoint or hardware single stepping. @@ -2648,7 +2698,7 @@ void ProcessGDBRemote::SetLastStopPacket( // We are are not using non-stop mode, there can only be one last stop // reply packet, so clear the list. - if (GetTarget().GetNonStopModeEnabled() == false) + if (!GetTarget().GetNonStopModeEnabled()) m_stop_packet_stack.clear(); // Add this stop packet to the stop packet stack This stack will get popped @@ -3378,6 +3428,43 @@ Status ProcessGDBRemote::DoSignal(int signo) { return error; } +Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) { + if (!loader) + return Status("No loader provided."); + + auto provider_info = loader->GetProviderInfo("gdb-remote"); + if (!provider_info) + return Status("No provider for gdb-remote."); + + if (provider_info->files.empty()) + return Status("Provider for gdb-remote contains no files."); + + // Construct replay history path. + FileSpec history_file = loader->GetRoot().CopyByAppendingPathComponent( + provider_info->files.front()); + + // Enable replay mode. + m_replay_mode = true; + + // Load replay history. + if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file)) + return Status("Unable to load replay history"); + + // Make a local connection. + if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm, + m_gdb_replay_server)) + return Status("Unable to connect to replay server"); + + // Start server thread. + m_gdb_replay_server.StartAsyncThread(); + + // Start client thread. + StartAsyncThread(); + + // Do the usual setup. + return ConnectToDebugserver(""); +} + Status ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { // Make sure we aren't already connected? @@ -3388,6 +3475,9 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { if (platform_sp && !platform_sp->IsHost()) return Status("Lost debug server connection"); + if (repro::Loader *loader = repro::Reproducer::Instance().GetLoader()) + return ConnectToReplayServer(loader); + auto error = LaunchAndConnectToDebugserver(process_info); if (error.Fail()) { const char *error_string = error.AsCString(); @@ -3497,7 +3587,7 @@ bool ProcessGDBRemote::MonitorDebugserverProcess( bool exited, // True if the process did exit int signo, // Zero for no signal int exit_status // Exit value of process if signal is zero - ) { +) { // "debugserver_pid" argument passed in is the process ID for debugserver // that we are tracking... Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); @@ -4269,8 +4359,9 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, return false; feature_node.ForEachChildElementWithName( - "reg", [&target_info, &dyn_reg_info, &cur_reg_num, ®_offset, - &abi_sp](const XMLNode ®_node) -> bool { + "reg", + [&target_info, &dyn_reg_info, &cur_reg_num, ®_offset, + &abi_sp](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; ConstString reg_name; @@ -4432,7 +4523,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, return true; } -} // namespace {} +} // namespace // query the target of gdb-remote for extended target information return: // 'true' on success @@ -4509,12 +4600,19 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { // <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board) // use that if we don't have anything better. if (!arch_to_use.IsValid() && !target_info.arch.empty()) { - if (target_info.arch == "i386:x86-64") - { + if (target_info.arch == "i386:x86-64") { // We don't have any information about vendor or OS. arch_to_use.SetTriple("x86_64--"); GetTarget().MergeArchitecture(arch_to_use); } + + // SEGGER J-Link jtag boards send this very-generic arch name, + // we'll need to use this if we have absolutely nothing better + // to work with or the register definitions won't be accepted. + if (target_info.arch == "arm") { + arch_to_use.SetTriple("arm--"); + GetTarget().MergeArchitecture(arch_to_use); + } } // Initialize these outside of ParseRegisters, since they should not be @@ -4760,7 +4858,8 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { if (!modInfo.get_link_map(link_map)) link_map = LLDB_INVALID_ADDRESS; - FileSpec file(mod_name, true); + FileSpec file(mod_name); + FileSystem::Instance().Resolve(file); lldb::ModuleSP module_sp = LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset); @@ -4802,7 +4901,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { return true; lldb::ModuleSP module_copy_sp = module_sp; - target.SetExecutableModule(module_copy_sp, false); + target.SetExecutableModule(module_copy_sp, eLoadDependentsNo); return false; }); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 45bb2d4c28e71..14a5237e43451 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -10,15 +10,12 @@ #ifndef liblldb_ProcessGDBRemote_h_ #define liblldb_ProcessGDBRemote_h_ -// C Includes -// C++ Includes #include <atomic> #include <map> #include <mutex> #include <string> #include <vector> -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ThreadSafeValue.h" @@ -26,6 +23,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamGDBRemote.h" @@ -36,11 +34,15 @@ #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationClient.h" +#include "GDBRemoteCommunicationReplayServer.h" #include "GDBRemoteRegisterContext.h" #include "llvm/ADT/DenseMap.h" namespace lldb_private { +namespace repro { +class Loader; +} namespace process_gdb_remote { class ThreadGDBRemote; @@ -264,6 +266,7 @@ protected: }; GDBRemoteCommunicationClient m_gdb_comm; + GDBRemoteCommunicationReplayServer m_gdb_replay_server; std::atomic<lldb::pid_t> m_debugserver_pid; std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet // stack replaces @@ -304,6 +307,7 @@ protected: int64_t m_breakpoint_pc_offset; lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach + bool m_replay_mode; bool m_allow_flash_writes; using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>; using FlashRange = FlashRangeVector::Entry; @@ -331,6 +335,8 @@ protected: bool UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status ConnectToReplayServer(repro::Loader *loader); + Status EstablishConnectionIfNeeded(const ProcessInfo &process_info); Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index 3c58011766908..d4981df88d8da 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -10,11 +10,7 @@ #ifndef liblldb_ProcessGDBRemoteLog_h_ #define liblldb_ProcessGDBRemoteLog_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define GDBR_LOG_PROCESS (1u << 1) diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index a525c16b9f135..db7dc3eae0ba4 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -10,7 +10,6 @@ #include "ThreadGDBRemote.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -20,6 +19,7 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "ProcessGDBRemote.h" @@ -197,13 +197,10 @@ void ThreadGDBRemote::SetQueueLibdispatchQueueAddress( } bool ThreadGDBRemote::ThreadHasQueueInformation() const { - if (m_thread_dispatch_qaddr != 0 && - m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && - m_dispatch_queue_t != LLDB_INVALID_ADDRESS && - m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0) { - return true; - } - return false; + return m_thread_dispatch_qaddr != 0 && + m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && + m_dispatch_queue_t != LLDB_INVALID_ADDRESS && + m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0; } LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() { diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 1a5b60aea2887..4485a9cdc4c36 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadGDBRemote_h_ #define liblldb_ThreadGDBRemote_h_ -// C Includes -// C++ Includes #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/StructuredData.h" diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp index bfa35ed506a96..08b9f08a47f67 100644 --- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -8,38 +8,33 @@ // //===----------------------------------------------------------------------===// -// C Includes #include <errno.h> #include <stdlib.h> -// C++ Includes #include "llvm/Support/MathExtras.h" #include "llvm/Support/Threading.h" #include <mutex> -// Other libraries and framework includes #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" -// Project includes #include "ProcessMachCore.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include "ThreadMachCore.h" // Needed for the plug-in names for the dynamic loaders. -#include "lldb/Utility/SafeMachO.h" +#include "lldb/Host/SafeMachO.h" #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" @@ -67,8 +62,8 @@ lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp, lldb::ProcessSP process_sp; if (crash_file) { const size_t header_size = sizeof(llvm::MachO::mach_header); - auto data_sp = - DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0); + auto data_sp = FileSystem::Instance().CreateDataBuffer( + crash_file->GetPath(), header_size, 0); if (data_sp && data_sp->GetByteSize() == header_size) { DataExtractor data(data_sp, lldb::eByteOrderLittle, 4); @@ -90,7 +85,7 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp, return true; // For now we are just making sure the file exists for a given module - if (!m_core_module_sp && m_core_file.Exists()) { + if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { // Don't add the Target's architecture to the ModuleSpec - we may be // working with a core file that doesn't have the correct cpusubtype in the // header but we should still try to use it - @@ -307,36 +302,38 @@ Status ProcessMachCore::DoLoadCore() { // LC_IDENT is very obsolete and should not be used in new code, but if the // load command is present, let's use the contents. std::string corefile_identifier = core_objfile->GetIdentifierString(); - if (found_main_binary_definitively == false - && corefile_identifier.find("Darwin Kernel") != std::string::npos) { - UUID uuid; - addr_t addr = LLDB_INVALID_ADDRESS; - if (corefile_identifier.find("UUID=") != std::string::npos) { - size_t p = corefile_identifier.find("UUID=") + strlen("UUID="); - std::string uuid_str = corefile_identifier.substr(p, 36); - uuid.SetFromStringRef(uuid_str); - } - if (corefile_identifier.find("stext=") != std::string::npos) { - size_t p = corefile_identifier.find("stext=") + strlen("stext="); - if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') { - errno = 0; - addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16); - if (errno != 0 || addr == 0) - addr = LLDB_INVALID_ADDRESS; - } - } - if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) { - m_mach_kernel_addr = addr; - found_main_binary_definitively = true; - if (log) - log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64 - " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", addr, corefile_identifier.c_str()); + if (!found_main_binary_definitively && + corefile_identifier.find("Darwin Kernel") != std::string::npos) { + UUID uuid; + addr_t addr = LLDB_INVALID_ADDRESS; + if (corefile_identifier.find("UUID=") != std::string::npos) { + size_t p = corefile_identifier.find("UUID=") + strlen("UUID="); + std::string uuid_str = corefile_identifier.substr(p, 36); + uuid.SetFromStringRef(uuid_str); + } + if (corefile_identifier.find("stext=") != std::string::npos) { + size_t p = corefile_identifier.find("stext=") + strlen("stext="); + if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') { + errno = 0; + addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16); + if (errno != 0 || addr == 0) + addr = LLDB_INVALID_ADDRESS; } + } + if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) { + m_mach_kernel_addr = addr; + found_main_binary_definitively = true; + if (log) + log->Printf( + "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64 + " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", + addr, corefile_identifier.c_str()); + } } - if (found_main_binary_definitively == false - && (m_dyld_addr == LLDB_INVALID_ADDRESS - || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) { + if (!found_main_binary_definitively && + (m_dyld_addr == LLDB_INVALID_ADDRESS || + m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) { // We need to locate the main executable in the memory ranges we have in // the core file. We need to search for both a user-process dyld binary // and a kernel binary in memory; we must look at all the pages in the @@ -357,16 +354,15 @@ Status ProcessMachCore::DoLoadCore() { } } - if (found_main_binary_definitively == false - && m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { + if (!found_main_binary_definitively && + m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { // In the case of multiple kernel images found in the core file via // exhaustive search, we may not pick the correct one. See if the // DynamicLoaderDarwinKernel's search heuristics might identify the correct // one. Most of the time, I expect the address from SearchForDarwinKernel() // will be the same as the address we found via exhaustive search. - if (GetTarget().GetArchitecture().IsValid() == false && - m_core_module_sp.get()) { + if (!GetTarget().GetArchitecture().IsValid() && m_core_module_sp.get()) { GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture()); } diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h index 101df6b79115c..0c6fc693a50c5 100644 --- a/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -10,13 +10,9 @@ #ifndef liblldb_ProcessMachCore_h_ #define liblldb_ProcessMachCore_h_ -// C Includes -// C++ Includes #include <list> #include <vector> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp index c262dd47f9787..16edd28f1a132 100644 --- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp @@ -9,10 +9,7 @@ #include "ThreadMachCore.h" -#include "lldb/Utility/SafeMachO.h" - #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -21,6 +18,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "ProcessMachCore.h" diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h index a4db484e850f9..696ba7294e4aa 100644 --- a/source/Plugins/Process/mach-core/ThreadMachCore.h +++ b/source/Plugins/Process/mach-core/ThreadMachCore.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadMachCore_h_ #define liblldb_ThreadMachCore_h_ -// C Includes -// C++ Includes #include <string> -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" class ProcessMachCore; diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt index b898ee1aa1444..4126a7ea991c2 100644 --- a/source/Plugins/Process/minidump/CMakeLists.txt +++ b/source/Plugins/Process/minidump/CMakeLists.txt @@ -1,6 +1,8 @@ add_lldb_library(lldbPluginProcessMinidump PLUGIN MinidumpTypes.cpp MinidumpParser.cpp + RegisterContextMinidump_ARM.cpp + RegisterContextMinidump_ARM64.cpp RegisterContextMinidump_x86_32.cpp RegisterContextMinidump_x86_64.cpp ProcessMinidump.cpp diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp index 9a979335e99e1..d4053ca70b943 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -7,20 +7,19 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "MinidumpParser.h" #include "NtStructures.h" #include "RegisterContextMinidump_x86_32.h" -// Other libraries and framework includes -#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/LLDBAssert.h" +#include "Plugins/Process/Utility/LinuxProcMaps.h" // C includes // C++ includes #include <algorithm> #include <map> #include <vector> +#include <utility> using namespace lldb_private; using namespace minidump; @@ -80,8 +79,18 @@ UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) { // PDB70 record const CvRecordPdb70 *pdb70_uuid = nullptr; Status error = consumeObject(cv_record, pdb70_uuid); - if (!error.Fail()) - return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid)); + if (!error.Fail()) { + auto arch = GetArchitecture(); + // For Apple targets we only need a 16 byte UUID so that we can match + // the UUID in the Module to actual UUIDs from the built binaries. The + // "Age" field is zero in breakpad minidump files for Apple targets, so + // we restrict the UUID to the "Uuid" field so we have a UUID we can use + // to match. + if (arch.GetTriple().getVendor() == llvm::Triple::Apple) + return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid)); + else + return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid)); + } } else if (cv_signature == CvSignature::ElfBuildId) return UUID::fromData(cv_record); @@ -98,11 +107,15 @@ llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() { } llvm::ArrayRef<uint8_t> -MinidumpParser::GetThreadContext(const MinidumpThread &td) { - if (td.thread_context.rva + td.thread_context.data_size > GetData().size()) +MinidumpParser::GetThreadContext(const MinidumpLocationDescriptor &location) { + if (location.rva + location.data_size > GetData().size()) return {}; + return GetData().slice(location.rva, location.data_size); +} - return GetData().slice(td.thread_context.rva, td.thread_context.data_size); +llvm::ArrayRef<uint8_t> +MinidumpParser::GetThreadContext(const MinidumpThread &td) { + return GetThreadContext(td.thread_context); } llvm::ArrayRef<uint8_t> @@ -146,11 +159,14 @@ const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() { } ArchSpec MinidumpParser::GetArchitecture() { - ArchSpec arch_spec; + if (m_arch.IsValid()) + return m_arch; + + // Set the architecture in m_arch const MinidumpSystemInfo *system_info = GetSystemInfo(); if (!system_info) - return arch_spec; + return m_arch; // TODO what to do about big endiand flavors of arm ? // TODO set the arm subarch stuff if the minidump has info about it @@ -196,19 +212,28 @@ ArchSpec MinidumpParser::GetArchitecture() { break; case MinidumpOSPlatform::MacOSX: triple.setOS(llvm::Triple::OSType::MacOSX); + triple.setVendor(llvm::Triple::Apple); + break; + case MinidumpOSPlatform::IOS: + triple.setOS(llvm::Triple::OSType::IOS); + triple.setVendor(llvm::Triple::Apple); break; case MinidumpOSPlatform::Android: triple.setOS(llvm::Triple::OSType::Linux); triple.setEnvironment(llvm::Triple::EnvironmentType::Android); break; - default: + default: { triple.setOS(llvm::Triple::OSType::UnknownOS); + std::string csd_version; + if (auto s = GetMinidumpString(system_info->csd_version_rva)) + csd_version = *s; + if (csd_version.find("Linux") != std::string::npos) + triple.setOS(llvm::Triple::OSType::Linux); break; + } } - - arch_spec.SetTriple(triple); - - return arch_spec; + m_arch.SetTriple(triple); + return m_arch; } const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { @@ -254,36 +279,45 @@ llvm::ArrayRef<MinidumpModule> MinidumpParser::GetModuleList() { std::vector<const MinidumpModule *> MinidumpParser::GetFilteredModuleList() { llvm::ArrayRef<MinidumpModule> modules = GetModuleList(); - // map module_name -> pair(load_address, pointer to module struct in memory) - llvm::StringMap<std::pair<uint64_t, const MinidumpModule *>> lowest_addr; + // map module_name -> filtered_modules index + typedef llvm::StringMap<size_t> MapType; + MapType module_name_to_filtered_index; std::vector<const MinidumpModule *> filtered_modules; - + llvm::Optional<std::string> name; std::string module_name; for (const auto &module : modules) { name = GetMinidumpString(module.module_name_rva); - + if (!name) continue; - + module_name = name.getValue(); - - auto iter = lowest_addr.end(); - bool exists; - std::tie(iter, exists) = lowest_addr.try_emplace( - module_name, std::make_pair(module.base_of_image, &module)); - - if (exists && module.base_of_image < iter->second.first) - iter->second = std::make_pair(module.base_of_image, &module); - } - - filtered_modules.reserve(lowest_addr.size()); - for (const auto &module : lowest_addr) { - filtered_modules.push_back(module.second.second); + + MapType::iterator iter; + bool inserted; + // See if we have inserted this module aready into filtered_modules. If we + // haven't insert an entry into module_name_to_filtered_index with the + // index where we will insert it if it isn't in the vector already. + std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace( + module_name, filtered_modules.size()); + + if (inserted) { + // This module has not been seen yet, insert it into filtered_modules at + // the index that was inserted into module_name_to_filtered_index using + // "filtered_modules.size()" above. + filtered_modules.push_back(&module); + } else { + // This module has been seen. Modules are sometimes mentioned multiple + // times when they are mapped discontiguously, so find the module with + // the lowest "base_of_image" and use that as the filtered module. + auto dup_module = filtered_modules[iter->second]; + if (module.base_of_image < dup_module->base_of_image) + filtered_modules[iter->second] = &module; + } } - return filtered_modules; } @@ -381,72 +415,153 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr, return range->range_ref.slice(offset, overlap); } -llvm::Optional<MemoryRegionInfo> -MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) { - MemoryRegionInfo info; - llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryInfoList); +static bool +CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, + std::vector<MemoryRegionInfo> ®ions) { + auto data = parser.GetStream(MinidumpStreamType::LinuxMaps); if (data.empty()) - return llvm::None; + return false; + ParseLinuxMapRegions(llvm::toStringRef(data), + [&](const lldb_private::MemoryRegionInfo ®ion, + const lldb_private::Status &status) -> bool { + if (status.Success()) + regions.push_back(region); + return true; + }); + return !regions.empty(); +} - std::vector<const MinidumpMemoryInfo *> mem_info_list = - MinidumpMemoryInfo::ParseMemoryInfoList(data); +static bool +CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, + std::vector<MemoryRegionInfo> ®ions) { + auto data = parser.GetStream(MinidumpStreamType::MemoryInfoList); + if (data.empty()) + return false; + auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data); if (mem_info_list.empty()) - return llvm::None; + return false; + constexpr auto yes = MemoryRegionInfo::eYes; + constexpr auto no = MemoryRegionInfo::eNo; + regions.reserve(mem_info_list.size()); + for (const auto &entry : mem_info_list) { + MemoryRegionInfo region; + region.GetRange().SetRangeBase(entry->base_address); + region.GetRange().SetByteSize(entry->region_size); + region.SetReadable(entry->isReadable() ? yes : no); + region.SetWritable(entry->isWritable() ? yes : no); + region.SetExecutable(entry->isExecutable() ? yes : no); + region.SetMapped(entry->isMapped() ? yes : no); + regions.push_back(region); + } + return !regions.empty(); +} - const auto yes = MemoryRegionInfo::eYes; - const auto no = MemoryRegionInfo::eNo; +static bool +CreateRegionsCacheFromMemoryList(MinidumpParser &parser, + std::vector<MemoryRegionInfo> ®ions) { + auto data = parser.GetStream(MinidumpStreamType::MemoryList); + if (data.empty()) + return false; + auto memory_list = MinidumpMemoryDescriptor::ParseMemoryList(data); + if (memory_list.empty()) + return false; + regions.reserve(memory_list.size()); + for (const auto &memory_desc : memory_list) { + if (memory_desc.memory.data_size == 0) + continue; + MemoryRegionInfo region; + region.GetRange().SetRangeBase(memory_desc.start_of_memory_range); + region.GetRange().SetByteSize(memory_desc.memory.data_size); + region.SetReadable(MemoryRegionInfo::eYes); + region.SetMapped(MemoryRegionInfo::eYes); + regions.push_back(region); + } + regions.shrink_to_fit(); + return !regions.empty(); +} - const MinidumpMemoryInfo *next_entry = nullptr; - for (const auto &entry : mem_info_list) { - const auto head = entry->base_address; - const auto tail = head + entry->region_size; - - if (head <= load_addr && load_addr < tail) { - info.GetRange().SetRangeBase( - (entry->state != uint32_t(MinidumpMemoryInfoState::MemFree)) - ? head - : load_addr); - info.GetRange().SetRangeEnd(tail); - - const uint32_t PageNoAccess = - static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageNoAccess); - info.SetReadable((entry->protect & PageNoAccess) == 0 ? yes : no); - - const uint32_t PageWritable = - static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageWritable); - info.SetWritable((entry->protect & PageWritable) != 0 ? yes : no); - - const uint32_t PageExecutable = static_cast<uint32_t>( - MinidumpMemoryProtectionContants::PageExecutable); - info.SetExecutable((entry->protect & PageExecutable) != 0 ? yes : no); - - const uint32_t MemFree = - static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree); - info.SetMapped((entry->state != MemFree) ? yes : no); - - return info; - } else if (head > load_addr && - (next_entry == nullptr || head < next_entry->base_address)) { - // In case there is no region containing load_addr keep track of the - // nearest region after load_addr so we can return the distance to it. - next_entry = entry; - } +static bool +CreateRegionsCacheFromMemory64List(MinidumpParser &parser, + std::vector<MemoryRegionInfo> ®ions) { + llvm::ArrayRef<uint8_t> data = + parser.GetStream(MinidumpStreamType::Memory64List); + if (data.empty()) + return false; + llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list; + uint64_t base_rva; + std::tie(memory64_list, base_rva) = + MinidumpMemoryDescriptor64::ParseMemory64List(data); + + if (memory64_list.empty()) + return false; + + regions.reserve(memory64_list.size()); + for (const auto &memory_desc : memory64_list) { + if (memory_desc.data_size == 0) + continue; + MemoryRegionInfo region; + region.GetRange().SetRangeBase(memory_desc.start_of_memory_range); + region.GetRange().SetByteSize(memory_desc.data_size); + region.SetReadable(MemoryRegionInfo::eYes); + region.SetMapped(MemoryRegionInfo::eYes); + regions.push_back(region); } + regions.shrink_to_fit(); + return !regions.empty(); +} + +MemoryRegionInfo +MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const { + auto begin = m_regions.begin(); + auto end = m_regions.end(); + auto pos = std::lower_bound(begin, end, load_addr); + if (pos != end && pos->GetRange().Contains(load_addr)) + return *pos; + + MemoryRegionInfo region; + if (pos == begin) + region.GetRange().SetRangeBase(0); + else { + auto prev = pos - 1; + if (prev->GetRange().Contains(load_addr)) + return *prev; + region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd()); + } + if (pos == end) + region.GetRange().SetRangeEnd(UINT64_MAX); + else + region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase()); + region.SetReadable(MemoryRegionInfo::eNo); + region.SetWritable(MemoryRegionInfo::eNo); + region.SetExecutable(MemoryRegionInfo::eNo); + region.SetMapped(MemoryRegionInfo::eNo); + return region; +} - // No containing region found. Create an unmapped region that extends to the - // next region or LLDB_INVALID_ADDRESS - info.GetRange().SetRangeBase(load_addr); - info.GetRange().SetRangeEnd((next_entry != nullptr) ? next_entry->base_address - : LLDB_INVALID_ADDRESS); - info.SetReadable(no); - info.SetWritable(no); - info.SetExecutable(no); - info.SetMapped(no); - - // Note that the memory info list doesn't seem to contain ranges in kernel - // space, so if you're walking a stack that has kernel frames, the stack may - // appear truncated. - return info; +MemoryRegionInfo +MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) { + if (!m_parsed_regions) + GetMemoryRegions(); + return FindMemoryRegion(load_addr); +} + +const MemoryRegionInfos &MinidumpParser::GetMemoryRegions() { + if (!m_parsed_regions) { + m_parsed_regions = true; + // We haven't cached our memory regions yet we will create the region cache + // once. We create the region cache using the best source. We start with + // the linux maps since they are the most complete and have names for the + // regions. Next we try the MemoryInfoList since it has + // read/write/execute/map data, and then fall back to the MemoryList and + // Memory64List to just get a list of the memory that is mapped in this + // core file + if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions)) + if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions)) + if (!CreateRegionsCacheFromMemoryList(*this, m_regions)) + CreateRegionsCacheFromMemory64List(*this, m_regions); + llvm::sort(m_regions.begin(), m_regions.end()); + } + return m_regions; } Status MinidumpParser::Initialize() { @@ -531,10 +646,10 @@ Status MinidumpParser::Initialize() { } // Sort the file map ranges by start offset - std::sort(minidump_map.begin(), minidump_map.end(), - [](const FileRange &a, const FileRange &b) { - return a.offset < b.offset; - }); + llvm::sort(minidump_map.begin(), minidump_map.end(), + [](const FileRange &a, const FileRange &b) { + return a.offset < b.offset; + }); // Check for overlapping streams/data structures for (size_t i = 1; i < minidump_map.size(); ++i) { @@ -554,3 +669,48 @@ Status MinidumpParser::Initialize() { return error; } + +#define ENUM_TO_CSTR(ST) case (uint32_t)MinidumpStreamType::ST: return #ST + +llvm::StringRef +MinidumpParser::GetStreamTypeAsString(uint32_t stream_type) { + switch (stream_type) { + ENUM_TO_CSTR(Unused); + ENUM_TO_CSTR(Reserved0); + ENUM_TO_CSTR(Reserved1); + ENUM_TO_CSTR(ThreadList); + ENUM_TO_CSTR(ModuleList); + ENUM_TO_CSTR(MemoryList); + ENUM_TO_CSTR(Exception); + ENUM_TO_CSTR(SystemInfo); + ENUM_TO_CSTR(ThreadExList); + ENUM_TO_CSTR(Memory64List); + ENUM_TO_CSTR(CommentA); + ENUM_TO_CSTR(CommentW); + ENUM_TO_CSTR(HandleData); + ENUM_TO_CSTR(FunctionTable); + ENUM_TO_CSTR(UnloadedModuleList); + ENUM_TO_CSTR(MiscInfo); + ENUM_TO_CSTR(MemoryInfoList); + ENUM_TO_CSTR(ThreadInfoList); + ENUM_TO_CSTR(HandleOperationList); + ENUM_TO_CSTR(Token); + ENUM_TO_CSTR(JavascriptData); + ENUM_TO_CSTR(SystemMemoryInfo); + ENUM_TO_CSTR(ProcessVMCounters); + ENUM_TO_CSTR(BreakpadInfo); + ENUM_TO_CSTR(AssertionInfo); + ENUM_TO_CSTR(LinuxCPUInfo); + ENUM_TO_CSTR(LinuxProcStatus); + ENUM_TO_CSTR(LinuxLSBRelease); + ENUM_TO_CSTR(LinuxCMDLine); + ENUM_TO_CSTR(LinuxEnviron); + ENUM_TO_CSTR(LinuxAuxv); + ENUM_TO_CSTR(LinuxMaps); + ENUM_TO_CSTR(LinuxDSODebug); + ENUM_TO_CSTR(LinuxProcStat); + ENUM_TO_CSTR(LinuxProcUptime); + ENUM_TO_CSTR(LinuxProcFD); + } + return "unknown stream type"; +} diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h index 49b1eef14de58..07ea6aa908ff5 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.h +++ b/source/Plugins/Process/minidump/MinidumpParser.h @@ -1,5 +1,4 @@ -//===-- MinidumpParser.h -----------------------------------------*- C++ -//-*-===// +//===-- MinidumpParser.h -----------------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -11,9 +10,9 @@ #ifndef liblldb_MinidumpParser_h_ #define liblldb_MinidumpParser_h_ -// Project includes #include "MinidumpTypes.h" +#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/Status.h" @@ -59,6 +58,9 @@ public: llvm::ArrayRef<MinidumpThread> GetThreads(); + llvm::ArrayRef<uint8_t> + GetThreadContext(const MinidumpLocationDescriptor &location); + llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td); llvm::ArrayRef<uint8_t> GetThreadContextWow64(const MinidumpThread &td); @@ -87,17 +89,31 @@ public: llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size); - llvm::Optional<MemoryRegionInfo> GetMemoryRegionInfo(lldb::addr_t); + MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr); + + const MemoryRegionInfos &GetMemoryRegions(); // Perform consistency checks and initialize internal data structures Status Initialize(); + static llvm::StringRef GetStreamTypeAsString(uint32_t stream_type); + + const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> & + GetDirectoryMap() const { + return m_directory_map; + } + private: MinidumpParser(const lldb::DataBufferSP &data_buf_sp); + MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const; + private: lldb::DataBufferSP m_data_sp; llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> m_directory_map; + ArchSpec m_arch; + MemoryRegionInfos m_regions; + bool m_parsed_regions = false; }; } // end namespace minidump diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp index 049704ba80caf..7b1900e34ef1e 100644 --- a/source/Plugins/Process/minidump/MinidumpTypes.cpp +++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes // C includes // C++ includes @@ -244,6 +242,8 @@ MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) { return {}; std::vector<const MinidumpMemoryInfo *> result; + result.reserve(header->num_of_entries); + for (uint64_t i = 0; i < header->num_of_entries; ++i) { result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>( data.data() + i * header->size_of_entry)); diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h index e83089865b9e0..a5ea215d2548b 100644 --- a/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/source/Plugins/Process/minidump/MinidumpTypes.h @@ -10,9 +10,7 @@ #ifndef liblldb_MinidumpTypes_h_ #define liblldb_MinidumpTypes_h_ -// Project includes -// Other libraries and framework includes #include "lldb/Utility/Status.h" #include "llvm/ADT/ArrayRef.h" @@ -98,7 +96,10 @@ enum class MinidumpStreamType : uint32_t { LinuxEnviron = 0x47670007, /* /proc/$x/environ */ LinuxAuxv = 0x47670008, /* /proc/$x/auxv */ LinuxMaps = 0x47670009, /* /proc/$x/maps */ - LinuxDSODebug = 0x4767000A + LinuxDSODebug = 0x4767000A, + LinuxProcStat = 0x4767000B, /* /proc/$x/stat */ + LinuxProcUptime = 0x4767000C, /* uptime */ + LinuxProcFD = 0x4767000D, /* /proc/$x/fb */ }; // for MinidumpSystemInfo.processor_arch @@ -258,25 +259,6 @@ struct MinidumpMemoryInfoListHeader { static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16, "sizeof MinidumpMemoryInfoListHeader is not correct!"); -// Reference: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx -struct MinidumpMemoryInfo { - llvm::support::ulittle64_t base_address; - llvm::support::ulittle64_t allocation_base; - llvm::support::ulittle32_t allocation_protect; - llvm::support::ulittle32_t alignment1; - llvm::support::ulittle64_t region_size; - llvm::support::ulittle32_t state; - llvm::support::ulittle32_t protect; - llvm::support::ulittle32_t type; - llvm::support::ulittle32_t alignment2; - - static std::vector<const MinidumpMemoryInfo *> - ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data); -}; -static_assert(sizeof(MinidumpMemoryInfo) == 48, - "sizeof MinidumpMemoryInfo is not correct!"); - enum class MinidumpMemoryInfoState : uint32_t { MemCommit = 0x1000, MemFree = 0x10000, @@ -313,6 +295,45 @@ enum class MinidumpMemoryProtectionContants : uint32_t { }; // Reference: +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx +struct MinidumpMemoryInfo { + llvm::support::ulittle64_t base_address; + llvm::support::ulittle64_t allocation_base; + llvm::support::ulittle32_t allocation_protect; + llvm::support::ulittle32_t alignment1; + llvm::support::ulittle64_t region_size; + llvm::support::ulittle32_t state; + llvm::support::ulittle32_t protect; + llvm::support::ulittle32_t type; + llvm::support::ulittle32_t alignment2; + + static std::vector<const MinidumpMemoryInfo *> + ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data); + + bool isReadable() const { + const auto mask = MinidumpMemoryProtectionContants::PageNoAccess; + return (static_cast<uint32_t>(mask) & protect) == 0; + } + + bool isWritable() const { + const auto mask = MinidumpMemoryProtectionContants::PageWritable; + return (static_cast<uint32_t>(mask) & protect) != 0; + } + + bool isExecutable() const { + const auto mask = MinidumpMemoryProtectionContants::PageExecutable; + return (static_cast<uint32_t>(mask) & protect) != 0; + } + + bool isMapped() const { + return state != static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree); + } +}; + +static_assert(sizeof(MinidumpMemoryInfo) == 48, + "sizeof MinidumpMemoryInfo is not correct!"); + +// Reference: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx struct MinidumpThread { llvm::support::ulittle32_t thread_id; diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index b43f22382eaca..c5cca7ea62c69 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -7,28 +7,34 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "ProcessMinidump.h" #include "ThreadMinidump.h" -// Other libraries and framework includes +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" -#include "lldb/Target/DynamicLoader.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupBoolean.h" +#include "lldb/Target/JITLoaderList.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/Process/Utility/StopInfoMachException.h" + // C includes // C++ includes @@ -75,7 +81,7 @@ public: section_sp, module->base_of_image); } - ObjectFile *GetObjectFile() override { return nullptr; } +ObjectFile *GetObjectFile() override { return nullptr; } SectionList *GetSectionList() override { return Module::GetUnifiedSectionList(); @@ -100,8 +106,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, lldb::ProcessSP process_sp; // Read enough data for the Minidump header constexpr size_t header_size = sizeof(MinidumpHeader); - auto DataPtr = - DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0); + auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), + header_size, 0); if (!DataPtr) return nullptr; @@ -113,7 +119,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, if (header == nullptr) return nullptr; - auto AllData = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), -1, 0); + auto AllData = + FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0); if (!AllData) return nullptr; @@ -174,19 +181,21 @@ Status ProcessMinidump::DoLoadCore() { switch (arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: - // supported + case llvm::Triple::arm: + case llvm::Triple::aarch64: + // Any supported architectures must be listed here and also supported in + // ThreadMinidump::CreateRegisterContextForFrame(). break; - default: error.SetErrorStringWithFormat("unsupported minidump architecture: %s", arch.GetArchitectureName()); return error; } + GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser.GetThreads(); m_active_exception = m_minidump_parser.GetExceptionStream(); ReadModuleList(); - GetTarget().SetArchitecture(arch); llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid(); if (!pid) { @@ -198,12 +207,6 @@ Status ProcessMinidump::DoLoadCore() { return error; } -DynamicLoader *ProcessMinidump::GetDynamicLoader() { - if (m_dyld_ap.get() == nullptr) - m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr)); - return m_dyld_ap.get(); -} - ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); } uint32_t ProcessMinidump::GetPluginVersion() { return 1; } @@ -229,6 +232,11 @@ void ProcessMinidump::RefreshStateAfterStop() { if (arch.GetTriple().getOS() == llvm::Triple::Linux) { stop_info = StopInfo::CreateStopReasonWithSignal( *stop_thread, m_active_exception->exception_record.exception_code); + } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { + stop_info = StopInfoMachException::CreateStopReasonWithMachException( + *stop_thread, m_active_exception->exception_record.exception_code, 2, + m_active_exception->exception_record.exception_flags, + m_active_exception->exception_record.exception_address, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); @@ -284,33 +292,36 @@ ArchSpec ProcessMinidump::GetArchitecture() { Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) { - Status error; - auto info = m_minidump_parser.GetMemoryRegionInfo(load_addr); - if (!info) { - error.SetErrorString("No valid MemoryRegionInfo found!"); - return error; - } - range_info = info.getValue(); - return error; + range_info = m_minidump_parser.GetMemoryRegionInfo(load_addr); + return Status(); +} + +Status ProcessMinidump::GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) { + region_list = m_minidump_parser.GetMemoryRegions(); + return Status(); } void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); } bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { - uint32_t num_threads = 0; - if (m_thread_list.size() > 0) - num_threads = m_thread_list.size(); + for (const MinidumpThread& thread : m_thread_list) { + MinidumpLocationDescriptor context_location = thread.thread_context; + + // If the minidump contains an exception context, use it + if (m_active_exception != nullptr && + m_active_exception->thread_id == thread.thread_id) { + context_location = m_active_exception->thread_context; + } - for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { llvm::ArrayRef<uint8_t> context; if (!m_is_wow64) - context = m_minidump_parser.GetThreadContext(m_thread_list[tid]); + context = m_minidump_parser.GetThreadContext(context_location); else - context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]); + context = m_minidump_parser.GetThreadContextWow64(thread); - lldb::ThreadSP thread_sp( - new ThreadMinidump(*this, m_thread_list[tid], context)); + lldb::ThreadSP thread_sp(new ThreadMinidump(*this, thread, context)); new_thread_list.AddThread(thread_sp); } return new_thread_list.GetSize(false) > 0; @@ -344,8 +355,8 @@ void ProcessMinidump::ReadModuleList() { } const auto uuid = m_minidump_parser.GetModuleUUID(module); - const auto file_spec = - FileSpec(name.getValue(), true, GetArchitecture().GetTriple()); + auto file_spec = FileSpec(name.getValue(), GetArchitecture().GetTriple()); + FileSystem::Instance().Resolve(file_spec); ModuleSpec module_spec(file_spec, uuid); Status error; lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error); @@ -357,6 +368,12 @@ void ProcessMinidump::ReadModuleList() { // This enables most LLDB functionality involving address-to-module // translations (ex. identifing the module for a stack frame PC) and // modules/sections commands (ex. target modules list, ...) + if (log) { + log->Printf("Unable to locate the matching object file, creating a " + "placeholder module for: %s", + name.getValue().c_str()); + } + auto placeholder_module = std::make_shared<PlaceholderModule>(module_spec); placeholder_module->CreateImageSection(module, GetTarget()); @@ -387,3 +404,248 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) { } return true; } + +// For minidumps there's no runtime generated code so we don't need JITLoader(s) +// Avoiding them will also speed up minidump loading since JITLoaders normally +// try to set up symbolic breakpoints, which in turn may force loading more +// debug information than needed. +JITLoaderList &ProcessMinidump::GetJITLoaders() { + if (!m_jit_loaders_ap) { + m_jit_loaders_ap = llvm::make_unique<JITLoaderList>(); + } + return *m_jit_loaders_ap; +} + +#define INIT_BOOL(VAR, LONG, SHORT, DESC) \ + VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true) +#define APPEND_OPT(VAR) \ + m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1) + +class CommandObjectProcessMinidumpDump : public CommandObjectParsed { +private: + OptionGroupOptions m_option_group; + OptionGroupBoolean m_dump_all; + OptionGroupBoolean m_dump_directory; + OptionGroupBoolean m_dump_linux_cpuinfo; + OptionGroupBoolean m_dump_linux_proc_status; + OptionGroupBoolean m_dump_linux_lsb_release; + OptionGroupBoolean m_dump_linux_cmdline; + OptionGroupBoolean m_dump_linux_environ; + OptionGroupBoolean m_dump_linux_auxv; + OptionGroupBoolean m_dump_linux_maps; + OptionGroupBoolean m_dump_linux_proc_stat; + OptionGroupBoolean m_dump_linux_proc_uptime; + OptionGroupBoolean m_dump_linux_proc_fd; + OptionGroupBoolean m_dump_linux_all; + + void SetDefaultOptionsIfNoneAreSet() { + if (m_dump_all.GetOptionValue().GetCurrentValue() || + m_dump_linux_all.GetOptionValue().GetCurrentValue() || + m_dump_directory.GetOptionValue().GetCurrentValue() || + m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_status.GetOptionValue().GetCurrentValue() || + m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue() || + m_dump_linux_cmdline.GetOptionValue().GetCurrentValue() || + m_dump_linux_environ.GetOptionValue().GetCurrentValue() || + m_dump_linux_auxv.GetOptionValue().GetCurrentValue() || + m_dump_linux_maps.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue()) + return; + // If no options were set, then dump everything + m_dump_all.GetOptionValue().SetCurrentValue(true); + } + bool DumpAll() const { + return m_dump_all.GetOptionValue().GetCurrentValue(); + } + bool DumpDirectory() const { + return DumpAll() || + m_dump_directory.GetOptionValue().GetCurrentValue(); + } + bool DumpLinux() const { + return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxCPUInfo() const { + return DumpLinux() || + m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcStatus() const { + return DumpLinux() || + m_dump_linux_proc_status.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcStat() const { + return DumpLinux() || + m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxLSBRelease() const { + return DumpLinux() || + m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxCMDLine() const { + return DumpLinux() || + m_dump_linux_cmdline.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxEnviron() const { + return DumpLinux() || + m_dump_linux_environ.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxAuxv() const { + return DumpLinux() || + m_dump_linux_auxv.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxMaps() const { + return DumpLinux() || + m_dump_linux_maps.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcUptime() const { + return DumpLinux() || + m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcFD() const { + return DumpLinux() || + m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue(); + } +public: + + CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "process plugin dump", + "Dump information from the minidump file.", NULL), + m_option_group(), + INIT_BOOL(m_dump_all, "all", 'a', + "Dump the everything in the minidump."), + INIT_BOOL(m_dump_directory, "directory", 'd', + "Dump the minidump directory map."), + INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C', + "Dump linux /proc/cpuinfo."), + INIT_BOOL(m_dump_linux_proc_status, "status", 's', + "Dump linux /proc/<pid>/status."), + INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r', + "Dump linux /etc/lsb-release."), + INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c', + "Dump linux /proc/<pid>/cmdline."), + INIT_BOOL(m_dump_linux_environ, "environ", 'e', + "Dump linux /proc/<pid>/environ."), + INIT_BOOL(m_dump_linux_auxv, "auxv", 'x', + "Dump linux /proc/<pid>/auxv."), + INIT_BOOL(m_dump_linux_maps, "maps", 'm', + "Dump linux /proc/<pid>/maps."), + INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S', + "Dump linux /proc/<pid>/stat."), + INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u', + "Dump linux process uptime."), + INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f', + "Dump linux /proc/<pid>/fd."), + INIT_BOOL(m_dump_linux_all, "linux", 'l', + "Dump all linux streams.") { + APPEND_OPT(m_dump_all); + APPEND_OPT(m_dump_directory); + APPEND_OPT(m_dump_linux_cpuinfo); + APPEND_OPT(m_dump_linux_proc_status); + APPEND_OPT(m_dump_linux_lsb_release); + APPEND_OPT(m_dump_linux_cmdline); + APPEND_OPT(m_dump_linux_environ); + APPEND_OPT(m_dump_linux_auxv); + APPEND_OPT(m_dump_linux_maps); + APPEND_OPT(m_dump_linux_proc_stat); + APPEND_OPT(m_dump_linux_proc_uptime); + APPEND_OPT(m_dump_linux_proc_fd); + APPEND_OPT(m_dump_linux_all); + m_option_group.Finalize(); + } + + ~CommandObjectProcessMinidumpDump() {} + + Options *GetOptions() override { return &m_option_group; } + + bool DoExecute(Args &command, CommandReturnObject &result) override { + const size_t argc = command.GetArgumentCount(); + if (argc > 0) { + result.AppendErrorWithFormat("'%s' take no arguments, only options", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + SetDefaultOptionsIfNoneAreSet(); + + ProcessMinidump *process = static_cast<ProcessMinidump *>( + m_interpreter.GetExecutionContext().GetProcessPtr()); + result.SetStatus(eReturnStatusSuccessFinishResult); + Stream &s = result.GetOutputStream(); + MinidumpParser &minidump = process->m_minidump_parser; + if (DumpDirectory()) { + s.Printf("RVA SIZE TYPE MinidumpStreamType\n"); + s.Printf("---------- ---------- ---------- --------------------------\n"); + for (const auto &pair: minidump.GetDirectoryMap()) + s.Printf("0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)pair.second.rva, + (uint32_t)pair.second.data_size, pair.first, + MinidumpParser::GetStreamTypeAsString(pair.first).data()); + s.Printf("\n"); + } + auto DumpTextStream = [&](MinidumpStreamType stream_type, + llvm::StringRef label) -> void { + auto bytes = minidump.GetStream(stream_type); + if (!bytes.empty()) { + if (label.empty()) + label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type); + s.Printf("%s:\n%s\n\n", label.data(), bytes.data()); + } + }; + auto DumpBinaryStream = [&](MinidumpStreamType stream_type, + llvm::StringRef label) -> void { + auto bytes = minidump.GetStream(stream_type); + if (!bytes.empty()) { + if (label.empty()) + label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type); + s.Printf("%s:\n", label.data()); + DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle, + process->GetAddressByteSize()); + DumpDataExtractor(data, &s, 0, lldb::eFormatBytesWithASCII, 1, + bytes.size(), 16, 0, 0, 0); + s.Printf("\n\n"); + } + }; + + if (DumpLinuxCPUInfo()) + DumpTextStream(MinidumpStreamType::LinuxCPUInfo, "/proc/cpuinfo"); + if (DumpLinuxProcStatus()) + DumpTextStream(MinidumpStreamType::LinuxProcStatus, "/proc/PID/status"); + if (DumpLinuxLSBRelease()) + DumpTextStream(MinidumpStreamType::LinuxLSBRelease, "/etc/lsb-release"); + if (DumpLinuxCMDLine()) + DumpTextStream(MinidumpStreamType::LinuxCMDLine, "/proc/PID/cmdline"); + if (DumpLinuxEnviron()) + DumpTextStream(MinidumpStreamType::LinuxEnviron, "/proc/PID/environ"); + if (DumpLinuxAuxv()) + DumpBinaryStream(MinidumpStreamType::LinuxAuxv, "/proc/PID/auxv"); + if (DumpLinuxMaps()) + DumpTextStream(MinidumpStreamType::LinuxMaps, "/proc/PID/maps"); + if (DumpLinuxProcStat()) + DumpTextStream(MinidumpStreamType::LinuxProcStat, "/proc/PID/stat"); + if (DumpLinuxProcUptime()) + DumpTextStream(MinidumpStreamType::LinuxProcUptime, "uptime"); + if (DumpLinuxProcFD()) + DumpTextStream(MinidumpStreamType::LinuxProcFD, "/proc/PID/fd"); + return true; + } +}; + +class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword { +public: + CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "process plugin", + "Commands for operating on a ProcessMinidump process.", + "process plugin <subcommand> [<subcommand-options>]") { + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter))); + } + + ~CommandObjectMultiwordProcessMinidump() {} +}; + +CommandObject *ProcessMinidump::GetPluginCommandObject() { + if (!m_command_sp) + m_command_sp.reset(new CommandObjectMultiwordProcessMinidump( + GetTarget().GetDebugger().GetCommandInterpreter())); + return m_command_sp.get(); +} diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h index d65ada9009a7e..30347b79e1c17 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/source/Plugins/Process/minidump/ProcessMinidump.h @@ -10,11 +10,9 @@ #ifndef liblldb_ProcessMinidump_h_ #define liblldb_ProcessMinidump_h_ -// Project includes #include "MinidumpParser.h" #include "MinidumpTypes.h" -// Other libraries and framework includes #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -24,8 +22,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -// C Includes -// C++ Includes namespace lldb_private { @@ -53,9 +49,11 @@ public: bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; + CommandObject *GetPluginCommandObject() override; + Status DoLoadCore() override; - DynamicLoader *GetDynamicLoader() override; + DynamicLoader *GetDynamicLoader() override { return nullptr; } ConstString GetPluginName() override; @@ -82,6 +80,9 @@ public: Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; + Status GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) override; + bool GetProcessInfo(ProcessInstanceInfo &info) override; Status WillResume() override { @@ -102,10 +103,13 @@ protected: void ReadModuleList(); + JITLoaderList &GetJITLoaders() override; + private: FileSpec m_core_file; llvm::ArrayRef<MinidumpThread> m_thread_list; const MinidumpExceptionStream *m_active_exception; + lldb::CommandObjectSP m_command_sp; bool m_is_wow64; }; diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp new file mode 100644 index 0000000000000..93c3ba70b9e7e --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -0,0 +1,532 @@ +//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextMinidump_ARM.h" + +#include "Utility/ARM_DWARF_Registers.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include <assert.h> + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r)) + +#define DEF_R(i) \ + { \ + "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_R_ARG(i, n) \ + { \ + "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_d##i, INV, INV, reg_d##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \ + {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_Q(i) \ + { \ + "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_q##i, INV, INV, reg_q##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + // Floating Point Registers + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + k_num_regs +}; + +static RegisterInfo g_reg_info_apple_fp = { + "fp", + "r7", + 4, + OFFSET(r) + 7 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, + nullptr, + nullptr, + nullptr, + 0}; + +static RegisterInfo g_reg_info_fp = { + "fp", + "r11", + 4, + OFFSET(r) + 11 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, + nullptr, + nullptr, + nullptr, + 0}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_R_ARG(0, 1), + DEF_R_ARG(1, 2), + DEF_R_ARG(2, 3), + DEF_R_ARG(3, 4), + DEF_R(4), + DEF_R(5), + DEF_R(6), + DEF_R(7), + DEF_R(8), + DEF_R(9), + DEF_R(10), + DEF_R(11), + DEF_R(12), + {"sp", + "r13", + 4, + OFFSET(r) + 13 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + OFFSET(r) + 14 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + OFFSET(r) + 15 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 8, + OFFSET(fpscr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpscr}, + nullptr, + nullptr, + nullptr, + 0}, + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + DEF_Q(0), + DEF_Q(1), + DEF_Q(2), + DEF_Q(3), + DEF_Q(4), + DEF_Q(5), + DEF_Q(6), + DEF_Q(7), + DEF_Q(8), + DEF_Q(9), + DEF_Q(10), + DEF_Q(11), + DEF_Q(12), + DEF_Q(13), + DEF_Q(14), + DEF_Q(15)}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( + Thread &thread, const DataExtractor &data, bool apple) + : RegisterContext(thread, 0), m_apple(apple) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU32(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i) + m_regs.r[i] = data.GetU32(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpscr = data.GetU64(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i) + m_regs.d[i] = data.GetU64(&offset); + lldbassert(k_num_regs == k_num_reg_infos); +} + +size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) { + if (m_apple) { + if (reg == reg_r7) + return &g_reg_info_apple_fp; + } else { + if (reg == reg_r11) + return &g_reg_info_fp; + } + return &g_reg_infos[reg]; + } + return nullptr; +} + +size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h new file mode 100644 index 0000000000000..959611a1491d8 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -0,0 +1,93 @@ +//===-- RegisterContextMinidump_ARM.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM_h_ +#define liblldb_RegisterContextMinidump_ARM_h_ + +#include "MinidumpTypes.h" + +#include "Plugins/Process/Utility/RegisterInfoInterface.h" + +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM(lldb_private::Thread &thread, + const DataExtractor &data, bool apple); + + ~RegisterContextMinidump_ARM() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct QRegValue { + uint64_t lo; + uint64_t hi; + }; + + struct Context { + uint32_t context_flags; + uint32_t r[16]; + uint32_t cpsr; + uint64_t fpscr; + union { + uint64_t d[32]; + uint32_t s[32]; + QRegValue q[16]; + }; + uint32_t extra[8]; + }; + +protected: + enum class Flags : uint32_t { + ARM_Flag = 0x40000000, + Integer = ARM_Flag | 0x00000002, + FloatingPoint = ARM_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; + const bool m_apple; // True if this is an Apple ARM where FP is R7 +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM_h_ diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp new file mode 100644 index 0000000000000..3582e7d018676 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -0,0 +1,834 @@ +//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextMinidump_ARM64.h" + +#include "Utility/ARM64_DWARF_Registers.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include <assert.h> + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r)) + +#define DEF_X(i) \ + { \ + "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ + nullptr, 0 \ + } + +#define DEF_W(i) \ + { \ + "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_X_ARG(i, n) \ + { \ + "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_V(i) \ + { \ + "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_H(i) \ + { \ + "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_x0 = 0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_pc, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_cpsr, + // Floating Point Registers + reg_fpsr, + reg_fpcr, + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + k_num_regs +}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_X_ARG(0, 1), + DEF_X_ARG(1, 2), + DEF_X_ARG(2, 3), + DEF_X_ARG(3, 4), + DEF_X_ARG(4, 5), + DEF_X_ARG(5, 6), + DEF_X_ARG(6, 7), + DEF_X_ARG(7, 8), + DEF_X(8), + DEF_X(9), + DEF_X(10), + DEF_X(11), + DEF_X(12), + DEF_X(13), + DEF_X(14), + DEF_X(15), + DEF_X(16), + DEF_X(17), + DEF_X(18), + DEF_X(19), + DEF_X(20), + DEF_X(21), + DEF_X(22), + DEF_X(23), + DEF_X(24), + DEF_X(25), + DEF_X(26), + DEF_X(27), + DEF_X(28), + {"fp", + "x29", + 8, + OFFSET(x) + 29 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "x30", + 8, + OFFSET(x) + 30 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "x31", + 8, + OFFSET(x) + 31 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 8, + OFFSET(pc), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + // w0 - w31 + DEF_W(0), + DEF_W(1), + DEF_W(2), + DEF_W(3), + DEF_W(4), + DEF_W(5), + DEF_W(6), + DEF_W(7), + DEF_W(8), + DEF_W(9), + DEF_W(10), + DEF_W(11), + DEF_W(12), + DEF_W(13), + DEF_W(14), + DEF_W(15), + DEF_W(16), + DEF_W(17), + DEF_W(18), + DEF_W(19), + DEF_W(20), + DEF_W(21), + DEF_W(22), + DEF_W(23), + DEF_W(24), + DEF_W(25), + DEF_W(26), + DEF_W(27), + DEF_W(28), + DEF_W(29), + DEF_W(30), + DEF_W(31), + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpsr", + nullptr, + 4, + OFFSET(fpsr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpcr", + nullptr, + 4, + OFFSET(fpcr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpcr}, + nullptr, + nullptr, + nullptr, + 0}, + // v0 - v31 + DEF_V(0), + DEF_V(1), + DEF_V(2), + DEF_V(3), + DEF_V(4), + DEF_V(5), + DEF_V(6), + DEF_V(7), + DEF_V(8), + DEF_V(9), + DEF_V(10), + DEF_V(11), + DEF_V(12), + DEF_V(13), + DEF_V(14), + DEF_V(15), + DEF_V(16), + DEF_V(17), + DEF_V(18), + DEF_V(19), + DEF_V(20), + DEF_V(21), + DEF_V(22), + DEF_V(23), + DEF_V(24), + DEF_V(25), + DEF_V(26), + DEF_V(27), + DEF_V(28), + DEF_V(29), + DEF_V(30), + DEF_V(31), + // d0 - d31 + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + // s0 - s31 + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + // h0 - h31 + DEF_H(0), + DEF_H(1), + DEF_H(2), + DEF_H(3), + DEF_H(4), + DEF_H(5), + DEF_H(6), + DEF_H(7), + DEF_H(8), + DEF_H(9), + DEF_H(10), + DEF_H(11), + DEF_H(12), + DEF_H(13), + DEF_H(14), + DEF_H(15), + DEF_H(16), + DEF_H(17), + DEF_H(18), + DEF_H(19), + DEF_H(20), + DEF_H(21), + DEF_H(22), + DEF_H(23), + DEF_H(24), + DEF_H(25), + DEF_H(26), + DEF_H(27), + DEF_H(28), + DEF_H(29), + DEF_H(30), + DEF_H(31), +}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM64 general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_x0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + reg_fpsr, + reg_fpcr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64( + Thread &thread, const DataExtractor &data) + : RegisterContext(thread, 0) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU64(&offset); + for (unsigned i = 0; i < 32; ++i) + m_regs.x[i] = data.GetU64(&offset); + m_regs.pc = data.GetU64(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpsr = data.GetU32(&offset); + m_regs.fpcr = data.GetU32(&offset); + auto regs_data = data.GetData(&offset, sizeof(m_regs.v)); + if (regs_data) + memcpy(m_regs.v, regs_data, sizeof(m_regs.v)); + assert(k_num_regs == k_num_reg_infos); +} +size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) + return &g_reg_infos[reg]; + return nullptr; +} + +size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h new file mode 100644 index 0000000000000..ee47b1577e522 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h @@ -0,0 +1,83 @@ +//===-- RegisterContextMinidump_ARM64.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM64_h_ +#define liblldb_RegisterContextMinidump_ARM64_h_ + +#include "MinidumpTypes.h" + +#include "Plugins/Process/Utility/RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM64(lldb_private::Thread &thread, + const DataExtractor &data); + + ~RegisterContextMinidump_ARM64() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct Context { + uint64_t context_flags; + uint64_t x[32]; + uint64_t pc; + uint32_t cpsr; + uint32_t fpsr; + uint32_t fpcr; + uint8_t v[32 * 16]; // 32 128-bit floating point registers + }; + +protected: + enum class Flags : uint32_t { + ARM64_Flag = 0x80000000, + Integer = ARM64_Flag | 0x00000002, + FloatingPoint = ARM64_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM64_h_ diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 7605f8b143af6..1fdbb5e3f1e59 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "RegisterContextMinidump_x86_32.h" -// Other libraries and framework includes #include "lldb/Utility/DataBufferHeap.h" // C includes diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h index e18bb3b4f5d98..38c2ffca49389 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h @@ -10,10 +10,8 @@ #ifndef liblldb_RegisterContextMinidump_x86_32_h_ #define liblldb_RegisterContextMinidump_x86_32_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index ba1cb6dbf3efd..eaa155de8eb9b 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "RegisterContextMinidump_x86_64.h" -// Other libraries and framework includes #include "lldb/Utility/DataBufferHeap.h" // C includes diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h index 9ba2ee9f29ad1..30ce9065e1414 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h @@ -10,10 +10,8 @@ #ifndef liblldb_RegisterContextMinidump_h_ #define liblldb_RegisterContextMinidump_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp index 3fafb6134e7f6..f4c136577719c 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "ThreadMinidump.h" #include "ProcessMinidump.h" +#include "RegisterContextMinidump_ARM.h" +#include "RegisterContextMinidump_ARM64.h" #include "RegisterContextMinidump_x86_32.h" #include "RegisterContextMinidump_x86_64.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h" @@ -27,8 +27,6 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" -// C Includes -// C++ Includes using namespace lldb; using namespace lldb_private; @@ -54,7 +52,6 @@ RegisterContextSP ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); @@ -88,15 +85,22 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, gpregset, {})); break; } - default: + case llvm::Triple::aarch64: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data)); break; } - - if (!reg_interface) { - if (log) - log->Printf("elf-core::%s:: Architecture(%d) not supported", - __FUNCTION__, arch.GetMachine()); - assert(false && "Architecture not supported"); + case llvm::Triple::arm: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple; + m_thread_reg_ctx_sp.reset( + new RegisterContextMinidump_ARM(*this, data, apple)); + break; + } + default: + break; } reg_ctx_sp = m_thread_reg_ctx_sp; diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h index 74ac44f74dcf6..45364facaa562 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.h +++ b/source/Plugins/Process/minidump/ThreadMinidump.h @@ -10,14 +10,10 @@ #ifndef liblldb_ThreadMinidump_h_ #define liblldb_ThreadMinidump_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "lldb/Target/Thread.h" -// C Includes -// C++ Includes namespace lldb_private { |