diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:48:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:48:25 +0000 |
| commit | f678e45dc4469314acdd381171b56060b4e61272 (patch) | |
| tree | 981686fed7982ab8e5f0f696e0b0f91f89324256 /contrib/llvm/tools/lldb/source/Plugins/Process | |
| parent | 46b69c69334114d2a2b5c70f29d5e5fc2aa2d084 (diff) | |
| parent | 74a628f776edb588bff8f8f5cc16eac947c9d631 (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Process')
115 files changed, 4021 insertions, 1469 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp index 63b1ae6da9682..feb7a11584f80 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp @@ -30,11 +30,11 @@ // LLDB includes #include "lldb/lldb-enumerations.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Host/PseudoTerminal.h" #include "lldb/Target/ProcessLaunchInfo.h" -#include "lldb/Utility/PseudoTerminal.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" #include "CFBundle.h" #include "CFString.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/MachException.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/MachException.cpp index 81706441494ad..5a97a4b01be35 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/MachException.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/MachException.cpp @@ -22,11 +22,11 @@ #include <mutex> // LLDB includes -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/Error.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp index e56375ebaa49f..65ab12fe1adf3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp @@ -19,11 +19,11 @@ // C++ includes // LLDB includes -#include "lldb/Core/Log.h" #include "lldb/Core/State.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Host/PseudoTerminal.h" #include "lldb/Target/ProcessLaunchInfo.h" -#include "lldb/Utility/PseudoTerminal.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" #include "CFBundle.h" #include "CFString.h" @@ -31,6 +31,8 @@ #include "MachException.h" +#include "llvm/Support/FileSystem.h" + using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_darwin; @@ -63,7 +65,7 @@ Error NativeProcessProtocol::Launch( FileSpec working_dir(launch_info.GetWorkingDirectory()); if (working_dir && (!working_dir.ResolvePath() || - working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) { + !llvm::sys::fs::is_directory(working_dir.GetPath())) { error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); return error; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h index 69c1b8d9e4cc8..01fdd64b1273a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h @@ -24,11 +24,11 @@ // Other libraries and framework includes #include "lldb/Core/ArchSpec.h" #include "lldb/Host/Debug.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/lldb-types.h" #include "LaunchFlavor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp index 5e7f9ae7e6f95..b04f9053136bd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp @@ -13,7 +13,7 @@ #include <libproc.h> // LLDB includes -#include "lldb/Core/Stream.h" +#include "lldb/Utility/Stream.h" #include "NativeProcessDarwin.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp index aa9b041576587..fa06fb8b2a5f4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp @@ -20,9 +20,9 @@ #include <sys/sysctl.h> // LLDB includes -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" #include "NativeProcessDarwin.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index be92a0d810d28..caf0fdf80c6d3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -9,6 +9,12 @@ // C Includes #include <errno.h> +#include <pthread.h> +#include <pthread_np.h> +#include <stdlib.h> +#include <sys/sysctl.h> +#include <sys/types.h> +#include <sys/user.h> // C++ Includes // Other libraries and framework includes @@ -18,16 +24,16 @@ // Project includes #include "FreeBSDThread.h" #include "POSIXStopInfo.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h" +#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" -#include "ProcessPOSIXLog.h" #include "RegisterContextPOSIXProcessMonitor_arm.h" #include "RegisterContextPOSIXProcessMonitor_arm64.h" #include "RegisterContextPOSIXProcessMonitor_mips64.h" @@ -53,8 +59,7 @@ FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid) : Thread(process, tid), m_frame_ap(), m_breakpoint(), m_thread_name_valid(false), m_thread_name(), m_posix_thread(NULL) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); + LLDB_LOGV(log, "tid = {0}", tid); // Set the current watchpoints for this thread. Target &target = GetProcess()->GetTarget(); @@ -114,9 +119,41 @@ void FreeBSDThread::SetName(const char *name) { const char *FreeBSDThread::GetName() { if (!m_thread_name_valid) { - llvm::SmallString<32> thread_name; - HostNativeThread::GetName(GetID(), thread_name); - m_thread_name = thread_name.c_str(); + m_thread_name.clear(); + int pid = GetProcess()->GetID(); + + struct kinfo_proc *kp = nullptr, *nkp; + size_t len = 0; + int error; + int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD, + pid}; + + while (1) { + error = sysctl(ctl, 4, kp, &len, nullptr, 0); + if (kp == nullptr || (error != 0 && errno == ENOMEM)) { + // Add extra space in case threads are added before next call. + len += sizeof(*kp) + len / 10; + nkp = (struct kinfo_proc *)realloc(kp, len); + if (nkp == nullptr) { + free(kp); + return nullptr; + } + kp = nkp; + continue; + } + if (error != 0) + len = 0; + break; + } + + for (size_t i = 0; i < len / sizeof(*kp); i++) { + if (kp[i].ki_tid == (lwpid_t)GetID()) { + m_thread_name.append(kp[i].ki_tdname, + kp[i].ki_tdname + strlen(kp[i].ki_tdname)); + break; + } + } + free(kp); m_thread_name_valid = true; } @@ -138,7 +175,7 @@ lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() { reg_interface = new RegisterInfoPOSIX_arm64(target_arch); break; case llvm::Triple::arm: - reg_interface = new RegisterContextFreeBSD_arm(target_arch); + reg_interface = new RegisterInfoPOSIX_arm(target_arch); break; case llvm::Triple::ppc: #ifndef __powerpc64__ @@ -215,8 +252,7 @@ FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) { uint32_t concrete_frame_idx = 0; Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf("FreeBSDThread::%s ()", __FUNCTION__); + LLDB_LOGV(log, "called"); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h index 1ee16dd5f8f48..e51fc08d74cc7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h @@ -10,15 +10,9 @@ #ifndef liblldb_POSIXStopInfo_H_ #define liblldb_POSIXStopInfo_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/StopInfo.h" - -#include "CrashReason.h" #include "FreeBSDThread.h" - +#include "Plugins/Process/POSIX/CrashReason.h" +#include "lldb/Target/StopInfo.h" #include <string> //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index 82e45a5d5fc17..93d294fd040ab 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -10,12 +10,21 @@ // C Includes #include <errno.h> +#include <pthread.h> +#include <pthread_np.h> +#include <stdlib.h> +#include <sys/sysctl.h> +#include <sys/types.h> +#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/Host.h" #include "lldb/Symbol/ObjectFile.h" @@ -23,11 +32,11 @@ #include "lldb/Target/Target.h" #include "FreeBSDThread.h" +#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/FreeBSDSignals.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" -#include "ProcessPOSIXLog.h" // Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" @@ -36,15 +45,19 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Host/posix/Fcntl.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Threading.h" + using namespace lldb; using namespace lldb_private; @@ -70,12 +83,11 @@ ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp, } void ProcessFreeBSD::Initialize() { - static std::once_flag g_once_flag; + static llvm::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); - ProcessPOSIXLog::Initialize(GetPluginNameStatic()); }); } @@ -122,6 +134,7 @@ Error ProcessFreeBSD::DoResume() { std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); bool do_step = false; + bool software_single_step = !SupportHardwareSingleStepping(); for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); @@ -133,6 +146,11 @@ Error ProcessFreeBSD::DoResume() { t_pos != t_end; ++t_pos) { m_monitor->ThreadSuspend(*t_pos, false); do_step = true; + if (software_single_step) { + Error error = SetupSoftwareSingleStepping(*t_pos); + if (error.Fail()) + return error; + } } for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); @@ -145,7 +163,7 @@ Error ProcessFreeBSD::DoResume() { if (log) log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue"); - if (do_step) + if (do_step && !software_single_step) m_monitor->SingleStep(GetID(), m_resume_signo); else m_monitor->Resume(GetID(), m_resume_signo); @@ -281,8 +299,7 @@ Error ProcessFreeBSD::DoAttachToProcessWithID( assert(m_monitor == NULL); Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); + LLDB_LOGV(log, "pid = {0}", GetID()); m_monitor = new ProcessMonitor(this, pid, error); @@ -354,9 +371,9 @@ Error ProcessFreeBSD::DoLaunch(Module *module, ProcessLaunchInfo &launch_info) { assert(m_monitor == NULL); FileSpec working_dir = launch_info.GetWorkingDirectory(); - if (working_dir && - (!working_dir.ResolvePath() || - working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) { + 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", working_dir.GetCString()); return error; @@ -528,9 +545,7 @@ ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, void ProcessFreeBSD::RefreshStateAfterStop() { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, - (int)m_message_queue.size()); + LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size()); std::lock_guard<std::recursive_mutex> guard(m_message_mutex); @@ -542,10 +557,8 @@ void ProcessFreeBSD::RefreshStateAfterStop() { // Resolve the thread this message corresponds to and pass it along. lldb::tid_t tid = message.GetTID(); - if (log) - log->Printf( - "ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64, - __FUNCTION__, (int)m_message_queue.size(), tid); + LLDB_LOGV(log, " message_queue size = {0}, pid = {1}", + m_message_queue.size(), tid); m_thread_list.RefreshStateAfterStop(); @@ -557,10 +570,7 @@ void ProcessFreeBSD::RefreshStateAfterStop() { if (message.GetKind() == ProcessMessage::eExitMessage) { // FIXME: We should tell the user about this, but the limbo message is // probably better for that. - if (log) - log->Printf("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, - __FUNCTION__, tid); - + LLDB_LOG(log, "removing thread, tid = {0}", tid); std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); @@ -903,13 +913,207 @@ bool ProcessFreeBSD::IsAThreadRunning() { const DataBufferSP ProcessFreeBSD::GetAuxvData() { // If we're the local platform, we can ask the host for auxv data. PlatformSP platform_sp = GetTarget().GetPlatform(); - if (platform_sp && platform_sp->IsHost()) - return lldb_private::Host::GetAuxvData(this); + assert(platform_sp && platform_sp->IsHost()); + + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()}; + size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo); + DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0)); + + if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) { + perror("sysctl failed on auxv"); + buf_sp.reset(); + } + + return buf_sp; +} + +struct EmulatorBaton { + ProcessFreeBSD *m_process; + RegisterContext *m_reg_context; + + // eRegisterKindDWARF -> RegisterValue + std::unordered_map<uint32_t, RegisterValue> m_register_values; + + EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context) + : m_process(process), m_reg_context(reg_context) {} +}; + +static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, void *dst, size_t length) { + EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); + + Error error; + size_t bytes_read = + emulator_baton->m_process->DoReadMemory(addr, dst, length, error); + if (!error.Success()) + bytes_read = 0; + return bytes_read; +} - // Somewhat unexpected - the process is not running locally or we don't have a - // platform. - assert( - false && - "no platform or not the host - how did we get here with ProcessFreeBSD?"); - return DataBufferSP(); +static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton, + const RegisterInfo *reg_info, + RegisterValue ®_value) { + EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); + + auto it = emulator_baton->m_register_values.find( + reg_info->kinds[eRegisterKindDWARF]); + if (it != emulator_baton->m_register_values.end()) { + reg_value = it->second; + return true; + } + + // The emulator only fills in the dwarf register numbers (and in some cases + // the generic register numbers). Get the full register info from the + // register context based on the dwarf register numbers. + const RegisterInfo *full_reg_info = + emulator_baton->m_reg_context->GetRegisterInfo( + eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]); + + bool error = + emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value); + return error; +} + +static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton, + const EmulateInstruction::Context &context, + const RegisterInfo *reg_info, + const RegisterValue ®_value) { + EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); + emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = + reg_value; + return true; +} + +static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, const void *dst, + size_t length) { + return length; +} + +bool ProcessFreeBSD::SingleStepBreakpointHit( + void *baton, lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, lldb::user_id_t break_loc_id) { + return false; +} + +Error ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, + lldb::addr_t addr) { + Error error; + + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + if (log) { + log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr); + log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr); + } + + // Validate the address. + if (addr == LLDB_INVALID_ADDRESS) + return Error("ProcessFreeBSD::%s invalid load address specified.", + __FUNCTION__); + + Breakpoint *const sw_step_break = + m_process->GetTarget().CreateBreakpoint(addr, true, false).get(); + sw_step_break->SetCallback(SingleStepBreakpointHit, this, true); + sw_step_break->SetBreakpointKind("software-signle-step"); + + if (log) + log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS", + __FUNCTION__, addr); + + m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()}); + return Error(); +} + +bool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) { + ThreadSP thread = GetThreadList().FindThreadByID(tid); + if (!thread) + return false; + + assert(thread->GetRegisterContext()); + lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC(); + + const auto &iter = m_threads_stepping_with_breakpoint.find(tid); + if (iter == m_threads_stepping_with_breakpoint.end()) + return false; + + lldb::break_id_t bp_id = iter->second; + BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id); + if (!bp) + return false; + + BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc); + if (!bp_loc) + return false; + + GetTarget().RemoveBreakpointByID(bp_id); + m_threads_stepping_with_breakpoint.erase(tid); + return true; +} + +bool ProcessFreeBSD::SupportHardwareSingleStepping() const { + lldb_private::ArchSpec arch = GetTarget().GetArchitecture(); + if (arch.GetMachine() == llvm::Triple::arm || + arch.GetMachine() == llvm::Triple::mips64 || + arch.GetMachine() == llvm::Triple::mips64el || + arch.GetMachine() == llvm::Triple::mips || + arch.GetMachine() == llvm::Triple::mipsel) + return false; + return true; +} + +Error ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) { + std::unique_ptr<EmulateInstruction> emulator_ap( + EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(), + eInstructionTypePCModifying, nullptr)); + + if (emulator_ap == nullptr) + return Error("Instruction emulator not found!"); + + FreeBSDThread *thread = static_cast<FreeBSDThread *>( + m_thread_list.FindThreadByID(tid, false).get()); + if (thread == NULL) + return Error("Thread not found not found!"); + + lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext(); + + EmulatorBaton baton(this, register_context_sp.get()); + emulator_ap->SetBaton(&baton); + emulator_ap->SetReadMemCallback(&ReadMemoryCallback); + emulator_ap->SetReadRegCallback(&ReadRegisterCallback); + emulator_ap->SetWriteMemCallback(&WriteMemoryCallback); + emulator_ap->SetWriteRegCallback(&WriteRegisterCallback); + + if (!emulator_ap->ReadInstruction()) + return Error("Read instruction failed!"); + + bool emulation_result = + emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); + const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + auto pc_it = + baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]); + + lldb::addr_t next_pc; + if (emulation_result) { + assert(pc_it != baton.m_register_values.end() && + "Emulation was successful but PC wasn't updated"); + next_pc = pc_it->second.GetAsUInt64(); + } else if (pc_it == baton.m_register_values.end()) { + // Emulate instruction failed and it haven't changed PC. Advance PC + // with the size of the current opcode because the emulation of all + // PC modifying instruction should be successful. The failure most + // likely caused by a not supported instruction which don't modify PC. + next_pc = + register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize(); + } else { + // The instruction emulation failed after it modified the PC. It is an + // unknown error where we can't continue because the next instruction is + // modifying the PC but we don't know how. + return Error("Instruction emulation failed unexpectedly"); + } + + SetSoftwareSingleStepBreakpoint(tid, next_pc); + return Error(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h index cd38989f973cf..063eb6f681231 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h @@ -11,19 +11,13 @@ #ifndef liblldb_ProcessFreeBSD_H_ #define liblldb_ProcessFreeBSD_H_ -// C Includes - -// C++ Includes +#include "Plugins/Process/POSIX/ProcessMessage.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/ThreadList.h" #include <mutex> #include <queue> #include <set> -// Other libraries and framework includes -#include "ProcessFreeBSD.h" -#include "ProcessMessage.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/ThreadList.h" - class ProcessMonitor; class FreeBSDThread; @@ -171,7 +165,25 @@ public: virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid); + static bool SingleStepBreakpointHit( + void *baton, lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + + lldb_private::Error SetupSoftwareSingleStepping(lldb::tid_t tid); + + lldb_private::Error SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, + lldb::addr_t addr); + + bool IsSoftwareStepBreakpoint(lldb::tid_t tid); + + bool SupportHardwareSingleStepping() const; + + typedef std::vector<lldb::tid_t> tid_collection; + tid_collection &GetStepTids() { return m_step_tids; } + protected: + static const size_t MAX_TRAP_OPCODE_SIZE = 8; + /// Target byte order. lldb::ByteOrder m_byte_order; @@ -207,10 +219,10 @@ protected: friend class FreeBSDThread; - typedef std::vector<lldb::tid_t> tid_collection; tid_collection m_suspend_tids; tid_collection m_run_tids; tid_collection m_step_tids; + std::map<lldb::tid_t, lldb::break_id_t> m_threads_stepping_with_breakpoint; int m_resume_signo; }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index afc649de3b657..68ab41651162c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -21,21 +21,21 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/Error.h" #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/PseudoTerminal.h" +#include "lldb/Utility/Error.h" #include "FreeBSDThread.h" #include "Plugins/Process/POSIX/CrashReason.h" +#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" -#include "ProcessPOSIXLog.h" extern "C" { extern char **environ; @@ -1141,11 +1141,19 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, case SI_KERNEL: case TRAP_BRKPT: - if (log) - log->Printf( - "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, - __FUNCTION__, tid); - message = ProcessMessage::Break(tid); + if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) { + if (log) + log->Printf("ProcessMonitor::%s() received sw single step breakpoint " + "event, tid = %" PRIu64, + __FUNCTION__, tid); + message = ProcessMessage::Trace(tid); + } else { + if (log) + log->Printf( + "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, + __FUNCTION__, tid); + message = ProcessMessage::Break(tid); + } break; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 4c2594e9da6a0..58629189b7b8c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -18,8 +18,8 @@ #include <mutex> // Other libraries and framework includes -#include "lldb/Host/FileSpec.h" #include "lldb/Host/HostThread.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/lldb-types.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp index f8d5f2edd3a33..14171d614c9e7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp index 98a213a370fed..8a8eb0520cca6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "ProcessFreeBSD.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp index 020636eb0a6be..ab50a5db3f3eb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "ProcessFreeBSD.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h index 2f75e6058fbc0..6f57b0d9cd652 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h @@ -11,6 +11,7 @@ #define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_ #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" +#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h" #include "RegisterContextPOSIX.h" class RegisterContextPOSIXProcessMonitor_mips64 @@ -72,6 +73,8 @@ protected: uint32_t NumSupportedHardwareWatchpoints(); private: + uint64_t + m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers. ProcessMonitor &GetMonitor(); }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp index e7b01fa8634ad..70eec945ce8df 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp index 976b190b23555..036306058ff81 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" #include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" #include "Plugins/Process/FreeBSD/ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt new file mode 100644 index 0000000000000..5b2cef8b847be --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories(.) +include_directories(../POSIX) +include_directories(../Utility) + +add_lldb_library(lldbPluginProcessNetBSD PLUGIN + NativeProcessNetBSD.cpp + NativeRegisterContextNetBSD.cpp + NativeRegisterContextNetBSD_x86_64.cpp + NativeThreadNetBSD.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + lldbTarget + lldbUtility + lldbPluginProcessPOSIX + lldbPluginProcessUtility + LINK_COMPONENTS + Support + ) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp new file mode 100644 index 0000000000000..298faa48e1c3d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -0,0 +1,1018 @@ +//===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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" + +// System includes - They have to be included after framework includes because +// they define some +// macros which collide with variable names in other modules +// clang-format off +#include <sys/types.h> +#include <sys/ptrace.h> +#include <sys/sysctl.h> +#include <sys/wait.h> +#include <uvm/uvm_prot.h> +#include <elf.h> +#include <util.h> +// clang-format on + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_netbsd; +using namespace llvm; + +static ExitType convert_pid_status_to_exit_type(int status) { + if (WIFEXITED(status)) + return ExitType::eExitTypeExit; + else if (WIFSIGNALED(status)) + return ExitType::eExitTypeSignal; + else if (WIFSTOPPED(status)) + return ExitType::eExitTypeStop; + else { + // We don't know what this is. + return ExitType::eExitTypeInvalid; + } +} + +static int convert_pid_status_to_return_code(int status) { + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + return WTERMSIG(status); + else if (WIFSTOPPED(status)) + return WSTOPSIG(status); + else { + // We don't know what this is. + return ExitType::eExitTypeInvalid; + } +} + +// Simple helper function to ensure flags are enabled on the given file +// descriptor. +static Error EnsureFDFlags(int fd, int flags) { + Error error; + + int status = fcntl(fd, F_GETFL); + if (status == -1) { + error.SetErrorToErrno(); + return error; + } + + if (fcntl(fd, F_SETFL, status | flags) == -1) { + error.SetErrorToErrno(); + return error; + } + + return error; +} + +// ----------------------------------------------------------------------------- +// Public Static Methods +// ----------------------------------------------------------------------------- + +Error NativeProcessProtocol::Launch( + ProcessLaunchInfo &launch_info, + NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop, + NativeProcessProtocolSP &native_process_sp) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + + Error error; + + // 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", + working_dir.GetCString()); + return error; + } + + // Create the NativeProcessNetBSD in launch mode. + native_process_sp.reset(new NativeProcessNetBSD()); + + if (!native_process_sp->RegisterNativeDelegate(native_delegate)) { + native_process_sp.reset(); + error.SetErrorStringWithFormat("failed to register the native delegate"); + return error; + } + + error = std::static_pointer_cast<NativeProcessNetBSD>(native_process_sp) + ->LaunchInferior(mainloop, launch_info); + + if (error.Fail()) { + native_process_sp.reset(); + LLDB_LOG(log, "failed to launch process: {0}", error); + return error; + } + + launch_info.SetProcessID(native_process_sp->GetID()); + + return error; +} + +Error NativeProcessProtocol::Attach( + lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, + MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "pid = {0:x}", pid); + + // Retrieve the architecture for the running process. + ArchSpec process_arch; + Error error = ResolveProcessArchitecture(pid, process_arch); + if (!error.Success()) + return error; + + std::shared_ptr<NativeProcessNetBSD> native_process_netbsd_sp( + new NativeProcessNetBSD()); + + if (!native_process_netbsd_sp->RegisterNativeDelegate(native_delegate)) { + error.SetErrorStringWithFormat("failed to register the native delegate"); + return error; + } + + native_process_netbsd_sp->AttachToInferior(mainloop, pid, error); + if (!error.Success()) + return error; + + native_process_sp = native_process_netbsd_sp; + return error; +} + +// ----------------------------------------------------------------------------- +// Public Instance Methods +// ----------------------------------------------------------------------------- + +NativeProcessNetBSD::NativeProcessNetBSD() + : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(), + m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache() {} + +// Handles all waitpid events from the inferior process. +void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + + switch (signal) { + case SIGTRAP: + return MonitorSIGTRAP(pid); + case SIGSTOP: + return MonitorSIGSTOP(pid); + default: + return MonitorSignal(pid, signal); + } +} + +void NativeProcessNetBSD::MonitorExited(lldb::pid_t pid, int signal, + int status) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + + LLDB_LOG(log, "got exit signal({0}) , pid = {1}", signal, pid); + + /* Stop Tracking All Threads attached to Process */ + m_threads.clear(); + + SetExitStatus(convert_pid_status_to_exit_type(status), + convert_pid_status_to_return_code(status), nullptr, true); + + // Notify delegate that our process has exited. + SetState(StateType::eStateExited, true); +} + +void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + ptrace_siginfo_t info; + + const auto siginfo_err = + PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); + + // Get details on the signal raised. + if (siginfo_err.Success()) { + // Handle SIGSTOP from LLGS (LLDB GDB Server) + if (info.psi_siginfo.si_code == SI_USER && + info.psi_siginfo.si_pid == ::getpid()) { + /* Stop Tracking All Threads attached to Process */ + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal( + SIGSTOP, &info.psi_siginfo); + } + } + } +} + +void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + ptrace_siginfo_t info; + + const auto siginfo_err = + PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); + + // Get details on the signal raised. + if (siginfo_err.Success()) { + switch (info.psi_siginfo.si_code) { + case TRAP_BRKPT: + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp) + ->SetStoppedByBreakpoint(); + FixupBreakpointPCAsNeeded( + *static_pointer_cast<NativeThreadNetBSD>(thread_sp)); + } + SetState(StateType::eStateStopped, true); + break; + case TRAP_TRACE: + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace(); + } + SetState(StateType::eStateStopped, true); + break; + case TRAP_EXEC: { + Error error = ReinitializeThreads(); + if (error.Fail()) { + SetState(StateType::eStateInvalid); + return; + } + + // Let our delegate know we have just exec'd. + NotifyDidExec(); + + SetState(StateType::eStateStopped, true); + } break; + } + } +} + +void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + + ptrace_siginfo_t info; + const auto siginfo_err = + PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); + + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal( + info.psi_siginfo.si_signo, &info.psi_siginfo); + } + SetState(StateType::eStateStopped, true); +} + +Error NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, + int data, int *result) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); + Error error; + int ret; + + errno = 0; + ret = ptrace(req, static_cast<::pid_t>(pid), addr, data); + + if (ret == -1) + error.SetErrorToErrno(); + + if (result) + *result = ret; + + LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret); + + if (error.Fail()) + LLDB_LOG(log, "ptrace() failed: {0}", error); + + return error; +} + +Error 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 Error(); + default: + assert(false && "CPU type not supported!"); + return Error("CPU type not supported"); + } +} + +Error NativeProcessNetBSD::FixupBreakpointPCAsNeeded( + NativeThreadNetBSD &thread) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); + Error error; + // Find out the size of a breakpoint (might depend on where we are in the + // code). + NativeRegisterContextSP context_sp = thread.GetRegisterContext(); + if (!context_sp) { + error.SetErrorString("cannot get a NativeRegisterContext for the thread"); + LLDB_LOG(log, "failed: {0}", error); + return error; + } + 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_sp->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 Error(); + } + // 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 Error(); + } + // + // 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 Error(); + } + // + // 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 Error(); + } + // 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_sp->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; +} + +Error NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "pid {0}", GetID()); + + const auto &thread_sp = m_threads[0]; + const ResumeAction *const action = + resume_actions.GetActionForThread(thread_sp->GetID(), true); + + if (action == nullptr) { + LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(), + thread_sp->GetID()); + return Error(); + } + + Error error; + + switch (action->state) { + case eStateRunning: { + // Run the thread, possibly feeding it the signal. + error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1, + action->signal); + if (!error.Success()) + return error; + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning(); + } + SetState(eStateRunning, true); + break; + } + case eStateStepping: + // Run the thread, possibly feeding it the signal. + error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1, + action->signal); + if (!error.Success()) + return error; + for (const auto &thread_sp : m_threads) { + static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStepping(); + } + SetState(eStateStepping, true); + break; + + case eStateSuspended: + case eStateStopped: + llvm_unreachable("Unexpected state"); + + default: + return Error("NativeProcessLinux::%s (): unexpected state %s specified " + "for pid %" PRIu64 ", tid %" PRIu64, + __FUNCTION__, StateAsCString(action->state), GetID(), + thread_sp->GetID()); + } + + return Error(); +} + +Error NativeProcessNetBSD::Halt() { + Error error; + + if (kill(GetID(), SIGSTOP) != 0) + error.SetErrorToErrno(); + + return error; +} + +Error NativeProcessNetBSD::Detach() { + Error error; + + // Stop monitoring the inferior. + m_sigchld_handle.reset(); + + // Tell ptrace to detach from the process. + if (GetID() == LLDB_INVALID_PROCESS_ID) + return error; + + return PtraceWrapper(PT_DETACH, GetID()); +} + +Error NativeProcessNetBSD::Signal(int signo) { + Error error; + + if (kill(GetID(), signo)) + error.SetErrorToErrno(); + + return error; +} + +Error NativeProcessNetBSD::Kill() { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "pid {0}", GetID()); + + Error error; + + switch (m_state) { + case StateType::eStateInvalid: + case StateType::eStateExited: + case StateType::eStateCrashed: + case StateType::eStateDetached: + case StateType::eStateUnloaded: + // Nothing to do - the process is already dead. + LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(), + StateAsCString(m_state)); + return error; + + case StateType::eStateConnected: + case StateType::eStateAttaching: + case StateType::eStateLaunching: + case StateType::eStateStopped: + case StateType::eStateRunning: + case StateType::eStateStepping: + case StateType::eStateSuspended: + // We can try to kill a process in these states. + break; + } + + if (kill(GetID(), SIGKILL) != 0) { + error.SetErrorToErrno(); + return error; + } + + return error; +} + +Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) { + + if (m_supports_mem_region == LazyBool::eLazyBoolNo) { + // We're done. + return Error("unsupported"); + } + + Error error = PopulateMemoryRegionCache(); + if (error.Fail()) { + return error; + } + + lldb::addr_t prev_base_address = 0; + // FIXME start by finding the last region that is <= target address using + // binary search. Data is sorted. + // There can be a ton of regions on pthreads apps with lots of threads. + for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end(); + ++it) { + MemoryRegionInfo &proc_entry_info = it->first; + // Sanity check assumption that memory map entries are ascending. + assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) && + "descending memory map entries detected, unexpected"); + prev_base_address = proc_entry_info.GetRange().GetRangeBase(); + UNUSED_IF_ASSERT_DISABLED(prev_base_address); + // If the target address comes before this entry, indicate distance to next + // region. + if (load_addr < proc_entry_info.GetRange().GetRangeBase()) { + range_info.GetRange().SetRangeBase(load_addr); + range_info.GetRange().SetByteSize( + proc_entry_info.GetRange().GetRangeBase() - load_addr); + range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); + return error; + } else if (proc_entry_info.GetRange().Contains(load_addr)) { + // The target address is within the memory region we're processing here. + range_info = proc_entry_info; + return error; + } + // The target memory address comes somewhere after the region we just + // parsed. + } + // If we made it here, we didn't find an entry that contained the given + // address. Return the + // load_addr as start and the amount of bytes betwwen load address and the end + // of the memory as + // size. + range_info.GetRange().SetRangeBase(load_addr); + range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); + range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); + return error; +} + +Error NativeProcessNetBSD::PopulateMemoryRegionCache() { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + // If our cache is empty, pull the latest. There should always be at least + // one memory region if memory region handling is supported. + if (!m_mem_region_cache.empty()) { + LLDB_LOG(log, "reusing {0} cached memory region entries", + m_mem_region_cache.size()); + return Error(); + } + + struct kinfo_vmentry *vm; + size_t count, i; + vm = kinfo_getvmmap(GetID(), &count); + if (vm == NULL) { + m_supports_mem_region = LazyBool::eLazyBoolNo; + Error error; + error.SetErrorString("not supported"); + return error; + } + for (i = 0; i < count; i++) { + MemoryRegionInfo info; + info.Clear(); + info.GetRange().SetRangeBase(vm[i].kve_start); + info.GetRange().SetRangeEnd(vm[i].kve_end); + info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); + + if (vm[i].kve_protection & VM_PROT_READ) + info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); + else + info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + + if (vm[i].kve_protection & VM_PROT_WRITE) + info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); + else + info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + + if (vm[i].kve_protection & VM_PROT_EXECUTE) + info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); + else + info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + + if (vm[i].kve_path[0]) + info.SetName(vm[i].kve_path); + + m_mem_region_cache.emplace_back( + info, FileSpec(info.GetName().GetCString(), true)); + } + free(vm); + + if (m_mem_region_cache.empty()) { + // No entries after attempting to read them. This shouldn't happen. + // Assume we don't support map entries. + LLDB_LOG(log, "failed to find any vmmap entries, assuming no support " + "for memory region metadata retrieval"); + m_supports_mem_region = LazyBool::eLazyBoolNo; + Error error; + error.SetErrorString("not supported"); + return error; + } + LLDB_LOG(log, "read {0} memory region entries from process {1}", + m_mem_region_cache.size(), GetID()); + // We support memory retrieval, remember that. + m_supports_mem_region = LazyBool::eLazyBoolYes; + return Error(); +} + +Error NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions, + lldb::addr_t &addr) { + return Error("Unimplemented"); +} + +Error NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) { + return Error("Unimplemented"); +} + +lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() { + // punt on this for now + return LLDB_INVALID_ADDRESS; +} + +size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); } + +bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const { + arch = m_arch; + return true; +} + +Error NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size, + bool hardware) { + if (hardware) + return Error("NativeProcessNetBSD does not support hardware breakpoints"); + else + return SetSoftwareBreakpoint(addr, size); +} + +Error 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 Error(); + default: + assert(false && "CPU type not supported!"); + return Error("CPU type not supported"); + } +} + +Error NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path, + FileSpec &file_spec) { + return Error("Unimplemented"); +} + +Error NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name, + lldb::addr_t &load_addr) { + load_addr = LLDB_INVALID_ADDRESS; + return Error(); +} + +Error NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop, + ProcessLaunchInfo &launch_info) { + Error error; + m_sigchld_handle = mainloop.RegisterSignal( + SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error); + if (!m_sigchld_handle) + return error; + + SetState(eStateLaunching); + + ::pid_t pid = ProcessLauncherPosixFork() + .LaunchProcess(launch_info, error) + .GetProcessId(); + if (error.Fail()) + return error; + + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + + // Wait for the child process to trap on its call to execve. + ::pid_t wpid; + int status; + if ((wpid = waitpid(pid, &status, 0)) < 0) { + error.SetErrorToErrno(); + LLDB_LOG(log, "waitpid for inferior failed with %s", error); + + // Mark the inferior as invalid. + // FIXME this could really use a new state - eStateLaunchFailure. For now, + // using eStateInvalid. + SetState(StateType::eStateInvalid); + + return error; + } + assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) && + "Could not sync with inferior process."); + + LLDB_LOG(log, "inferior started, now in stopped state"); + + // Release the master terminal descriptor and pass it off to the + // NativeProcessNetBSD instance. Similarly stash the inferior pid. + m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + m_pid = pid; + launch_info.SetProcessID(pid); + + if (m_terminal_fd != -1) { + error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); + if (error.Fail()) { + LLDB_LOG(log, + "inferior EnsureFDFlags failed for ensuring terminal " + "O_NONBLOCK setting: {0}", + error); + + // Mark the inferior as invalid. + // FIXME this could really use a new state - eStateLaunchFailure. For + // now, using eStateInvalid. + SetState(StateType::eStateInvalid); + + return error; + } + } + + LLDB_LOG(log, "adding pid = {0}", pid); + + ResolveProcessArchitecture(m_pid, m_arch); + + error = ReinitializeThreads(); + if (error.Fail()) { + SetState(StateType::eStateInvalid); + return error; + } + + /* Set process stopped */ + SetState(StateType::eStateStopped); + + if (error.Fail()) + LLDB_LOG(log, "inferior launching failed {0}", error); + return error; +} + +void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, + Error &error) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "pid = {0:x}", pid); + + m_sigchld_handle = mainloop.RegisterSignal( + SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error); + if (!m_sigchld_handle) + return; + + error = ResolveProcessArchitecture(pid, m_arch); + if (!error.Success()) + return; + + // Set the architecture to the exe architecture. + LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid, + m_arch.GetArchitectureName()); + + m_pid = pid; + SetState(eStateAttaching); + + Attach(pid, error); +} + +void NativeProcessNetBSD::SigchldHandler() { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + // Process all pending waitpid notifications. + int status; + ::pid_t wait_pid = waitpid(GetID(), &status, WALLSIG | WNOHANG); + + if (wait_pid == 0) + return; // We are done. + + if (wait_pid == -1) { + if (errno == EINTR) + return; + + Error error(errno, eErrorTypePOSIX); + LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); + } + + bool exited = false; + int signal = 0; + int exit_status = 0; + const char *status_cstr = nullptr; + if (WIFSTOPPED(status)) { + signal = WSTOPSIG(status); + status_cstr = "STOPPED"; + } else if (WIFEXITED(status)) { + exit_status = WEXITSTATUS(status); + status_cstr = "EXITED"; + exited = true; + } else if (WIFSIGNALED(status)) { + signal = WTERMSIG(status); + status_cstr = "SIGNALED"; + if (wait_pid == static_cast<::pid_t>(GetID())) { + exited = true; + exit_status = -1; + } + } else + status_cstr = "(\?\?\?)"; + + LLDB_LOG(log, + "waitpid ({0}, &status, _) => pid = {1}, status = {2:x} " + "({3}), signal = {4}, exit_state = {5}", + GetID(), wait_pid, status, status_cstr, signal, exit_status); + + if (exited) + MonitorExited(wait_pid, signal, exit_status); + else + MonitorCallback(wait_pid, signal); +} + +NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) { + + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id); + + assert(!HasThreadNoLock(thread_id) && + "attempted to add a thread by id that already exists"); + + // If this is the first thread, save it as the current thread + if (m_threads.empty()) + SetCurrentThreadID(thread_id); + + auto thread_sp = std::make_shared<NativeThreadNetBSD>(this, thread_id); + m_threads.push_back(thread_sp); + return thread_sp; +} + +::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Error &error) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + if (pid <= 1) { + error.SetErrorToGenericError(); + error.SetErrorString("Attaching to process 1 is not allowed."); + return -1; + } + + // Attach to the requested process. + // An attach will cause the thread to stop with a SIGSTOP. + error = PtraceWrapper(PT_ATTACH, pid); + if (error.Fail()) + return -1; + + int status; + // Need to use WALLSIG otherwise we receive an error with errno=ECHLD + // At this point we should have a thread stopped if waitpid succeeds. + if ((status = waitpid(pid, NULL, WALLSIG)) < 0) + return -1; + + m_pid = pid; + + /* Initialize threads */ + error = ReinitializeThreads(); + if (error.Fail()) { + SetState(StateType::eStateInvalid); + return -1; + } + + // Let our process instance know the thread has stopped. + SetState(StateType::eStateStopped); + + return pid; +} + +Error NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, size_t size, + size_t &bytes_read) { + unsigned char *dst = static_cast<unsigned char *>(buf); + struct ptrace_io_desc io; + + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); + + bytes_read = 0; + io.piod_op = PIOD_READ_D; + io.piod_len = size; + + do { + io.piod_offs = (void *)(addr + bytes_read); + io.piod_addr = dst + bytes_read; + + Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); + if (error.Fail()) + return error; + + bytes_read = io.piod_len; + io.piod_len = size - bytes_read; + } while (bytes_read < size); + + return Error(); +} + +Error NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, + size_t size, + size_t &bytes_read) { + Error error = ReadMemory(addr, buf, size, bytes_read); + if (error.Fail()) + return error; + return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size); +} + +Error 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); + Error error; + struct ptrace_io_desc io; + + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); + + bytes_written = 0; + io.piod_op = PIOD_WRITE_D; + io.piod_len = size; + + do { + io.piod_addr = (void *)(src + bytes_written); + io.piod_offs = (void *)(addr + bytes_written); + + Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); + if (error.Fail()) + return error; + + bytes_written = io.piod_len; + io.piod_len = size - bytes_written; + } while (bytes_written < size); + + return error; +} + +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +NativeProcessNetBSD::GetAuxvData() const { + /* + * ELF_AUX_ENTRIES is currently restricted to kernel + * (<sys/exec_elf.h> r. 1.155 specifies 15) + * + * ptrace(2) returns the whole AUXV including extra fiels after AT_NULL this + * information isn't needed. + */ + size_t auxv_size = 100 * sizeof(AuxInfo); + + ErrorOr<std::unique_ptr<MemoryBuffer>> buf = + llvm::MemoryBuffer::getNewMemBuffer(auxv_size); + + struct ptrace_io_desc io = {.piod_op = PIOD_READ_AUXV, + .piod_offs = 0, + .piod_addr = (void *)buf.get()->getBufferStart(), + .piod_len = auxv_size}; + + Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); + + if (error.Fail()) + return std::error_code(error.GetError(), std::generic_category()); + + if (io.piod_len < 1) + return std::error_code(ECANCELED, std::generic_category()); + + return buf; +} + +Error NativeProcessNetBSD::ReinitializeThreads() { + // Clear old threads + m_threads.clear(); + + // Initialize new thread + struct ptrace_lwpinfo info = {}; + Error error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info)); + if (error.Fail()) { + return error; + } + // Reinitialize from scratch threads and register them in process + while (info.pl_lwpid != 0) { + NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid); + thread_sp->SetStoppedByExec(); + error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info)); + if (error.Fail()) { + return error; + } + } + + return error; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h new file mode 100644 index 0000000000000..ae946a8e004d0 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -0,0 +1,141 @@ +//===-- NativeProcessNetBSD.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_NativeProcessNetBSD_H_ +#define liblldb_NativeProcessNetBSD_H_ + +// C++ Includes + +// Other libraries and framework includes + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/FileSpec.h" + +#include "NativeThreadNetBSD.h" +#include "lldb/Host/common/NativeProcessProtocol.h" + +namespace lldb_private { +namespace process_netbsd { +/// @class NativeProcessNetBSD +/// @brief Manages communication with the inferior (debugee) process. +/// +/// Upon construction, this class prepares and launches an inferior process for +/// debugging. +/// +/// Changes in the inferior process state are broadcasted. +class NativeProcessNetBSD : public NativeProcessProtocol { + friend Error NativeProcessProtocol::Launch( + ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, + MainLoop &mainloop, NativeProcessProtocolSP &process_sp); + + friend Error NativeProcessProtocol::Attach( + lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, + MainLoop &mainloop, NativeProcessProtocolSP &process_sp); + +public: + // --------------------------------------------------------------------- + // NativeProcessProtocol Interface + // --------------------------------------------------------------------- + Error Resume(const ResumeActionList &resume_actions) override; + + Error Halt() override; + + Error Detach() override; + + Error Signal(int signo) override; + + Error Kill() override; + + Error GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + + Error ReadMemory(lldb::addr_t addr, void *buf, size_t size, + size_t &bytes_read) override; + + Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, + size_t &bytes_read) override; + + Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size, + size_t &bytes_written) override; + + Error AllocateMemory(size_t size, uint32_t permissions, + lldb::addr_t &addr) override; + + Error DeallocateMemory(lldb::addr_t addr) override; + + lldb::addr_t GetSharedLibraryInfoAddress() override; + + size_t UpdateThreads() override; + + bool GetArchitecture(ArchSpec &arch) const override; + + Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override; + + Error GetLoadedModuleFileSpec(const char *module_path, + FileSpec &file_spec) override; + + Error GetFileLoadAddress(const llvm::StringRef &file_name, + lldb::addr_t &load_addr) override; + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> + GetAuxvData() const override; + + // --------------------------------------------------------------------- + // Interface used by NativeRegisterContext-derived classes. + // --------------------------------------------------------------------- + static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, + int data = 0, int *result = nullptr); + +protected: + // --------------------------------------------------------------------- + // NativeProcessProtocol protected interface + // --------------------------------------------------------------------- + + Error + 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; + LazyBool m_supports_mem_region; + std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache; + + // --------------------------------------------------------------------- + // Private Instance Methods + // --------------------------------------------------------------------- + NativeProcessNetBSD(); + + NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id); + + Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info); + void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error); + + void MonitorCallback(lldb::pid_t pid, int signal); + void MonitorExited(lldb::pid_t pid, int signal, int status); + void MonitorSIGSTOP(lldb::pid_t pid); + void MonitorSIGTRAP(lldb::pid_t pid); + void MonitorSignal(lldb::pid_t pid, int signal); + + Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); + Error FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread); + Error PopulateMemoryRegionCache(); + void SigchldHandler(); + + ::pid_t Attach(lldb::pid_t pid, Error &error); + + Error ReinitializeThreads(); +}; + +} // namespace process_netbsd +} // namespace lldb_private + +#endif // #ifndef liblldb_NativeProcessNetBSD_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp new file mode 100644 index 0000000000000..1bb6324c97fe3 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp @@ -0,0 +1,92 @@ +//===-- NativeRegisterContextNetBSD.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "NativeRegisterContextNetBSD.h" + +#include "lldb/Host/common/NativeProcessProtocol.h" + +using namespace lldb_private; +using namespace lldb_private::process_netbsd; + +// clang-format off +#include <sys/types.h> +#include <sys/ptrace.h> +// clang-format on + +NativeRegisterContextNetBSD::NativeRegisterContextNetBSD( + NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *reg_info_interface_p) + : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx, + reg_info_interface_p) {} + +Error NativeRegisterContextNetBSD::ReadGPR() { + void *buf = GetGPRBuffer(); + if (!buf) + return Error("GPR buffer is NULL"); + + return DoReadGPR(buf); +} + +Error NativeRegisterContextNetBSD::WriteGPR() { + void *buf = GetGPRBuffer(); + if (!buf) + return Error("GPR buffer is NULL"); + + return DoWriteGPR(buf); +} + +Error NativeRegisterContextNetBSD::ReadFPR() { + void *buf = GetFPRBuffer(); + if (!buf) + return Error("FPR buffer is NULL"); + + return DoReadFPR(buf); +} + +Error NativeRegisterContextNetBSD::WriteFPR() { + void *buf = GetFPRBuffer(); + if (!buf) + return Error("FPR buffer is NULL"); + + return DoWriteFPR(buf); +} + +Error NativeRegisterContextNetBSD::DoReadGPR(void *buf) { + return NativeProcessNetBSD::PtraceWrapper(PT_GETREGS, GetProcessPid(), buf, + m_thread.GetID()); +} + +Error NativeRegisterContextNetBSD::DoWriteGPR(void *buf) { + return NativeProcessNetBSD::PtraceWrapper(PT_SETREGS, GetProcessPid(), buf, + m_thread.GetID()); +} + +Error NativeRegisterContextNetBSD::DoReadFPR(void *buf) { + return NativeProcessNetBSD::PtraceWrapper(PT_GETFPREGS, GetProcessPid(), buf, + m_thread.GetID()); +} + +Error NativeRegisterContextNetBSD::DoWriteFPR(void *buf) { + return NativeProcessNetBSD::PtraceWrapper(PT_SETFPREGS, GetProcessPid(), buf, + m_thread.GetID()); +} + +NativeProcessNetBSD &NativeRegisterContextNetBSD::GetProcess() { + auto process_sp = + std::static_pointer_cast<NativeProcessNetBSD>(m_thread.GetProcess()); + assert(process_sp); + return *process_sp; +} + +::pid_t NativeRegisterContextNetBSD::GetProcessPid() { + NativeProcessNetBSD &process = GetProcess(); + lldb::pid_t pid = process.GetID(); + + return pid; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h new file mode 100644 index 0000000000000..5ff59bc87c989 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h @@ -0,0 +1,65 @@ +//===-- NativeRegisterContextNetBSD.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_NativeRegisterContextNetBSD_h +#define lldb_NativeRegisterContextNetBSD_h + +#include "lldb/Host/common/NativeThreadProtocol.h" + +#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h" +#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" + +namespace lldb_private { +namespace process_netbsd { + +class NativeRegisterContextNetBSD : public NativeRegisterContextRegisterInfo { +public: + NativeRegisterContextNetBSD(NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx, + RegisterInfoInterface *reg_info_interface_p); + + // This function is implemented in the NativeRegisterContextNetBSD_* + // subclasses to create a new instance of the host specific + // NativeRegisterContextNetBSD. The implementations can't collide as only one + // NativeRegisterContextNetBSD_* variant should be compiled into the final + // executable. + static NativeRegisterContextNetBSD * + CreateHostNativeRegisterContextNetBSD(const ArchSpec &target_arch, + NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx); + +protected: + virtual Error ReadGPR(); + virtual Error WriteGPR(); + + virtual Error ReadFPR(); + virtual Error WriteFPR(); + + virtual void *GetGPRBuffer() { return nullptr; } + virtual size_t GetGPRSize() { + return GetRegisterInfoInterface().GetGPRSize(); + } + + virtual void *GetFPRBuffer() { return nullptr; } + virtual size_t GetFPRSize() { return 0; } + + virtual Error DoReadGPR(void *buf); + virtual Error DoWriteGPR(void *buf); + + virtual Error DoReadFPR(void *buf); + virtual Error DoWriteFPR(void *buf); + + virtual NativeProcessNetBSD &GetProcess(); + virtual ::pid_t GetProcessPid(); +}; + +} // namespace process_netbsd +} // namespace lldb_private + +#endif // #ifndef lldb_NativeRegisterContextNetBSD_h diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp new file mode 100644 index 0000000000000..76e64ac48d66f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -0,0 +1,483 @@ +//===-- NativeRegisterContextNetBSD_x86_64.cpp ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#if defined(__x86_64__) + +#include "NativeRegisterContextNetBSD_x86_64.h" + +#include "lldb/Core/RegisterValue.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Log.h" + +#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" + +#include <elf.h> + +using namespace lldb_private; +using namespace lldb_private::process_netbsd; + +// ---------------------------------------------------------------------------- +// Private namespace. +// ---------------------------------------------------------------------------- + +namespace { +// x86 64-bit general purpose registers. +static const uint32_t g_gpr_regnums_x86_64[] = { + lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, + lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64, + lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64, + lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64, + lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64, + lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64, + lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64, + lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64, + lldb_r8d_x86_64, // Low 32 bits or r8 + lldb_r9d_x86_64, // Low 32 bits or r9 + lldb_r10d_x86_64, // Low 32 bits or r10 + lldb_r11d_x86_64, // Low 32 bits or r11 + lldb_r12d_x86_64, // Low 32 bits or r12 + lldb_r13d_x86_64, // Low 32 bits or r13 + lldb_r14d_x86_64, // Low 32 bits or r14 + lldb_r15d_x86_64, // Low 32 bits or r15 + lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64, + lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64, + lldb_r8w_x86_64, // Low 16 bits or r8 + lldb_r9w_x86_64, // Low 16 bits or r9 + lldb_r10w_x86_64, // Low 16 bits or r10 + lldb_r11w_x86_64, // Low 16 bits or r11 + lldb_r12w_x86_64, // Low 16 bits or r12 + lldb_r13w_x86_64, // Low 16 bits or r13 + lldb_r14w_x86_64, // Low 16 bits or r14 + lldb_r15w_x86_64, // Low 16 bits or r15 + lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64, + lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64, + lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64, + lldb_r8l_x86_64, // Low 8 bits or r8 + lldb_r9l_x86_64, // Low 8 bits or r9 + lldb_r10l_x86_64, // Low 8 bits or r10 + lldb_r11l_x86_64, // Low 8 bits or r11 + lldb_r12l_x86_64, // Low 8 bits or r12 + lldb_r13l_x86_64, // Low 8 bits or r13 + lldb_r14l_x86_64, // Low 8 bits or r14 + lldb_r15l_x86_64, // Low 8 bits or r15 + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - + 1 == + k_num_gpr_registers_x86_64, + "g_gpr_regnums_x86_64 has wrong number of register infos"); + +// Number of register sets provided by this context. +enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 }; + +// Register sets for x86 64-bit. +static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, + g_gpr_regnums_x86_64}, +}; + +#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize()) + +} // namespace + +NativeRegisterContextNetBSD * +NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD( + const ArchSpec &target_arch, NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx) { + return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread, + concrete_frame_idx); +} + +// ---------------------------------------------------------------------------- +// NativeRegisterContextNetBSD_x86_64 members. +// ---------------------------------------------------------------------------- + +static RegisterInfoInterface * +CreateRegisterInfoInterface(const ArchSpec &target_arch) { + assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && + "Register setting path assumes this is a 64-bit host"); + // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the + // x86_64 register context. + return new RegisterContextNetBSD_x86_64(target_arch); +} + +NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64( + const ArchSpec &target_arch, NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx) + : NativeRegisterContextNetBSD(native_thread, concrete_frame_idx, + CreateRegisterInfoInterface(target_arch)), + m_gpr_x86_64() {} + +// CONSIDER after local and llgs debugging are merged, register set support can +// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. +uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const { + uint32_t sets = 0; + for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { + if (GetSetForNativeRegNum(set_index) != -1) + ++sets; + } + + return sets; +} + +const RegisterSet * +NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const { + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86_64: + return &g_reg_sets_x86_64[set_index]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + + return nullptr; +} + +int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( + int reg_num) const { + if (reg_num < lldb_fctrl_x86_64) + return GPRegSet; + else + return -1; +} + +int NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { + switch (set) { + case GPRegSet: + ReadGPR(); + return 0; + case FPRegSet: + ReadFPR(); + return 0; + default: + break; + } + return -1; +} +int NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { + switch (set) { + case GPRegSet: + WriteGPR(); + return 0; + case FPRegSet: + WriteFPR(); + return 0; + default: + break; + } + return -1; +} + +Error NativeRegisterContextNetBSD_x86_64::ReadRegister( + const RegisterInfo *reg_info, RegisterValue ®_value) { + Error error; + + if (!reg_info) { + error.SetErrorString("reg_info NULL"); + return error; + } + + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " + "register, cannot read directly", + reg_info->name); + return error; + } + + int set = GetSetForNativeRegNum(reg); + if (set == -1) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + if (ReadRegisterSet(set) != 0) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat( + "reading register set for register \"%s\" failed", reg_info->name); + return error; + } + + switch (reg) { + case lldb_rax_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RAX]; + break; + case lldb_rbx_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBX]; + break; + case lldb_rcx_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RCX]; + break; + case lldb_rdx_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDX]; + break; + case lldb_rdi_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDI]; + break; + case lldb_rsi_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSI]; + break; + case lldb_rbp_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBP]; + break; + case lldb_rsp_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSP]; + break; + case lldb_r8_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R8]; + break; + case lldb_r9_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R9]; + break; + case lldb_r10_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R10]; + break; + case lldb_r11_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R11]; + break; + case lldb_r12_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R12]; + break; + case lldb_r13_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R13]; + break; + case lldb_r14_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R14]; + break; + case lldb_r15_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R15]; + break; + case lldb_rip_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RIP]; + break; + case lldb_rflags_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RFLAGS]; + break; + case lldb_cs_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_CS]; + break; + case lldb_fs_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_FS]; + break; + case lldb_gs_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_GS]; + break; + case lldb_ss_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_SS]; + break; + case lldb_ds_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_DS]; + break; + case lldb_es_x86_64: + reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES]; + break; + } + + return error; +} + +Error NativeRegisterContextNetBSD_x86_64::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue ®_value) { + + Error error; + + if (!reg_info) { + error.SetErrorString("reg_info NULL"); + return error; + } + + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " + "register, cannot read directly", + reg_info->name); + return error; + } + + int set = GetSetForNativeRegNum(reg); + if (set == -1) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + if (ReadRegisterSet(set) != 0) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat( + "reading register set for register \"%s\" failed", reg_info->name); + return error; + } + + switch (reg) { + case lldb_rax_x86_64: + m_gpr_x86_64.regs[_REG_RAX] = reg_value.GetAsUInt64(); + break; + case lldb_rbx_x86_64: + m_gpr_x86_64.regs[_REG_RBX] = reg_value.GetAsUInt64(); + break; + case lldb_rcx_x86_64: + m_gpr_x86_64.regs[_REG_RCX] = reg_value.GetAsUInt64(); + break; + case lldb_rdx_x86_64: + m_gpr_x86_64.regs[_REG_RDX] = reg_value.GetAsUInt64(); + break; + case lldb_rdi_x86_64: + m_gpr_x86_64.regs[_REG_RDI] = reg_value.GetAsUInt64(); + break; + case lldb_rsi_x86_64: + m_gpr_x86_64.regs[_REG_RSI] = reg_value.GetAsUInt64(); + break; + case lldb_rbp_x86_64: + m_gpr_x86_64.regs[_REG_RBP] = reg_value.GetAsUInt64(); + break; + case lldb_rsp_x86_64: + m_gpr_x86_64.regs[_REG_RSP] = reg_value.GetAsUInt64(); + break; + case lldb_r8_x86_64: + m_gpr_x86_64.regs[_REG_R8] = reg_value.GetAsUInt64(); + break; + case lldb_r9_x86_64: + m_gpr_x86_64.regs[_REG_R9] = reg_value.GetAsUInt64(); + break; + case lldb_r10_x86_64: + m_gpr_x86_64.regs[_REG_R10] = reg_value.GetAsUInt64(); + break; + case lldb_r11_x86_64: + m_gpr_x86_64.regs[_REG_R11] = reg_value.GetAsUInt64(); + break; + case lldb_r12_x86_64: + m_gpr_x86_64.regs[_REG_R12] = reg_value.GetAsUInt64(); + break; + case lldb_r13_x86_64: + m_gpr_x86_64.regs[_REG_R13] = reg_value.GetAsUInt64(); + break; + case lldb_r14_x86_64: + m_gpr_x86_64.regs[_REG_R14] = reg_value.GetAsUInt64(); + break; + case lldb_r15_x86_64: + m_gpr_x86_64.regs[_REG_R15] = reg_value.GetAsUInt64(); + break; + case lldb_rip_x86_64: + m_gpr_x86_64.regs[_REG_RIP] = reg_value.GetAsUInt64(); + break; + case lldb_rflags_x86_64: + m_gpr_x86_64.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); + break; + case lldb_cs_x86_64: + m_gpr_x86_64.regs[_REG_CS] = reg_value.GetAsUInt64(); + break; + case lldb_fs_x86_64: + m_gpr_x86_64.regs[_REG_FS] = reg_value.GetAsUInt64(); + break; + case lldb_gs_x86_64: + m_gpr_x86_64.regs[_REG_GS] = reg_value.GetAsUInt64(); + break; + case lldb_ss_x86_64: + m_gpr_x86_64.regs[_REG_SS] = reg_value.GetAsUInt64(); + break; + case lldb_ds_x86_64: + m_gpr_x86_64.regs[_REG_DS] = reg_value.GetAsUInt64(); + break; + case lldb_es_x86_64: + m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64(); + break; + } + + if (WriteRegisterSet(set) != 0) + error.SetErrorStringWithFormat("failed to write register set"); + + return error; +} + +Error NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( + lldb::DataBufferSP &data_sp) { + Error error; + + data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); + if (!data_sp) { + error.SetErrorStringWithFormat( + "failed to allocate DataBufferHeap instance of size %" PRIu64, + REG_CONTEXT_SIZE); + return error; + } + + error = ReadGPR(); + if (error.Fail()) + return error; + + uint8_t *dst = data_sp->GetBytes(); + if (dst == nullptr) { + error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 + " returned a null pointer", + REG_CONTEXT_SIZE); + return error; + } + + ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); + dst += GetRegisterInfoInterface().GetGPRSize(); + + RegisterValue value((uint64_t)-1); + const RegisterInfo *reg_info = + GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax"); + if (reg_info == nullptr) + reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax"); + return error; +} + +Error NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + Error error; + + if (!data_sp) { + error.SetErrorStringWithFormat( + "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided", + __FUNCTION__); + return error; + } + + if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { + error.SetErrorStringWithFormat( + "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched " + "data size, expected %" PRIu64 ", actual %" PRIu64, + __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); + return error; + } + + uint8_t *src = data_sp->GetBytes(); + if (src == nullptr) { + error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s " + "DataBuffer::GetBytes() returned a null " + "pointer", + __FUNCTION__); + return error; + } + ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize()); + + error = WriteGPR(); + if (error.Fail()) + return error; + src += GetRegisterInfoInterface().GetGPRSize(); + + return error; +} + +#endif // defined(__x86_64__) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h new file mode 100644 index 0000000000000..f6f7d7f0976a1 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -0,0 +1,72 @@ +//===-- NativeRegisterContextNetBSD_x86_64.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#if defined(__x86_64__) + +#ifndef lldb_NativeRegisterContextNetBSD_x86_64_h +#define lldb_NativeRegisterContextNetBSD_x86_64_h + +// clang-format off +#include <sys/param.h> +#include <sys/types.h> +#include <machine/reg.h> +// clang-format on + +#include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h" +#include "Plugins/Process/Utility/RegisterContext_x86.h" +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" + +namespace lldb_private { +namespace process_netbsd { + +class NativeProcessNetBSD; + +class NativeRegisterContextNetBSD_x86_64 : public NativeRegisterContextNetBSD { +public: + NativeRegisterContextNetBSD_x86_64(const ArchSpec &target_arch, + NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx); + uint32_t GetRegisterSetCount() const override; + + const RegisterSet *GetRegisterSet(uint32_t set_index) const override; + + Error ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + Error WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + + Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + +protected: + void *GetGPRBuffer() override { return &m_gpr_x86_64; } + void *GetFPRBuffer() override { return &m_fpr_x86_64; } + +private: + // Private member types. + enum { GPRegSet, FPRegSet }; + + // Private member variables. + struct reg m_gpr_x86_64; + struct fpreg m_fpr_x86_64; + + int GetSetForNativeRegNum(int reg_num) const; + + int ReadRegisterSet(uint32_t set); + int WriteRegisterSet(uint32_t set); +}; + +} // namespace process_netbsd +} // namespace lldb_private + +#endif // #ifndef lldb_NativeRegisterContextNetBSD_x86_64_h + +#endif // defined(__x86_64__) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp new file mode 100644 index 0000000000000..f23621e45aadf --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -0,0 +1,159 @@ +//===-- NativeThreadNetBSD.cpp -------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "NativeThreadNetBSD.h" +#include "NativeRegisterContextNetBSD.h" + +#include "NativeProcessNetBSD.h" + +#include "Plugins/Process/POSIX/CrashReason.h" +#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/State.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_netbsd; + +NativeThreadNetBSD::NativeThreadNetBSD(NativeProcessNetBSD *process, + lldb::tid_t tid) + : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid), + m_stop_info(), m_reg_context_sp(), m_stop_description() {} + +void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, + const siginfo_t *info) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo); + + SetStopped(); + + m_stop_info.reason = StopReason::eStopReasonSignal; + m_stop_info.details.signal.signo = signo; + + m_stop_description.clear(); + if (info) { + switch (signo) { + case SIGSEGV: + case SIGBUS: + case SIGFPE: + case SIGILL: + const auto reason = GetCrashReason(*info); + m_stop_description = GetCrashReasonString(reason, *info); + break; + } + } +} + +void NativeThreadNetBSD::SetStoppedByBreakpoint() { + SetStopped(); + m_stop_info.reason = StopReason::eStopReasonBreakpoint; + m_stop_info.details.signal.signo = SIGTRAP; +} + +void NativeThreadNetBSD::SetStoppedByTrace() { + SetStopped(); + m_stop_info.reason = StopReason::eStopReasonTrace; + m_stop_info.details.signal.signo = SIGTRAP; +} + +void NativeThreadNetBSD::SetStoppedByExec() { + SetStopped(); + m_stop_info.reason = StopReason::eStopReasonExec; + m_stop_info.details.signal.signo = SIGTRAP; +} + +void NativeThreadNetBSD::SetStopped() { + const StateType new_state = StateType::eStateStopped; + m_state = new_state; + m_stop_description.clear(); +} + +void NativeThreadNetBSD::SetRunning() { + m_state = StateType::eStateRunning; + m_stop_info.reason = StopReason::eStopReasonNone; +} + +void NativeThreadNetBSD::SetStepping() { + m_state = StateType::eStateStepping; + m_stop_info.reason = StopReason::eStopReasonNone; +} + +std::string NativeThreadNetBSD::GetName() { return std::string(""); } + +lldb::StateType NativeThreadNetBSD::GetState() { return m_state; } + +bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info, + std::string &description) { + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); + + description.clear(); + + switch (m_state) { + case eStateStopped: + case eStateCrashed: + case eStateExited: + case eStateSuspended: + case eStateUnloaded: + stop_info = m_stop_info; + description = m_stop_description; + + return true; + + case eStateInvalid: + case eStateConnected: + case eStateAttaching: + case eStateLaunching: + case eStateRunning: + case eStateStepping: + case eStateDetached: + LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(), + StateAsCString(m_state)); + return false; + } + llvm_unreachable("unhandled StateType!"); +} + +NativeRegisterContextSP NativeThreadNetBSD::GetRegisterContext() { + // Return the register context if we already created it. + if (m_reg_context_sp) + return m_reg_context_sp; + + NativeProcessProtocolSP m_process_sp = m_process_wp.lock(); + if (!m_process_sp) + return NativeRegisterContextSP(); + + ArchSpec target_arch; + if (!m_process_sp->GetArchitecture(target_arch)) + return NativeRegisterContextSP(); + + const uint32_t concrete_frame_idx = 0; + m_reg_context_sp.reset( + NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD( + target_arch, *this, concrete_frame_idx)); + + return m_reg_context_sp; +} + +Error NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size, + uint32_t watch_flags, bool hardware) { + return Error("Unimplemented"); +} + +Error NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) { + return Error("Unimplemented"); +} + +Error NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr, + size_t size) { + return Error("Unimplemented"); +} + +Error NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) { + return Error("Unimplemented"); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h new file mode 100644 index 0000000000000..85fff5d5653f6 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h @@ -0,0 +1,73 @@ +//===-- NativeThreadNetBSD.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_NativeThreadNetBSD_H_ +#define liblldb_NativeThreadNetBSD_H_ + +#include "lldb/Host/common/NativeThreadProtocol.h" + +namespace lldb_private { +namespace process_netbsd { + +class NativeProcessNetBSD; + +class NativeThreadNetBSD : public NativeThreadProtocol { + friend class NativeProcessNetBSD; + +public: + NativeThreadNetBSD(NativeProcessNetBSD *process, lldb::tid_t tid); + + // --------------------------------------------------------------------- + // NativeThreadProtocol Interface + // --------------------------------------------------------------------- + std::string GetName() override; + + lldb::StateType GetState() override; + + bool GetStopReason(ThreadStopInfo &stop_info, + std::string &description) override; + + NativeRegisterContextSP GetRegisterContext() override; + + Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, + bool hardware) override; + + Error RemoveWatchpoint(lldb::addr_t addr) override; + + Error SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; + + Error RemoveHardwareBreakpoint(lldb::addr_t addr) override; + +private: + // --------------------------------------------------------------------- + // Interface for friend classes + // --------------------------------------------------------------------- + + void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr); + void SetStoppedByBreakpoint(); + void SetStoppedByTrace(); + void SetStoppedByExec(); + void SetStopped(); + void SetRunning(); + void SetStepping(); + + // --------------------------------------------------------------------- + // Member Variables + // --------------------------------------------------------------------- + lldb::StateType m_state; + ThreadStopInfo m_stop_info; + NativeRegisterContextSP m_reg_context_sp; + std::string m_stop_description; +}; + +typedef std::shared_ptr<NativeThreadNetBSD> NativeThreadNetBSDSP; +} // namespace process_netbsd +} // namespace lldb_private + +#endif // #ifndef liblldb_NativeThreadNetBSD_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/CrashReason.cpp index 77d6e287486c1..864418c900310 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/CrashReason.cpp @@ -62,7 +62,6 @@ CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) { return CrashReason::eBoundViolation; } - assert(false && "unexpected si_code for SIGSEGV"); return CrashReason::eInvalidCrashReason; } @@ -88,7 +87,6 @@ CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) { return CrashReason::eInternalStackError; } - assert(false && "unexpected si_code for SIGILL"); return CrashReason::eInvalidCrashReason; } @@ -114,7 +112,6 @@ CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) { return CrashReason::eFloatSubscriptRange; } - assert(false && "unexpected si_code for SIGFPE"); return CrashReason::eInvalidCrashReason; } @@ -130,7 +127,6 @@ CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) { return CrashReason::eHardwareError; } - assert(false && "unexpected si_code for SIGBUS"); return CrashReason::eInvalidCrashReason; } } @@ -158,7 +154,7 @@ std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { switch (reason) { default: - assert(false && "invalid CrashReason"); + str = "unknown crash reason"; break; case CrashReason::eInvalidAddress: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp index 9ced11c7ca2a0..f1beb0f7f7388 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp @@ -10,188 +10,23 @@ #include "ProcessPOSIXLog.h" -#include <mutex> +#include "llvm/Support/Threading.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Interpreter/Args.h" - -#include "ProcessPOSIXLog.h" - -using namespace lldb; using namespace lldb_private; -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_log_sp the first time this function is -// called. -static bool g_log_enabled = false; -static Log *g_log = NULL; -static Log *GetLog() { - if (!g_log_enabled) - return NULL; - return g_log; -} +static constexpr Log::Category g_categories[] = { + {{"break"}, {"log breakpoints"}, POSIX_LOG_BREAKPOINTS}, + {{"memory"}, {"log memory reads and writes"}, POSIX_LOG_MEMORY}, + {{"process"}, {"log process events and activities"}, POSIX_LOG_PROCESS}, + {{"ptrace"}, {"log all calls to ptrace"}, POSIX_LOG_PTRACE}, + {{"registers"}, {"log register read/writes"}, POSIX_LOG_REGISTERS}, + {{"thread"}, {"log thread events and activities"}, POSIX_LOG_THREAD}, + {{"watch"}, {"log watchpoint related activities"}, POSIX_LOG_WATCHPOINTS}, +}; -void ProcessPOSIXLog::Initialize(ConstString name) { - static std::once_flag g_once_flag; - - std::call_once(g_once_flag, [name]() { - Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories}; - - Log::RegisterLogChannel(name, log_callbacks); - RegisterPluginName(name); - }); -} +Log::Channel ProcessPOSIXLog::g_channel(g_categories, POSIX_LOG_DEFAULT); -Log *ProcessPOSIXLog::GetLogIfAllCategoriesSet(uint32_t mask) { - Log *log(GetLog()); - if (log && mask) { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return NULL; - } - return log; +void ProcessPOSIXLog::Initialize() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { Log::Register("posix", g_channel); }); } - -static uint32_t GetFlagBits(const char *arg) { - if (::strcasecmp(arg, "all") == 0) - return POSIX_LOG_ALL; - else if (::strcasecmp(arg, "async") == 0) - return POSIX_LOG_ASYNC; - else if (::strncasecmp(arg, "break", 5) == 0) - return POSIX_LOG_BREAKPOINTS; - else if (::strncasecmp(arg, "comm", 4) == 0) - return POSIX_LOG_COMM; - else if (::strcasecmp(arg, "default") == 0) - return POSIX_LOG_DEFAULT; - else if (::strcasecmp(arg, "packets") == 0) - return POSIX_LOG_PACKETS; - else if (::strcasecmp(arg, "memory") == 0) - return POSIX_LOG_MEMORY; - else if (::strcasecmp(arg, "data-short") == 0) - return POSIX_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp(arg, "data-long") == 0) - return POSIX_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp(arg, "process") == 0) - return POSIX_LOG_PROCESS; - else if (::strcasecmp(arg, "ptrace") == 0) - return POSIX_LOG_PTRACE; - else if (::strcasecmp(arg, "registers") == 0) - return POSIX_LOG_REGISTERS; - else if (::strcasecmp(arg, "step") == 0) - return POSIX_LOG_STEP; - else if (::strcasecmp(arg, "thread") == 0) - return POSIX_LOG_THREAD; - else if (::strcasecmp(arg, "verbose") == 0) - return POSIX_LOG_VERBOSE; - else if (::strncasecmp(arg, "watch", 5) == 0) - return POSIX_LOG_WATCHPOINTS; - return 0; -} - -void ProcessPOSIXLog::DisableLog(const char **args, Stream *feedback_strm) { - Log *log(GetLog()); - if (log) { - uint32_t flag_bits = 0; - - flag_bits = log->GetMask().Get(); - for (; args && args[0]; args++) { - const char *arg = args[0]; - uint32_t bits = GetFlagBits(arg); - - if (bits) { - flag_bits &= ~bits; - } else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories(feedback_strm); - } - } - - log->GetMask().Reset(flag_bits); - if (flag_bits == 0) - g_log_enabled = false; - } - - return; -} - -Log *ProcessPOSIXLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, - const char **args, Stream *feedback_strm) { - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the - // same. - uint32_t flag_bits = 0; - if (g_log) - flag_bits = g_log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) { - if (g_log) - g_log->SetStream(log_stream_sp); - else - g_log = new Log(log_stream_sp); - } - - if (g_log) { - bool got_unknown_category = false; - for (; args && args[0]; args++) { - const char *arg = args[0]; - uint32_t bits = GetFlagBits(arg); - - if (bits) { - flag_bits |= bits; - } else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) { - got_unknown_category = true; - ListLogCategories(feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = POSIX_LOG_DEFAULT; - g_log->GetMask().Reset(flag_bits); - g_log->GetOptions().Reset(log_options); - g_log_enabled = true; - } - return g_log; -} - -void ProcessPOSIXLog::ListLogCategories(Stream *strm) { - strm->Printf( - "Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short " - "transactions only\n" - " data-long - log memory bytes for memory reads and writes for all " - "transactions\n" - " process - log process events and activities\n" -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION - " ptrace - log all calls to ptrace\n" -#endif - " registers - log register read/writes\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", - ProcessPOSIXLog::m_pluginname); -} - -void ProcessPOSIXLog::LogIf(uint32_t mask, const char *format, ...) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(mask)); - if (log) { - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} - -int ProcessPOSIXLog::m_nestinglevel; -const char *ProcessPOSIXLog::m_pluginname = ""; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index 7d187da4e4889..134013517a110 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -16,87 +16,29 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/Log.h" +#include "lldb/Utility/Log.h" -#define POSIX_LOG_VERBOSE (1u << 0) #define POSIX_LOG_PROCESS (1u << 1) #define POSIX_LOG_THREAD (1u << 2) -#define POSIX_LOG_PACKETS (1u << 3) #define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define POSIX_LOG_MEMORY_DATA_SHORT \ - (1u << 5) // Log short memory reads/writes bytes -#define POSIX_LOG_MEMORY_DATA_LONG \ - (1u << 6) // Log all memory reads/writes bytes +#define POSIX_LOG_PTRACE (1u << 5) +#define POSIX_LOG_REGISTERS (1u << 6) #define POSIX_LOG_BREAKPOINTS (1u << 7) #define POSIX_LOG_WATCHPOINTS (1u << 8) -#define POSIX_LOG_STEP (1u << 9) -#define POSIX_LOG_COMM (1u << 10) -#define POSIX_LOG_ASYNC (1u << 11) -#define POSIX_LOG_PTRACE (1u << 12) -#define POSIX_LOG_REGISTERS (1u << 13) #define POSIX_LOG_ALL (UINT32_MAX) -#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS - -// The size which determines "short memory reads/writes". -#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t)) +#define POSIX_LOG_DEFAULT POSIX_LOG_PROCESS +namespace lldb_private { class ProcessPOSIXLog { - static int m_nestinglevel; - static const char *m_pluginname; + static Log::Channel g_channel; public: - // --------------------------------------------------------------------- - // Public Static Methods - // --------------------------------------------------------------------- - static void Initialize(lldb_private::ConstString name); - - static void RegisterPluginName(const char *pluginName) { - m_pluginname = pluginName; - } - - static void RegisterPluginName(lldb_private::ConstString pluginName) { - m_pluginname = pluginName.GetCString(); - } - - static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static void DisableLog(const char **args, - lldb_private::Stream *feedback_strm); - - static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp, - uint32_t log_options, const char **args, - lldb_private::Stream *feedback_strm); - - static void ListLogCategories(lldb_private::Stream *strm); - - static void LogIf(uint32_t mask, const char *format, ...); - - // The following functions can be used to enable the client to limit - // logging to only the top level function calls. This is useful for - // recursive functions. FIXME: not thread safe! - // Example: - // void NestingFunc() { - // LogSP log - // (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL)); - // if (log) - // { - // ProcessPOSIXLog::IncNestLevel(); - // if (ProcessPOSIXLog::AtTopNestLevel()) - // log->Print(msg); - // } - // NestingFunc(); - // if (log) - // ProcessPOSIXLog::DecNestLevel(); - // } - - static bool AtTopNestLevel() { return m_nestinglevel == 1; } - - static void IncNestLevel() { ++m_nestinglevel; } + static void Initialize(); - static void DecNestLevel() { - --m_nestinglevel; - assert(m_nestinglevel >= 0); + static Log *GetLogIfAllCategoriesSet(uint32_t mask) { + return g_channel.GetLogIfAll(mask); } }; +} #endif // liblldb_ProcessPOSIXLog_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 75f7251fb1088..5e933d3b3dee9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -14,11 +14,11 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StructuredData.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/StringConvert.h" +#include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StringExtractor.h" using namespace lldb; @@ -281,6 +281,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, // Swap "dwarf_opcode_string" over into "opcode_extractor" opcode_extractor.GetStringRef().swap(dwarf_opcode_string); uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); + UNUSED_IF_ASSERT_DISABLED(ret_val); assert(ret_val == reg_info.dynamic_size_dwarf_len); for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index e5c22fe484e9f..a30bfa1e1f16c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -17,8 +17,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/ConstString.h" #include "lldb/Core/StructuredData.h" +#include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" class DynamicRegisterInfo { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index d27a7b0da9439..4983dcdb51428 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -13,9 +13,9 @@ #include "Plugins/Process/Utility/HistoryUnwind.h" #include "Plugins/Process/Utility/RegisterContextHistory.h" -#include "lldb/Core/Log.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h index 1a4898a95b7dc..363ba26696377 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -18,11 +18,11 @@ // Project includes #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" -#include "lldb/Core/UserID.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrameList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp new file mode 100644 index 0000000000000..0b18143624255 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -0,0 +1,43 @@ +//===-- NativeRegisterContextRegisterInfo.cpp -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "NativeRegisterContextRegisterInfo.h" +#include "lldb/lldb-private-forward.h" +#include "lldb/lldb-types.h" + +using namespace lldb_private; + +NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo( + NativeThreadProtocol &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info_interface) + : NativeRegisterContext(thread, concrete_frame_idx), + m_register_info_interface_up(register_info_interface) { + assert(register_info_interface && "null register_info_interface"); +} + +uint32_t NativeRegisterContextRegisterInfo::GetRegisterCount() const { + return m_register_info_interface_up->GetRegisterCount(); +} + +uint32_t NativeRegisterContextRegisterInfo::GetUserRegisterCount() const { + return m_register_info_interface_up->GetUserRegisterCount(); +} + +const RegisterInfo *NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex( + uint32_t reg_index) const { + if (reg_index <= GetRegisterCount()) + return m_register_info_interface_up->GetRegisterInfo() + reg_index; + else + return nullptr; +} + +const RegisterInfoInterface & +NativeRegisterContextRegisterInfo::GetRegisterInfoInterface() const { + return *m_register_info_interface_up; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h new file mode 100644 index 0000000000000..c1b597462b60a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -0,0 +1,41 @@ +//===-- NativeRegisterContextRegisterInfo.h ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO +#define LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO + +#include <memory> + +#include "RegisterInfoInterface.h" +#include "lldb/Host/common/NativeRegisterContext.h" + +namespace lldb_private { +class NativeRegisterContextRegisterInfo : public NativeRegisterContext { +public: + /// + /// Construct a NativeRegisterContextRegisterInfo, taking ownership + /// of the register_info_interface pointer. + /// + NativeRegisterContextRegisterInfo( + NativeThreadProtocol &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info_interface); + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; + + const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg_index) const override; + + const RegisterInfoInterface &GetRegisterInfoInterface() const; + +private: + std::unique_ptr<RegisterInfoInterface> m_register_info_interface_up; +}; +} +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp index 9b9db51e51679..7ed7189d80489 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -24,7 +24,35 @@ void NetBSDSignals::Reset() { // =================================================== AddSignal(32, "SIGPWR", false, true, true, "power fail/restart (not reset when caught)"); -#ifdef SIGRTMIN /* SIGRTMAX */ - /* Kernel only; not exposed to userland yet */ -#endif + AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); + AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 52ace5602f490..64a697ff53c89 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -17,12 +17,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" #include "llvm/Support/Compiler.h" #include "Plugins/Process/Utility/InstructionUtils.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 64983a2404e60..0c36f1a8346cd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -19,14 +19,14 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index f42fb00b375f0..c818fad9ac0e5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -12,12 +12,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 7c0bafa68f9e1..50e7292f86b1c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -14,12 +14,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index 93bb09b810ac6..dd6ca92a74ee2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -10,8 +10,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" @@ -28,6 +26,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" #include "lldb/lldb-private.h" #include "RegisterContextDummy.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp deleted file mode 100644 index fecfae0b7e662..0000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp +++ /dev/null @@ -1,97 +0,0 @@ -//===-- RegisterContextFreeBSD_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 <cassert> -#include <stddef.h> -#include <vector> - -#include "lldb/lldb-defines.h" -#include "llvm/Support/Compiler.h" - -#include "RegisterContextFreeBSD_arm.h" - -using namespace lldb; -using namespace lldb_private; - -// Based on RegisterContextLinux_arm.cpp and -// http://svnweb.freebsd.org/base/head/sys/arm/include/reg.h -#define GPR_OFFSET(idx) ((idx)*4) -#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR)) -#define FPSCR_OFFSET \ - (LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::FPU, fpscr) + \ - sizeof(RegisterContextFreeBSD_arm::GPR)) -#define EXC_OFFSET(idx) \ - ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR) + \ - sizeof(RegisterContextFreeBSD_arm::FPU)) -#define DBG_OFFSET(reg) \ - ((LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::DBG, reg) + \ - sizeof(RegisterContextFreeBSD_arm::GPR) + \ - sizeof(RegisterContextFreeBSD_arm::FPU) + \ - sizeof(RegisterContextFreeBSD_arm::EXC))) - -#define DEFINE_DBG(reg, i) \ - #reg, NULL, sizeof(((RegisterContextFreeBSD_arm::DBG *) NULL)->reg[i]), \ - DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \ - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - dbg_##reg##i }, \ - NULL, NULL, NULL, 0 -#define REG_CONTEXT_SIZE \ - (sizeof(RegisterContextFreeBSD_arm::GPR) + \ - sizeof(RegisterContextFreeBSD_arm::FPU) + \ - sizeof(RegisterContextFreeBSD_arm::EXC)) - -//----------------------------------------------------------------------------- -// Include RegisterInfos_arm to declare our g_register_infos_arm structure. -//----------------------------------------------------------------------------- -#define DECLARE_REGISTER_INFOS_ARM_STRUCT -#include "RegisterInfos_arm.h" -#undef DECLARE_REGISTER_INFOS_ARM_STRUCT - -static const lldb_private::RegisterInfo * -GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { - switch (target_arch.GetMachine()) { - case llvm::Triple::arm: - return g_register_infos_arm; - default: - assert(false && "Unhandled target architecture."); - return NULL; - } -} - -static uint32_t -GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { - switch (target_arch.GetMachine()) { - case llvm::Triple::arm: - return static_cast<uint32_t>(sizeof(g_register_infos_arm) / - sizeof(g_register_infos_arm[0])); - default: - assert(false && "Unhandled target architecture."); - return 0; - } -} - -RegisterContextFreeBSD_arm::RegisterContextFreeBSD_arm( - const lldb_private::ArchSpec &target_arch) - : lldb_private::RegisterInfoInterface(target_arch), - m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)) {} - -size_t RegisterContextFreeBSD_arm::GetGPRSize() const { - return sizeof(struct RegisterContextFreeBSD_arm::GPR); -} - -const lldb_private::RegisterInfo * -RegisterContextFreeBSD_arm::GetRegisterInfo() const { - return m_register_info_p; -} - -uint32_t RegisterContextFreeBSD_arm::GetRegisterCount() const { - return m_register_info_count; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp index c114cfb829f50..55a72b2a31b4f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp @@ -9,11 +9,33 @@ #include "RegisterContextFreeBSD_mips64.h" #include "RegisterContextPOSIX_mips64.h" +#include "lldb-mips-freebsd-register-enums.h" #include <vector> using namespace lldb_private; using namespace lldb; +static const uint32_t g_gpr_regnums[] = { + gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64, + gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64, + gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, + gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64, + gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64, + gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, + gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64, + gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64, + gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, + gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64}; + +// Number of register sets provided by this context. +constexpr size_t k_num_register_sets = 1; + +static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, + g_gpr_regnums}, +}; + + // http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h typedef struct _GPR { uint64_t zero; @@ -74,6 +96,19 @@ size_t RegisterContextFreeBSD_mips64::GetGPRSize() const { return sizeof(GPR_freebsd_mips); } +const RegisterSet * +RegisterContextFreeBSD_mips64::GetRegisterSet(size_t set) const { + // Check if RegisterSet is available + if (set < k_num_register_sets) + return &g_reg_sets_mips64[set]; + return nullptr; +} + +size_t +RegisterContextFreeBSD_mips64::GetRegisterSetCount() const { + return k_num_register_sets; +} + const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const { assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64); return g_register_infos_mips64; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h index 043e638758da0..5e5de71ad72e8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h @@ -19,6 +19,10 @@ public: size_t GetGPRSize() const override; + const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; + + size_t GetRegisterSetCount() const; + const lldb_private::RegisterInfo *GetRegisterInfo() const override; uint32_t GetRegisterCount() const override; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index 0fc47fcd8e3af..cc0d696b338a5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -10,8 +10,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" @@ -28,6 +26,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" #include "lldb/lldb-private.h" #include "RegisterContextHistory.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index ba84c40e9767a..485a39e6c9a56 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -9,8 +9,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" @@ -31,6 +29,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" #include "lldb/lldb-private.h" #include "RegisterContextLLDB.h" @@ -2015,7 +2015,18 @@ bool RegisterContextLLDB::GetStartPC(addr_t &start_pc) { return false; if (!m_start_pc.IsValid()) { - return ReadPC(start_pc); + bool read_successfully = ReadPC (start_pc); + if (read_successfully) + { + ProcessSP process_sp (m_thread.GetProcess()); + if (process_sp) + { + ABI *abi = process_sp->GetABI().get(); + if (abi) + start_pc = abi->FixCodeAddress(start_pc); + } + } + return read_successfully; } start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get()); return true; @@ -2044,9 +2055,16 @@ bool RegisterContextLLDB::ReadPC(addr_t &pc) { if (m_all_registers_available == false && above_trap_handler == false && (pc == 0 || pc == 1)) { return false; - } else { - return true; } + + ProcessSP process_sp (m_thread.GetProcess()); + if (process_sp) + { + ABI *abi = process_sp->GetABI().get(); + if (abi) + pc = abi->FixCodeAddress(pc); + } + return true; } else { return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index cb22eedd560a3..7e9e77dcf06d9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -21,7 +21,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Utility/RegisterNumber.h" +#include "lldb/Target/RegisterNumber.h" #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_arm.h deleted file mode 100644 index 9065bc0e08d2f..0000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_arm.h +++ /dev/null @@ -1,62 +0,0 @@ -//===-- RegisterContextLinux_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_RegisterContextLinux_arm_h_ -#define liblldb_RegisterContextLinux_arm_h_ - -#include "RegisterInfoInterface.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/lldb-private.h" - -class RegisterContextLinux_arm : public lldb_private::RegisterInfoInterface { -public: - struct GPR { - uint32_t r[16]; // R0-R15 - uint32_t cpsr; // CPSR - }; - - struct QReg { - uint8_t bytes[16]; - }; - - struct FPU { - union { - uint32_t s[32]; - uint64_t d[32]; - QReg q[16]; // the 128-bit NEON registers - } floats; - uint32_t fpscr; - }; - struct EXC { - uint32_t exception; - uint32_t fsr; /* Fault status */ - uint32_t far; /* Virtual Fault Address */ - }; - - struct DBG { - uint32_t bvr[16]; - uint32_t bcr[16]; - uint32_t wvr[16]; - uint32_t wcr[16]; - }; - - RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch); - - size_t GetGPRSize() const override; - - const lldb_private::RegisterInfo *GetRegisterInfo() const override; - - uint32_t GetRegisterCount() const override; - -private: - const lldb_private::RegisterInfo *m_register_info_p; - uint32_t m_register_info_count; -}; - -#endif // liblldb_RegisterContextLinux_arm_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp index 982eefea9ba6e..7b16531dcc894 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp @@ -29,6 +29,73 @@ using namespace lldb; #include "RegisterInfos_mips.h" #undef DECLARE_REGISTER_INFOS_MIPS_STRUCT +// mips general purpose registers. +const uint32_t g_gp_regnums_mips[] = { + gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips, + gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips, + gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips, + gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips, + gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips, + gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips, + gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips, + gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips, + gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips, + gpr_cause_mips, gpr_pc_mips, gpr_config5_mips, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 == + k_num_gpr_registers_mips, + "g_gp_regnums_mips has wrong number of register infos"); +// mips floating point registers. +const uint32_t g_fp_regnums_mips[] = { + fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips, + fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips, + fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips, + fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips, + fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips, + fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips, + fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips, + fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips, + fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 == + k_num_fpr_registers_mips, + "g_fp_regnums_mips has wrong number of register infos"); + +// mips MSA registers. +const uint32_t g_msa_regnums_mips[] = { + msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips, + msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips, + msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips, + msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips, + msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips, + msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips, + msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips, + msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips, + msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips, + msa_config5_mips, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) - + 1 == + k_num_msa_registers_mips, + "g_msa_regnums_mips has wrong number of register infos"); + +// Number of register sets provided by this context. +constexpr size_t k_num_register_sets = 3; + +// Register sets for mips. +static const RegisterSet g_reg_sets_mips[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_mips, + g_gp_regnums_mips}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_mips, + g_fp_regnums_mips}, + {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}}; + uint32_t GetUserRegisterInfoCount(bool msa_present) { if (msa_present) return static_cast<uint32_t>(k_num_user_registers_mips); @@ -56,6 +123,25 @@ const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const { } } +const RegisterSet * +RegisterContextLinux_mips::GetRegisterSet(size_t set) const { + if (set >= k_num_register_sets) + return nullptr; + switch (m_target_arch.GetMachine()) { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + return &g_reg_sets_mips[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +size_t +RegisterContextLinux_mips::GetRegisterSetCount() const { + return k_num_register_sets; +} + uint32_t RegisterContextLinux_mips::GetRegisterCount() const { return static_cast<uint32_t>(sizeof(g_register_infos_mips) / sizeof(g_register_infos_mips[0])); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h index cba4ee6cd2b00..a16c4ecd15f86 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h @@ -22,6 +22,10 @@ public: const lldb_private::RegisterInfo *GetRegisterInfo() const override; + const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; + + size_t GetRegisterSetCount() const; + uint32_t GetRegisterCount() const override; uint32_t GetUserRegisterCount() const override; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp index c40f69492624c..1bb16c701126c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp @@ -7,7 +7,6 @@ // //===---------------------------------------------------------------------===// -#if defined(__mips__) #include <stddef.h> #include <vector> @@ -41,6 +40,101 @@ using namespace lldb_private; #include "RegisterInfos_mips.h" #undef DECLARE_REGISTER_INFOS_MIPS_STRUCT +// mips64 general purpose registers. +const uint32_t g_gp_regnums_mips64[] = { + gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, + gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64, + gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64, + gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, + gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, + gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64, + gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64, + gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, + gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, + gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64, + gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64, + gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, + gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - + 1 == + k_num_gpr_registers_mips64, + "g_gp_regnums_mips64 has wrong number of register infos"); + +// mips64 floating point registers. +const uint32_t g_fp_regnums_mips64[] = { + fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64, + fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64, + fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64, + fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64, + fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64, + fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64, + fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64, + fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64, + fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - + 1 == + k_num_fpr_registers_mips64, + "g_fp_regnums_mips64 has wrong number of register infos"); + +// mips64 MSA registers. +const uint32_t g_msa_regnums_mips64[] = { + msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64, + msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64, + msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64, + msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64, + msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64, + msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64, + msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64, + msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64, + msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64, + msa_config5_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) - + 1 == + k_num_msa_registers_mips64, + "g_msa_regnums_mips64 has wrong number of register infos"); + +// Number of register sets provided by this context. +constexpr size_t k_num_register_sets = 3; + +// Register sets for mips64. +static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, + g_gp_regnums_mips64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64, + g_fp_regnums_mips64}, + {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64}, +}; + +const RegisterSet * +RegisterContextLinux_mips64::GetRegisterSet(size_t set) const { + if (set >= k_num_register_sets) + return nullptr; + + switch (m_target_arch.GetMachine()) { + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return &g_reg_sets_mips64[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + return nullptr; +} + +size_t +RegisterContextLinux_mips64::GetRegisterSetCount() const { + return k_num_register_sets; +} + static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) { switch (target_arch.GetMachine()) { case llvm::Triple::mips64: @@ -116,4 +210,3 @@ uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const { return m_user_register_count; } -#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h index 9669b0d849971..d3ca9d75300e2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -#if defined(__mips__) - #ifndef liblldb_RegisterContextLinux_mips64_H_ #define liblldb_RegisterContextLinux_mips64_H_ @@ -24,6 +22,10 @@ public: const lldb_private::RegisterInfo *GetRegisterInfo() const override; + const lldb_private::RegisterSet *GetRegisterSet(size_t set) const; + + size_t GetRegisterSetCount() const; + uint32_t GetRegisterCount() const override; uint32_t GetUserRegisterCount() const override; @@ -36,4 +38,3 @@ private: #endif -#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 95b106d68bb3c..2d24bdaed2cd0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -12,12 +12,12 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Core/StreamString.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/StreamString.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 57966e1729a6b..eed5eec8fae80 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -14,11 +14,11 @@ // Other libraries and framework includes // Project includes #include "DynamicRegisterInfo.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Error.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Error.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index 55de0412b094d..cad1592af5ba1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -16,8 +16,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/DataExtractor.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-private.h" class DynamicRegisterInfo; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp index 4f64a8c4f3219..ca7a0139ccc03 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp @@ -47,10 +47,14 @@ typedef struct _GPR { uint64_t ss; /* 25 */ } GPR; -/* - * As of NetBSD-7.99.25 there is no support for debug registers - * https://en.wikipedia.org/wiki/X86_debug_register - */ +struct DBG { + uint64_t dr[16]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ + /* Index 8-15: reserved */ +}; /* * src/sys/arch/amd64/include/mcontext.h @@ -66,276 +70,21 @@ struct UserArea { GPR gpr; uint64_t mc_tlsbase; FPR fpr; + DBG dbg; }; -//--------------------------------------------------------------------------- -// Cherry-pick parts of RegisterInfos_x86_64.h, without debug registers -//--------------------------------------------------------------------------- -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) - -// Computes the offset of the given FPR in the extended data area. -#define FPR_OFFSET(regname) \ - (LLVM_EXTENSION offsetof(UserArea, fpr) + \ - LLVM_EXTENSION offsetof(FPR, xstate) + \ - LLVM_EXTENSION offsetof(FXSAVE, regname)) - -// Computes the offset of the YMM register assembled from register halves. -// Based on DNBArchImplX86_64.cpp from debugserver -#define YMM_OFFSET(reg_index) \ - (LLVM_EXTENSION offsetof(UserArea, fpr) + \ - LLVM_EXTENSION offsetof(FPR, xstate) + \ - LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) - -// Number of bytes needed to represent a FPR. -#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) - -// Number of bytes needed to represent the i'th FP register. -#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) - -// Number of bytes needed to represent an XMM register. -#define XMM_SIZE sizeof(XMMReg) - -// Number of bytes needed to represent a YMM register. -#define YMM_SIZE sizeof(YMMReg) - -// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB - -// Note that the size and offset will be updated by platform-specific classes. -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { \ - #reg, alt, sizeof(((GPR *)nullptr)->reg), \ - GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, kind4, \ - lldb_##reg##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ - { \ - #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ - {kind1, kind2, kind3, kind4, \ - lldb_##name##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEFINE_FP_ST(reg, i) \ - { \ - #reg #i, nullptr, FP_SIZE, \ - LLVM_EXTENSION FPR_OFFSET( \ - stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEFINE_FP_MM(reg, i) \ - { \ - #reg #i, nullptr, sizeof(uint64_t), \ - LLVM_EXTENSION FPR_OFFSET( \ - stmm[i]), eEncodingUint, eFormatHex, \ - {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_mm##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEFINE_XMM(reg, i) \ - { \ - #reg #i, nullptr, XMM_SIZE, \ - LLVM_EXTENSION FPR_OFFSET( \ - reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEFINE_YMM(reg, i) \ - { \ - #reg #i, nullptr, YMM_SIZE, \ - LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ - {dwarf_##reg##i##h_x86_64, \ - dwarf_##reg##i##h_x86_64, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ - } +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, dbg) + \ + LLVM_EXTENSION offsetof(DBG, dr[reg_index])) -#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ - { \ - #reg32, nullptr, 4, \ - GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg32##_x86_64 }, \ - RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ - } - -#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ - { \ - #reg16, nullptr, 2, \ - GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg16##_x86_64 }, \ - RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ - } - -#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ - { \ - #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \ - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg8##_x86_64 }, \ - RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64,\ - nullptr, 0 \ - } - -#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ - { \ - #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - lldb_##reg8##_x86_64 }, \ - RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64,\ - nullptr, 0 \ - } - -static RegisterInfo g_register_infos_x86_64[] = { - // General purpose registers. EH_Frame, DWARF, - // Generic, Process Plugin - DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, - LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, - LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, - LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, - LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), - DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, - LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, - LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), - DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, - LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), - DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, - LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), - DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, - LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), - DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, - LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), - DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - - DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx), - DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx), - DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi), - DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp), - DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9), - DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11), - DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13), - DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15), - DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx), - DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx), - DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi), - DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp), - DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9), - DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11), - DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13), - DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15), - DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx), - DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx), - DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx), - DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx), - DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi), - DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp), - DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9), - DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11), - DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13), - DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15), - - // i387 Floating point registers. EH_frame, - // DWARF, Generic, Process Plugin - DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - - // FP registers. - DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), - DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), - DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0), - DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3), - DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6), - DEFINE_FP_MM(mm, 7), - - // XMM registers - DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), - DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), - DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8), - DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11), - DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14), - DEFINE_XMM(xmm, 15), - - // Copy of YMM registers assembled from xmm and ymmh - DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), - DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), - DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8), - DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11), - DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), - DEFINE_YMM(ymm, 15), -}; //--------------------------------------------------------------------------- -// End of cherry-pick of RegisterInfos_x86_64.h +// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 +// structure. //--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT static const RegisterInfo * PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp new file mode 100644 index 0000000000000..1f958105b10bf --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp @@ -0,0 +1,80 @@ +//===-- RegisterContextOpenBSD_i386.cpp ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextOpenBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// /usr/include/machine/reg.h +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct dbreg { + uint32_t dr[8]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ +}; + +using FPR_i386 = FXSAVE; + +struct UserArea { + GPR gpr; + FPR_i386 i387; +}; + +#define DR_SIZE sizeof(uint32_t) +#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index])) + +//--------------------------------------------------------------------------- +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +//--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextOpenBSD_i386::RegisterContextOpenBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextOpenBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextOpenBSD_i386::GetRegisterInfo() const { + switch (m_target_arch.GetMachine()) { + case llvm::Triple::x86: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return NULL; + } +} + +uint32_t RegisterContextOpenBSD_i386::GetRegisterCount() const { + return static_cast<uint32_t>(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h new file mode 100644 index 0000000000000..d3c13008bece7 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h @@ -0,0 +1,26 @@ +//===-- RegisterContextOpenBSD_i386.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_RegisterContextOpenBSD_i386_H_ +#define liblldb_RegisterContextOpenBSD_i386_H_ + +#include "RegisterInfoInterface.h" + +class RegisterContextOpenBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextOpenBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp new file mode 100644 index 0000000000000..e7ff0732ffecb --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp @@ -0,0 +1,107 @@ +//===-- RegisterContextOpenBSD_x86_64.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextOpenBSD_x86_64.h" +#include "RegisterContextPOSIX_x86.h" +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +// /usr/include/machine/reg.h +typedef struct _GPR { + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rbp; + uint64_t rbx; + uint64_t rax; + uint64_t rsp; + uint64_t rip; + uint64_t rflags; + uint64_t cs; + uint64_t ss; + uint64_t ds; + uint64_t es; + uint64_t fs; + uint64_t gs; +} GPR; + +struct DBG { + uint64_t dr[16]; /* debug registers */ + /* Index 0-3: debug address registers */ + /* Index 4-5: reserved */ + /* Index 6: debug status */ + /* Index 7: debug control */ + /* Index 8-15: reserved */ +}; + +struct UserArea { + GPR gpr; + FPR fpr; + DBG dbg; +}; + +#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index])) + +//--------------------------------------------------------------------------- +// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 +// structure. +//--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_X86_64_STRUCT +#include "RegisterInfos_x86_64.h" +#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +static const RegisterInfo * +PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86_64: + return g_register_infos_x86_64; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86_64: + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / + sizeof(g_register_infos_x86_64[0])); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextOpenBSD_x86_64::RegisterContextOpenBSD_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), + m_register_count(PrivateGetRegisterCount(target_arch)) {} + +size_t RegisterContextOpenBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextOpenBSD_x86_64::GetRegisterInfo() const { + return m_register_info_p; +} + +uint32_t RegisterContextOpenBSD_x86_64::GetRegisterCount() const { + return m_register_count; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h new file mode 100644 index 0000000000000..aa2b7733f3895 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h @@ -0,0 +1,31 @@ +//===-- RegisterContextOpenBSD_x86_64.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_RegisterContextOpenBSD_x86_64_H_ +#define liblldb_RegisterContextOpenBSD_x86_64_H_ + +#include "RegisterInfoInterface.h" + +class RegisterContextOpenBSD_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextOpenBSD_x86_64(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + const uint32_t m_register_count; +}; + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 15d155e315faa..bb3509330eece 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -11,13 +11,13 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/Support/Compiler.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h index 817649e7c498b..8c5fe9d2c2de4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -16,8 +16,8 @@ // Project includes #include "RegisterInfoInterface.h" #include "lldb-arm-register-enums.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" class ProcessMonitor; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 17c9dc301b50b..89384c8f5190b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -11,13 +11,13 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/Support/Compiler.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index 923e786dd045c..27251da2a9af0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -16,8 +16,8 @@ // Project includes #include "RegisterInfoInterface.h" #include "lldb-arm64-register-enums.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" class ProcessMonitor; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index 8c67fb89d08ea..207c69313282b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -11,47 +11,33 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/Support/Compiler.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" #include "RegisterContextPOSIX_mips64.h" +#include "RegisterContextFreeBSD_mips64.h" +#include "RegisterContextLinux_mips64.h" +#include "RegisterContextLinux_mips.h" using namespace lldb_private; using namespace lldb; -static const uint32_t g_gpr_regnums[] = { - gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64, - gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64, - gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, - gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64, - gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64, - gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, - gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64, - gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64, - gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, - gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64}; - -// Number of register sets provided by this context. -enum { k_num_register_sets = 1 }; - -static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, - g_gpr_regnums}, -}; - bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) { - return reg <= k_num_gpr_registers_mips64; // GPR's come first. + return reg < m_registers_count[gpr_registers_count]; // GPR's come first. } bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) { - // XXX + int set = GetRegisterSetCount(); + if (set > 1) + return reg < (m_registers_count[fpr_registers_count] + + m_registers_count[gpr_registers_count]); return false; } @@ -60,6 +46,18 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64( RegisterInfoInterface *register_info) : RegisterContext(thread, concrete_frame_idx) { m_register_info_ap.reset(register_info); + m_num_registers = GetRegisterCount(); + int set = GetRegisterSetCount(); + + const RegisterSet *reg_set_ptr; + for(int i = 0; i < set; ++i) { + reg_set_ptr = GetRegisterSet(i); + m_registers_count[i] = reg_set_ptr->num_registers; + } + + assert(m_num_registers == m_registers_count[gpr_registers_count] + + m_registers_count[fpr_registers_count] + + m_registers_count[msa_registers_count]); // elf-core yet to support ReadFPR() ProcessSP base = CalculateProcess(); @@ -74,18 +72,17 @@ void RegisterContextPOSIX_mips64::Invalidate() {} void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) { - assert(reg < k_num_registers_mips64 && "Invalid register number."); + assert(reg < m_num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_offset; } unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) { - assert(reg < k_num_registers_mips64 && "Invalid register number."); + assert(reg < m_num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_size; } size_t RegisterContextPOSIX_mips64::GetRegisterCount() { - size_t num_registers = k_num_registers_mips64; - return num_registers; + return m_register_info_ap->GetRegisterCount(); } size_t RegisterContextPOSIX_mips64::GetGPRSize() { @@ -101,31 +98,59 @@ const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() { const RegisterInfo * RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) { - if (reg < k_num_registers_mips64) + if (reg < m_num_registers) return &GetRegisterInfo()[reg]; else return NULL; } size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() { - size_t sets = 0; - for (size_t set = 0; set < k_num_register_sets; ++set) { - if (IsRegisterSetAvailable(set)) - ++sets; + ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); + switch (target_arch.GetTriple().getOS()) { + case llvm::Triple::Linux: { + if ((target_arch.GetMachine() == llvm::Triple::mipsel) || + (target_arch.GetMachine() == llvm::Triple::mips)) { + const auto *context = static_cast<const RegisterContextLinux_mips *> + (m_register_info_ap.get()); + return context->GetRegisterSetCount(); + } + const auto *context = static_cast<const RegisterContextLinux_mips64 *> + (m_register_info_ap.get()); + return context->GetRegisterSetCount(); + } + default: { + const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> + (m_register_info_ap.get()); + return context->GetRegisterSetCount(); + } + } - - return sets; } const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) { - if (IsRegisterSetAvailable(set)) - return &g_reg_sets_mips64[set]; - else - return NULL; + ArchSpec target_arch = m_register_info_ap->GetTargetArchitecture(); + switch (target_arch.GetTriple().getOS()) { + case llvm::Triple::Linux: { + if ((target_arch.GetMachine() == llvm::Triple::mipsel) || + (target_arch.GetMachine() == llvm::Triple::mips)) { + const auto *context = static_cast<const RegisterContextLinux_mips *> + (m_register_info_ap.get()); + return context->GetRegisterSet(set); + } + const auto *context = static_cast<const RegisterContextLinux_mips64 *> + (m_register_info_ap.get()); + return context->GetRegisterSet(set); + } + default: { + const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *> + (m_register_info_ap.get()); + return context->GetRegisterSet(set); + } + } } const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { - assert(reg < k_num_registers_mips64 && "Invalid register offset."); + assert(reg < m_num_registers && "Invalid register offset."); return GetRegisterInfo()[reg].name; } @@ -141,7 +166,7 @@ lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() { } bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { - size_t num_sets = k_num_register_sets; + size_t num_sets = GetRegisterSetCount(); return (set_index < num_sets); } @@ -150,7 +175,7 @@ bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { // object file sections that contain register numbers in them. uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber( lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); + const uint32_t num_regs = m_num_registers; assert(kind < kNumRegisterKinds); for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h index 90ff9d659491c..1695ec9a0bab9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -16,9 +16,8 @@ // Project includes #include "RegisterContext_mips.h" #include "RegisterInfoInterface.h" -#include "lldb-mips-freebsd-register-enums.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" using namespace lldb_private; @@ -26,6 +25,14 @@ class ProcessMonitor; class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext { public: + + enum Register_count{ + gpr_registers_count = 0, + fpr_registers_count, + msa_registers_count, + register_set_count + }; + RegisterContextPOSIX_mips64( lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info); @@ -56,8 +63,8 @@ public: uint32_t num) override; protected: - uint64_t - m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers. + uint32_t m_num_registers; + uint8_t m_registers_count[register_set_count]; std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index 6a9838a6fd0c0..c2b73e2261658 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -12,13 +12,13 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/Support/Compiler.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h index 79bb01f6740cb..50f234680ca0a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -16,8 +16,8 @@ // Project includes #include "RegisterContext_powerpc.h" #include "RegisterInfoInterface.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" class ProcessMonitor; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index e4dbe333a22d9..b3365ee2f098e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.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 "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_s390x.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h index 1ffc45c2d4b16..d5337630c32dd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -17,8 +17,8 @@ #include "RegisterContext_s390x.h" #include "RegisterInfoInterface.h" #include "lldb-s390x-register-enums.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" class ProcessMonitor; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 99525b6c2df2a..5e1bf35356b8f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -11,14 +11,14 @@ #include <errno.h> #include <stdint.h> -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" -#include "lldb/Target/Process.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_x86.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index c5afe089e4765..aa689273f2189 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -17,8 +17,8 @@ #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" #include "lldb-x86-register-enums.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" class ProcessMonitor; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index 2b5cb00fa96af..7d990e73b5bee 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Error.h" #include "lldb/Target/OperatingSystem.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Error.h" #include "lldb/lldb-private.h" #include "RegisterContextThreadMemory.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h index 12db366d7a57e..74d5d6e502085 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -13,6 +13,7 @@ #include <vector> #include "lldb/Core/ArchSpec.h" +#include "lldb/lldb-private-types.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index afa105f25404a..0111b842509ba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_arm.cpp ---------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm.cpp ------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,37 +14,35 @@ #include "lldb/lldb-defines.h" #include "llvm/Support/Compiler.h" -#include "RegisterContextLinux_arm.h" +#include "RegisterInfoPOSIX_arm.h" using namespace lldb; using namespace lldb_private; // Based on RegisterContextDarwin_arm.cpp #define GPR_OFFSET(idx) ((idx)*4) -#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR)) +#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR)) #define FPSCR_OFFSET \ - (LLVM_EXTENSION offsetof(RegisterContextLinux_arm::FPU, fpscr) + \ - sizeof(RegisterContextLinux_arm::GPR)) + (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::FPU, fpscr) + \ + sizeof(RegisterInfoPOSIX_arm::GPR)) #define EXC_OFFSET(idx) \ - ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR) + \ - sizeof(RegisterContextLinux_arm::FPU)) + ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR) + \ + sizeof(RegisterInfoPOSIX_arm::FPU)) #define DBG_OFFSET(reg) \ - ((LLVM_EXTENSION offsetof(RegisterContextLinux_arm::DBG, reg) + \ - sizeof(RegisterContextLinux_arm::GPR) + \ - sizeof(RegisterContextLinux_arm::FPU) + \ - sizeof(RegisterContextLinux_arm::EXC))) + ((LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::DBG, reg) + \ + sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ + sizeof(RegisterInfoPOSIX_arm::EXC))) #define DEFINE_DBG(reg, i) \ - #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *) NULL)->reg[i]), \ + #reg, NULL, sizeof(((RegisterInfoPOSIX_arm::DBG *) NULL)->reg[i]), \ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ dbg_##reg##i }, \ NULL, NULL, NULL, 0 #define REG_CONTEXT_SIZE \ - (sizeof(RegisterContextLinux_arm::GPR) + \ - sizeof(RegisterContextLinux_arm::FPU) + \ - sizeof(RegisterContextLinux_arm::EXC)) + (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ + sizeof(RegisterInfoPOSIX_arm::EXC)) //----------------------------------------------------------------------------- // Include RegisterInfos_arm to declare our g_register_infos_arm structure. @@ -76,21 +74,21 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { } } -RegisterContextLinux_arm::RegisterContextLinux_arm( +RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm( const lldb_private::ArchSpec &target_arch) : lldb_private::RegisterInfoInterface(target_arch), m_register_info_p(GetRegisterInfoPtr(target_arch)), m_register_info_count(GetRegisterInfoCount(target_arch)) {} -size_t RegisterContextLinux_arm::GetGPRSize() const { - return sizeof(struct RegisterContextLinux_arm::GPR); +size_t RegisterInfoPOSIX_arm::GetGPRSize() const { + return sizeof(struct RegisterInfoPOSIX_arm::GPR); } const lldb_private::RegisterInfo * -RegisterContextLinux_arm::GetRegisterInfo() const { +RegisterInfoPOSIX_arm::GetRegisterInfo() const { return m_register_info_p; } -uint32_t RegisterContextLinux_arm::GetRegisterCount() const { +uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const { return m_register_info_count; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h index 422ecb7686dc8..d90aec1c5116f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_arm.h ----------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm.h ---------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_arm_h_ -#define liblldb_RegisterContextFreeBSD_arm_h_ +#ifndef liblldb_RegisterInfoPOSIX_arm_h_ +#define liblldb_RegisterInfoPOSIX_arm_h_ #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" -class RegisterContextFreeBSD_arm : public lldb_private::RegisterInfoInterface { +class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoInterface { public: struct GPR { uint32_t r[16]; // R0-R15 @@ -46,7 +46,7 @@ public: uint32_t wcr[16]; }; - RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch); + RegisterInfoPOSIX_arm(const lldb_private::ArchSpec &target_arch); size_t GetGPRSize() const override; @@ -59,4 +59,4 @@ private: uint32_t m_register_info_count; }; -#endif // liblldb_RegisterContextFreeBSD_arm_h_ +#endif // liblldb_RegisterInfoPOSIX_arm_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 3b29a18dbe20c..435f3d18c0625 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -15,7 +15,6 @@ // Project includes #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/StreamString.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" @@ -25,6 +24,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 6e2a9a9ee100e..2b34bddd90b2f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/Function.h" @@ -17,6 +16,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" #include "RegisterContextLLDB.h" #include "UnwindLLDB.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h index b9323032180dd..3f84649aa05f8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h @@ -16,11 +16,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/ConstString.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/ConstString.h" #include "lldb/lldb-public.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 6ac308fe559c0..6561d2a05828f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -14,8 +14,6 @@ #include <mutex> // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" @@ -25,8 +23,12 @@ #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 "llvm/Support/ELF.h" +#include "llvm/Support/Threading.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" @@ -56,9 +58,12 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, lldb::ProcessSP process_sp; if (crash_file) { // Read enough data for a ELF32 header or ELF64 header + // Note: Here we care about e_type field only, so it is safe + // to ignore possible presence of the header extension. const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); - lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size)); + auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), + header_size, 0); if (data_sp && data_sp->GetByteSize() == header_size && elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) { elf::ELFHeader elf_header; @@ -209,16 +214,19 @@ Error ProcessElfCore::DoLoadCore() { // Even if the architecture is set in the target, we need to override // it to match the core file which is always single arch. ArchSpec arch(m_core_module_sp->GetArchitecture()); - if (arch.IsValid()) - GetTarget().SetArchitecture(arch); + ArchSpec target_arch = GetTarget().GetArchitecture(); + ArchSpec core_arch(m_core_module_sp->GetArchitecture()); + target_arch.MergeFrom(core_arch); + GetTarget().SetArchitecture(target_arch); + SetUnixSignals(UnixSignals::Create(GetArchitecture())); // Ensure we found at least one thread that was stopped on a signal. bool siginfo_signal_found = false; bool prstatus_signal_found = false; // Check we found a signal in a SIGINFO note. - for (const auto &thread_data: m_thread_data) { + for (const auto &thread_data : m_thread_data) { if (thread_data.signo != 0) siginfo_signal_found = true; if (thread_data.prstatus_sig != 0) @@ -228,7 +236,7 @@ Error ProcessElfCore::DoLoadCore() { // If we don't have signal from SIGINFO use the signal from each threads // PRSTATUS note. if (prstatus_signal_found) { - for (auto &thread_data: m_thread_data) + for (auto &thread_data : m_thread_data) thread_data.signo = thread_data.prstatus_sig; } else if (m_thread_data.size() > 0) { // If all else fails force the first thread to be SIGSTOP @@ -365,6 +373,10 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address + // Don't proceed if core file doesn't contain the actual data for this address range. + if (file_start == file_end) + return 0; + // Figure out how many on-disk bytes remain in this segment // starting at the given offset if (file_end > file_start + offset) @@ -398,9 +410,9 @@ void ProcessElfCore::Clear() { } void ProcessElfCore::Initialize() { - static std::once_flag g_once_flag; + static llvm::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); }); @@ -426,6 +438,10 @@ enum { NT_FILE = 0x46494c45, NT_PRXFPREG = 0x46e62b7f, NT_SIGINFO = 0x53494749, + NT_OPENBSD_PROCINFO = 10, + NT_OPENBSD_AUXV = 11, + NT_OPENBSD_REGS = 20, + NT_OPENBSD_FPREGS = 21, }; namespace FREEBSD { @@ -440,6 +456,11 @@ enum { }; } +namespace NETBSD { + +enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 }; +} + // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, ArchSpec &arch) { @@ -476,6 +497,28 @@ static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) { thread_data.name = data.GetCStr(&offset, 20); } +static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) { + lldb::offset_t offset = 0; + + int version = data.GetU32(&offset); + if (version != 1) + return; + + offset += 4; + thread_data.signo = data.GetU32(&offset); +} + +static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) { + lldb::offset_t offset = 0; + + int version = data.GetU32(&offset); + if (version != 1) + return; + + offset += 4; + thread_data.signo = data.GetU32(&offset); +} + /// Parse Thread context from PT_NOTE segment and store it in the thread list /// Notes: /// 1) A PT_NOTE segment is composed of one or more NOTE entries. @@ -564,6 +607,39 @@ Error ProcessElfCore::ParseThreadContextsFromNoteSegment( default: break; } + } else if (note.n_name.substr(0, 11) == "NetBSD-CORE") { + // NetBSD per-thread information is stored in notes named + // "NetBSD-CORE@nnn" so match on the initial part of the string. + m_os = llvm::Triple::NetBSD; + if (note.n_type == NETBSD::NT_PROCINFO) { + ParseNetBSDProcInfo(*thread_data, note_data); + } else if (note.n_type == NETBSD::NT_AUXV) { + m_auxv = DataExtractor(note_data); + } else if (arch.GetMachine() == llvm::Triple::x86_64 && + note.n_type == NETBSD::NT_AMD64_REGS) { + thread_data->gpregset = note_data; + } else if (arch.GetMachine() == llvm::Triple::x86_64 && + note.n_type == NETBSD::NT_AMD64_FPREGS) { + thread_data->fpregset = note_data; + } + } else if (note.n_name.substr(0, 7) == "OpenBSD") { + // OpenBSD per-thread information is stored in notes named + // "OpenBSD@nnn" so match on the initial part of the string. + m_os = llvm::Triple::OpenBSD; + switch (note.n_type) { + case NT_OPENBSD_PROCINFO: + ParseOpenBSDProcInfo(*thread_data, note_data); + break; + case NT_OPENBSD_AUXV: + m_auxv = DataExtractor(note_data); + break; + case NT_OPENBSD_REGS: + thread_data->gpregset = note_data; + break; + case NT_OPENBSD_FPREGS: + thread_data->fpregset = note_data; + break; + } } else if (note.n_name == "CORE") { switch (note.n_type) { case NT_PRSTATUS: @@ -583,6 +659,8 @@ Error ProcessElfCore::ParseThreadContextsFromNoteSegment( // The result from FXSAVE is in NT_PRXFPREG for i386 core files if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64) thread_data->fpregset = note_data; + else if(arch.IsMIPS()) + thread_data->fpregset = note_data; break; case NT_PRPSINFO: have_prpsinfo = true; @@ -650,6 +728,12 @@ ArchSpec ProcessElfCore::GetArchitecture() { (ObjectFileELF *)(m_core_module_sp->GetObjectFile()); ArchSpec arch; core_file->GetArchitecture(arch); + + ArchSpec target_arch = GetTarget().GetArchitecture(); + + if (target_arch.IsMIPS()) + return target_arch; + return arch; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index a8dde47b30790..cb2f31bde4c5c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -24,9 +24,9 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/ConstString.h" -#include "lldb/Core/Error.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Error.h" #include "Plugins/ObjectFile/ELF/ELFHeader.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index c0850e5e414e7..e095eac5eaf81 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -15,8 +15,8 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm { public: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index da3e5bff605c0..3a2bbdb0a2ebf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -15,8 +15,8 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 { public: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 6a168d314fd72..7549cf074be7f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -22,6 +22,10 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + m_fpr_buffer.reset( + new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); + m_fpr.SetData(m_fpr_buffer); + m_fpr.SetByteOrder(fpregset.GetByteOrder()); } RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {} @@ -42,12 +46,24 @@ bool RegisterContextCorePOSIX_mips64::WriteFPR() { bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { + lldb::offset_t offset = reg_info->byte_offset; - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); - if (offset == reg_info->byte_offset + reg_info->byte_size) { + lldb_private::ArchSpec arch = m_register_info_ap->GetTargetArchitecture(); + uint64_t v; + if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { + if (reg_info->byte_size == 4 && !(arch.GetMachine() == llvm::Triple::mips64el)) + // In case of 32bit core file, the register data are placed at 4 byte + // offset. + offset = offset / 2; + v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); value = v; return true; - } + } else if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { + offset = offset - sizeof(GPR_linux_mips); + v =m_fpr.GetMaxU64(&offset, reg_info->byte_size); + value = v; + return true; + } return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index b1deca3d3178b..2cb527a8de7c5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -15,8 +15,8 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_mips64 : public RegisterContextPOSIX_mips64 { public: @@ -51,7 +51,9 @@ protected: private: lldb::DataBufferSP m_gpr_buffer; + lldb::DataBufferSP m_fpr_buffer; lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpr; }; #endif // liblldb_RegisterContextCorePOSIX_mips64_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index edfa1902c3272..62f6413722f73 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_powerpc.h" -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h index 8e6315f06636a..aaa95e5d2397f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -15,7 +15,7 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc { public: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index 6db817789612a..b3530a8d6a42f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_s390x.h" -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h index 516e5c57e2b94..2b4ae10a87bd9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h @@ -15,7 +15,7 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/DataExtractor.h" class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x { public: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 7f8223f7752e8..260ae15d7a54d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_x86_64.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 0143146b79abf..a1cc26afb3960 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -7,22 +7,26 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" -#include "Plugins/Process/Utility/RegisterContextLinux_arm.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" //#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" +#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "ProcessElfCore.h" #include "RegisterContextPOSIXCore_arm.h" @@ -88,7 +92,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { reg_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::arm: - reg_interface = new RegisterContextFreeBSD_arm(arch); + reg_interface = new RegisterInfoPOSIX_arm(arch); break; case llvm::Triple::ppc: reg_interface = new RegisterContextFreeBSD_powerpc32(arch); @@ -111,14 +115,33 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { break; } + case llvm::Triple::NetBSD: { + switch (arch.GetMachine()) { + case llvm::Triple::x86_64: + reg_interface = new RegisterContextNetBSD_x86_64(arch); + break; + default: + break; + } + break; + } + case llvm::Triple::Linux: { switch (arch.GetMachine()) { case llvm::Triple::arm: - reg_interface = new RegisterContextLinux_arm(arch); + reg_interface = new RegisterInfoPOSIX_arm(arch); break; case llvm::Triple::aarch64: reg_interface = new RegisterInfoPOSIX_arm64(arch); break; + case llvm::Triple::mipsel: + case llvm::Triple::mips: + reg_interface = new RegisterContextLinux_mips(arch); + break; + case llvm::Triple::mips64el: + case llvm::Triple::mips64: + reg_interface = new RegisterContextLinux_mips64(arch); + break; // case llvm::Triple::systemz: // reg_interface = new RegisterContextLinux_s390x(arch); // break; @@ -134,6 +157,26 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { break; } + case llvm::Triple::OpenBSD: { + switch (arch.GetMachine()) { + case llvm::Triple::aarch64: + reg_interface = new RegisterInfoPOSIX_arm64(arch); + break; + case llvm::Triple::arm: + reg_interface = new RegisterInfoPOSIX_arm(arch); + break; + case llvm::Triple::x86: + reg_interface = new RegisterContextOpenBSD_i386(arch); + break; + case llvm::Triple::x86_64: + reg_interface = new RegisterContextOpenBSD_x86_64(arch); + break; + default: + break; + } + break; + } + default: break; } @@ -154,7 +197,13 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( *this, reg_interface, m_gpregset_data, m_fpregset_data)); break; + case llvm::Triple::mipsel: + case llvm::Triple::mips: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( + *this, reg_interface, m_gpregset_data, m_fpregset_data)); + break; case llvm::Triple::mips64: + case llvm::Triple::mips64el: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( *this, reg_interface, m_gpregset_data, m_fpregset_data)); break; @@ -200,6 +249,31 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() { memset(this, 0, sizeof(ELFLinuxPrStatus)); } +size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) { + constexpr size_t mips_linux_pr_status_size_o32 = 96; + constexpr size_t mips_linux_pr_status_size_n32 = 72; + if (arch.IsMIPS()) { + std::string abi = arch.GetTargetABI(); + assert(!abi.empty() && "ABI is not set"); + if (!abi.compare("n64")) + return sizeof(ELFLinuxPrStatus); + else if (!abi.compare("o32")) + return mips_linux_pr_status_size_o32; + // N32 ABI + return mips_linux_pr_status_size_n32; + } + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxPrStatus); + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 72; + default: + return 0; + } +} + Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) { Error error; if (GetSize(arch) > data.GetByteSize()) { @@ -239,7 +313,6 @@ Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) { pr_cstime.tv_sec = data.GetPointer(&offset); pr_cstime.tv_usec = data.GetPointer(&offset); - return error; } @@ -250,6 +323,27 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); } +size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) { + constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; + if (arch.IsMIPS()) { + uint8_t address_byte_size = arch.GetAddressByteSize(); + if (address_byte_size == 8) + return sizeof(ELFLinuxPrPsInfo); + return mips_linux_pr_psinfo_size_o32_n32; + } + + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxPrPsInfo); + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 124; + default: + return 0; + } +} + Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { Error error; ByteOrder byteorder = data.GetByteOrder(); @@ -273,9 +367,15 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { pr_flag = data.GetPointer(&offset); + if (arch.IsMIPS()) { + // The pr_uid and pr_gid is always 32 bit irrespective of platforms + pr_uid = data.GetU32(&offset); + pr_gid = data.GetU32(&offset); + } else { // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); + } pr_pid = data.GetU32(&offset); pr_ppid = data.GetU32(&offset); @@ -296,8 +396,21 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { //---------------------------------------------------------------- // Parse SIGINFO from NOTE entry //---------------------------------------------------------------- -ELFLinuxSigInfo::ELFLinuxSigInfo() { - memset(this, 0, sizeof(ELFLinuxSigInfo)); +ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } + +size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { + if (arch.IsMIPS()) + return sizeof(ELFLinuxSigInfo); + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxSigInfo); + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 12; + default: + return 0; + } } Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index 1957ac243ceb0..38c52658a23a2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -16,8 +16,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/DataExtractor.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" struct compat_timeval { alignas(8) uint64_t tv_sec; @@ -65,18 +65,7 @@ struct ELFLinuxPrStatus { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxPrStatus); - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 72; - default: - return 0; - } - } + static size_t GetSize(lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxPrStatus) == 112, @@ -97,18 +86,7 @@ struct ELFLinuxSigInfo { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(const lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxSigInfo); - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 12; - default: - return 0; - } - } + static size_t GetSize(const lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxSigInfo) == 12, @@ -143,18 +121,7 @@ struct ELFLinuxPrPsInfo { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxPrPsInfo); - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 124; - default: - return 0; - } - } + static size_t GetSize(lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxPrPsInfo) == 136, diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index bd87521fe6e75..7ef253decad66 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -16,12 +16,8 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/Log.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" #include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Pipe.h" @@ -30,6 +26,10 @@ #include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/StreamString.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/ScopedPrinter.h" @@ -72,7 +72,7 @@ void GDBRemoteCommunication::History::AddPacket(char 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 = Host::GetCurrentThreadID(); + m_packets[idx].tid = llvm::get_threadid(); } } @@ -87,7 +87,7 @@ void GDBRemoteCommunication::History::AddPacket(const std::string &src, 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 = Host::GetCurrentThreadID(); + m_packets[idx].tid = llvm::get_threadid(); } } @@ -321,8 +321,7 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, uint8_t buffer[8192]; Error error; - Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS | - GDBR_LOG_VERBOSE)); + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); // Check for a packet from our cache first without trying any reading... if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid) @@ -334,12 +333,11 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, lldb::ConnectionStatus status = eConnectionStatusNoConnection; size_t bytes_read = Read(buffer, sizeof(buffer), timeout, status, &error); - if (log) - log->Printf("%s: Read (buffer, (sizeof(buffer), timeout = %ld us, " - "status = %s, error = %s) => bytes_read = %" PRIu64, - LLVM_PRETTY_FUNCTION, long(timeout ? timeout->count() : -1), - Communication::ConnectionStatusAsCString(status), - error.AsCString(), (uint64_t)bytes_read); + LLDB_LOGV(log, + "Read(buffer, sizeof(buffer), timeout = {0}, " + "status = {1}, error = {2}) => bytes_read = {3}", + timeout, Communication::ConnectionStatusAsCString(status), error, + bytes_read); if (bytes_read > 0) { if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid) @@ -607,10 +605,10 @@ bool GDBRemoteCommunication::DecompressPacket() { m_compression_type == CompressionType::LZFSE || m_compression_type == CompressionType::LZ4)) { compression_algorithm compression_type; - if (m_compression_type == CompressionType::ZlibDeflate) - compression_type = COMPRESSION_ZLIB; - else if (m_compression_type == CompressionType::LZFSE) + if (m_compression_type == CompressionType::LZFSE) compression_type = COMPRESSION_LZFSE; + else if (m_compression_type == CompressionType::ZlibDeflate) + compression_type = COMPRESSION_ZLIB; else if (m_compression_type == CompressionType::LZ4) compression_type = COMPRESSION_LZ4_RAW; else if (m_compression_type == CompressionType::LZMA) @@ -1085,8 +1083,7 @@ Error GDBRemoteCommunication::StartDebugserverProcess( // port is null when debug server should listen on domain socket - // we're not interested in port value but rather waiting for debug server // to become available. - if (pass_comm_fd == -1 && - ((port != nullptr && *port == 0) || port == nullptr)) { + if (pass_comm_fd == -1) { if (url) { // Create a temporary file to get the stdout/stderr and redirect the // output of the command into this file. We will later read this file @@ -1258,11 +1255,21 @@ Error GDBRemoteCommunication::StartDebugserverProcess( port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes); if (error.Success() && (port != nullptr)) { assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0'); - *port = StringConvert::ToUInt32(port_cstr, 0); - if (log) - log->Printf("GDBRemoteCommunication::%s() " - "debugserver listens %u port", - __FUNCTION__, *port); + uint16_t child_port = StringConvert::ToUInt32(port_cstr, 0); + if (*port == 0 || *port == child_port) { + *port = child_port; + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "debugserver listens %u port", + __FUNCTION__, *port); + } else { + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "debugserver listening on port " + "%d but requested port was %d", + __FUNCTION__, (uint32_t)child_port, + (uint32_t)(*port)); + } } else { if (log) log->Printf("GDBRemoteCommunication::%s() " diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index b70f0903dbd56..2e94fa94331d1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -18,21 +18,20 @@ #include <sstream> // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/State.h" -#include "lldb/Core/StreamGDBRemote.h" -#include "lldb/Core/StreamString.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/StreamString.h" // Project includes #include "ProcessGDBRemote.h" @@ -87,6 +86,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_supports_jThreadExtendedInfo(eLazyBoolCalculate), m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate), m_supports_jGetSharedCacheInfo(eLazyBoolCalculate), + m_supports_QPassSignals(eLazyBoolCalculate), m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true), m_supports_qUserName(true), m_supports_qGroupName(true), m_supports_qThreadStopInfo(true), m_supports_z0(true), @@ -150,6 +150,13 @@ bool GDBRemoteCommunicationClient::GetEchoSupported() { return m_supports_qEcho == eLazyBoolYes; } +bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() { + if (m_supports_QPassSignals == eLazyBoolCalculate) { + GetRemoteQSupported(); + } + return m_supports_QPassSignals == eLazyBoolYes; +} + bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() { if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) { GetRemoteQSupported(); @@ -419,6 +426,11 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { else m_supports_qEcho = eLazyBoolNo; + if (::strstr(response_cstr, "QPassSignals+")) + m_supports_QPassSignals = eLazyBoolYes; + else + m_supports_QPassSignals = eLazyBoolNo; + const char *packet_size_str = ::strstr(response_cstr, "PacketSize="); if (packet_size_str) { StringExtractorGDBRemote packet_response(packet_size_str + @@ -1491,13 +1503,18 @@ Error GDBRemoteCommunicationClient::GetMemoryRegionInfo( } } - // We got a valid address range back but no permissions -- which means - // this is an unmapped page - if (region_info.GetRange().IsValid() && saw_permissions == false) { - region_info.SetReadable(MemoryRegionInfo::eNo); - region_info.SetWritable(MemoryRegionInfo::eNo); - region_info.SetExecutable(MemoryRegionInfo::eNo); - region_info.SetMapped(MemoryRegionInfo::eNo); + if (region_info.GetRange().IsValid()) { + // We got a valid address range back but no permissions -- which means + // this is an unmapped page + if (!saw_permissions) { + region_info.SetReadable(MemoryRegionInfo::eNo); + region_info.SetWritable(MemoryRegionInfo::eNo); + region_info.SetExecutable(MemoryRegionInfo::eNo); + region_info.SetMapped(MemoryRegionInfo::eNo); + } + } else { + // We got an invalid address range back + error.SetErrorString("Server returned invalid range"); } } else { m_supports_memory_region_info = eLazyBoolNo; @@ -1660,7 +1677,7 @@ bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { return false; std::string cwd; response.GetHexByteString(cwd); - working_dir.SetFile(cwd, false, GetHostArchitecture()); + working_dir.SetFile(cwd, false, GetHostArchitecture().GetTriple()); return !cwd.empty(); } return false; @@ -1907,6 +1924,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name); assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat); + assert(triple.getObjectFormat() != llvm::Triple::Wasm); switch (triple.getObjectFormat()) { case llvm::Triple::MachO: m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub); @@ -1917,6 +1935,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { case llvm::Triple::COFF: m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub); break; + case llvm::Triple::Wasm: + if (log) + log->Printf("error: not supported target architecture"); + return false; case llvm::Triple::UnknownObjectFormat: if (log) log->Printf("error: failed to determine target architecture"); @@ -1957,29 +1979,29 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( bool has_name_match = false; if (name && name[0]) { has_name_match = true; - NameMatchType name_match_type = match_info.GetNameMatchType(); + NameMatch name_match_type = match_info.GetNameMatchType(); switch (name_match_type) { - case eNameMatchIgnore: + case NameMatch::Ignore: has_name_match = false; break; - case eNameMatchEquals: + case NameMatch::Equals: packet.PutCString("name_match:equals;"); break; - case eNameMatchContains: + case NameMatch::Contains: packet.PutCString("name_match:contains;"); break; - case eNameMatchStartsWith: + case NameMatch::StartsWith: packet.PutCString("name_match:starts_with;"); break; - case eNameMatchEndsWith: + case NameMatch::EndsWith: packet.PutCString("name_match:ends_with;"); break; - case eNameMatchRegularExpression: + case NameMatch::RegularExpression: packet.PutCString("name_match:regex;"); break; } @@ -2190,23 +2212,19 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets, const duration<float> standard_deviation = calculate_standard_deviation(packet_times); if (json) { - strm.Printf("%s\n {\"send_size\" : %6" PRIu32 - ", \"recv_size\" : %6" PRIu32 - ", \"total_time_nsec\" : %12" PRIu64 - ", \"standard_deviation_nsec\" : %9" PRIu64 " }", + strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : " + "{2,6}, \"total_time_nsec\" : {3,12:ns-}, " + "\"standard_deviation_nsec\" : {4,9:ns-f0}}", result_idx > 0 ? "," : "", send_size, recv_size, - duration_cast<nanoseconds>(total_time).count(), - duration_cast<nanoseconds>(standard_deviation).count()); + total_time, standard_deviation); ++result_idx; } else { - strm.Printf( - "qSpeedTest(send=%-7u, recv=%-7u) in %.9f" - " sec for %9.2f packets/sec (%10.6f ms per packet) with standard " - "deviation of %10.6f ms\n", - send_size, recv_size, duration<float>(total_time).count(), - packets_per_second, - duration<float, std::milli>(average_per_packet).count(), - duration<float, std::milli>(standard_deviation).count()); + strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for " + "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with " + "standard deviation of {5,10:ms+f6}\n", + send_size, recv_size, duration<float>(total_time), + packets_per_second, duration<float>(average_per_packet), + standard_deviation); } strm.Flush(); } @@ -2249,21 +2267,18 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets, const auto average_per_packet = total_time / packet_count; if (json) { - strm.Printf("%s\n {\"send_size\" : %6" PRIu32 - ", \"recv_size\" : %6" PRIu32 - ", \"total_time_nsec\" : %12" PRIu64 " }", + strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : " + "{2,6}, \"total_time_nsec\" : {3,12:ns-}}", result_idx > 0 ? "," : "", send_size, recv_size, - duration_cast<nanoseconds>(total_time).count()); + total_time); ++result_idx; } else { - strm.Printf("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to " - "receive %2.1fMB in %.9f" - " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per " - "packet)\n", + strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed " + "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for " + "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n", send_size, recv_size, packet_count, k_recv_amount_mb, - duration<float>(total_time).count(), mb_second, - packets_per_second, - duration<float, std::milli>(average_per_packet).count()); + duration<float>(total_time), mb_second, + packets_per_second, duration<float>(average_per_packet)); } strm.Flush(); } @@ -3193,7 +3208,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( StringExtractor extractor(value); std::string path; extractor.GetHexByteString(path); - module_spec.GetFileSpec() = FileSpec(path, false, arch_spec); + module_spec.GetFileSpec() = FileSpec(path, false, arch_spec.GetTriple()); } } @@ -3227,7 +3242,8 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { if (!dict->GetValueForKeyAsString("file_path", string)) return llvm::None; - result.GetFileSpec() = FileSpec(string, false, result.GetArchitecture()); + result.GetFileSpec() = + FileSpec(string, false, result.GetArchitecture().GetTriple()); return result; } @@ -3254,6 +3270,9 @@ GDBRemoteCommunicationClient::GetModulesInfo( payload.PutEscapedBytes(unescaped_payload.GetString().data(), unescaped_payload.GetSize()); + // Increase the timeout for jModulesInfo since this packet can take longer. + ScopedTimeout timeout(*this, std::chrono::seconds(10)); + StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(payload.GetString(), response, false) != PacketResult::Success || @@ -3571,6 +3590,26 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { : nullptr; } +Error GDBRemoteCommunicationClient::SendSignalsToIgnore( + llvm::ArrayRef<int32_t> signals) { + // Format packet: + // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN> + auto range = llvm::make_range(signals.begin(), signals.end()); + std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str(); + + StringExtractorGDBRemote response; + auto send_status = SendPacketAndWaitForResponse(packet, response, false); + + if (send_status != GDBRemoteCommunication::PacketResult::Success) + return Error("Sending QPassSignals packet failed"); + + if (response.IsOKResponse()) { + return Error(); + } else { + return Error("Unknown error happened during sending QPassSignals packet."); + } +} + Error GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( const ConstString &type_name, const StructuredData::ObjectSP &config_sp) { Error error; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 83162a662e06c..63b9708cc9a0a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -347,6 +347,8 @@ public: bool GetEchoSupported(); + bool GetQPassSignalsSupported(); + bool GetAugmentedLibrariesSVR4ReadSupported(); bool GetQXferFeaturesReadSupported(); @@ -450,6 +452,9 @@ public: void ServeSymbolLookups(lldb_private::Process *process); + // Sends QPassSignals packet to the server with given signals to ignore. + Error SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals); + //------------------------------------------------------------------ /// Return the feature set supported by the gdb-remote server. /// @@ -527,6 +532,7 @@ protected: LazyBool m_supports_jThreadExtendedInfo; LazyBool m_supports_jLoadedDynamicLibrariesInfos; LazyBool m_supports_jGetSharedCacheInfo; + LazyBool m_supports_QPassSignals; bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1, m_supports_qUserName : 1, m_supports_qGroupName : 1, diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index e4e6810f665c1..66c1b15ff8572 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -22,23 +22,22 @@ #include <cstring> // Other libraries and framework includes -#include "lldb/Core/Log.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/StreamGDBRemote.h" -#include "lldb/Core/StreamString.h" #include "lldb/Host/Config.h" -#include "lldb/Host/Endian.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/Endian.h" #include "lldb/Utility/JSON.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/StreamString.h" #include "llvm/ADT/Triple.h" // Project includes @@ -360,16 +359,15 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( extractor.GetHexByteString(file); match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false); } else if (key.equals("name_match")) { - NameMatchType name_match = - llvm::StringSwitch<NameMatchType>(value) - .Case("equals", eNameMatchEquals) - .Case("starts_with", eNameMatchStartsWith) - .Case("ends_with", eNameMatchEndsWith) - .Case("contains", eNameMatchContains) - .Case("regex", eNameMatchRegularExpression) - .Default(eNameMatchIgnore); + NameMatch name_match = llvm::StringSwitch<NameMatch>(value) + .Case("equals", NameMatch::Equals) + .Case("starts_with", NameMatch::StartsWith) + .Case("ends_with", NameMatch::EndsWith) + .Case("contains", NameMatch::Contains) + .Case("regex", NameMatch::RegularExpression) + .Default(NameMatch::Ignore); match_info.SetNameMatchType(name_match); - if (name_match == eNameMatchIgnore) + if (name_match == NameMatch::Ignore) return SendErrorResponse(2); } else if (key.equals("pid")) { lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; @@ -643,14 +641,15 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Size( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path, false)); + uint64_t Size; + if (llvm::sys::fs::file_size(path, Size)) + return SendErrorResponse(5); StreamString response; response.PutChar('F'); - response.PutHex64(retcode); - if (retcode == UINT64_MAX) { + response.PutHex64(Size); + if (Size == UINT64_MAX) { response.PutChar(','); - response.PutHex64( - retcode); // TODO: replace with Host::GetSyswideErrorCode() + response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode() } return SendPacketNoLock(response.GetString()); } @@ -682,7 +681,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Exists( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - bool retcode = FileSystem::GetFileExists(FileSpec(path, false)); + bool retcode = llvm::sys::fs::exists(path); StreamString response; response.PutChar('F'); response.PutChar(','); @@ -715,7 +714,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( packet.SetFilePos(::strlen("vFile:unlink:")); std::string path; packet.GetHexByteString(path); - Error error = FileSystem::Unlink(FileSpec{path, true}); + Error error(llvm::sys::fs::remove(path)); StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); @@ -772,15 +771,15 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_MD5( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - uint64_t a, b; StreamGDBRemote response; - if (!FileSystem::CalculateMD5(FileSpec(path, false), a, b)) { + auto Result = llvm::sys::fs::md5_contents(path); + if (!Result) { response.PutCString("F,"); response.PutCString("x"); } else { response.PutCString("F,"); - response.PutHex64(a); - response.PutHex64(b); + response.PutHex64(Result->low()); + response.PutHex64(Result->high()); } return SendPacketNoLock(response.GetString()); } @@ -795,7 +794,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( if (packet.GetChar() == ',') { std::string path; packet.GetHexByteString(path); - Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode); + Error error(llvm::sys::fs::create_directory(path, mode)); StreamGDBRemote response; response.Printf("F%u", error.GetError()); @@ -810,11 +809,12 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("qPlatform_chmod:")); - mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); + auto perms = + static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX)); if (packet.GetChar() == ',') { std::string path; packet.GetHexByteString(path); - Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode); + Error error(llvm::sys::fs::setPermissions(path, perms)); StreamGDBRemote response; response.Printf("F%u", error.GetError()); @@ -838,7 +838,8 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported( response.PutCString(";QThreadSuffixSupported+"); response.PutCString(";QListThreadsInStopReply+"); response.PutCString(";qEcho+"); -#if defined(__linux__) +#if defined(__linux__) || defined(__NetBSD__) + response.PutCString(";QPassSignals+"); response.PutCString(";qXfer:auxv:read+"); #endif @@ -1091,12 +1092,11 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( StreamGDBRemote response; if (uuid_str.empty()) { - std::string md5_hash; - if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), - file_offset, file_size, md5_hash)) + auto Result = llvm::sys::fs::md5_contents(matched_module_spec.GetFileSpec().GetPath()); + if (!Result) return SendErrorResponse(5); response.PutCString("md5:"); - response.PutCStringAsRawHex8(md5_hash.c_str()); + response.PutCStringAsRawHex8(Result->digest().c_str()); } else { response.PutCString("uuid:"); response.PutCStringAsRawHex8(uuid_str.c_str()); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index bf72673f17696..290889ec662ae 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -12,7 +12,7 @@ #include "lldb/Host/Config.h" #include "GDBRemoteCommunicationServerLLGS.h" -#include "lldb/Core/StreamGDBRemote.h" +#include "lldb/Utility/StreamGDBRemote.h" // C Includes // C++ Includes @@ -21,27 +21,27 @@ #include <thread> // Other libraries and framework includes -#include "lldb/Core/DataBuffer.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/State.h" -#include "lldb/Core/StreamString.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" -#include "lldb/Host/Endian.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Interpreter/Args.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/Endian.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ScopedPrinter.h" @@ -49,7 +49,6 @@ #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "Utility/StringExtractorGDBRemote.h" -#include "Utility/UriParser.h" using namespace lldb; using namespace lldb_private; @@ -81,7 +80,6 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(), m_debugged_process_sp(), m_stdio_communication("process.stdio"), m_inferior_prev_state(StateType::eStateInvalid), - m_active_auxv_buffer_sp(), m_saved_registers_mutex(), m_saved_registers_map(), m_next_saved_registers_id(1), m_handshake_completed(false) { RegisterPacketHandlers(); @@ -181,6 +179,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { &GDBRemoteCommunicationServerLLGS::Handle_Z); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z, &GDBRemoteCommunicationServerLLGS::Handle_z); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_QPassSignals, + &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals); RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k, [this](StringExtractorGDBRemote packet, Error &error, @@ -415,7 +416,8 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf, static void WriteRegisterValueInHexFixedWidth( StreamString &response, NativeRegisterContextSP ®_ctx_sp, - const RegisterInfo ®_info, const RegisterValue *reg_value_p) { + const RegisterInfo ®_info, const RegisterValue *reg_value_p, + lldb::ByteOrder byte_order) { RegisterValue reg_value; if (!reg_value_p) { Error error = reg_ctx_sp->ReadRegister(®_info, reg_value); @@ -426,7 +428,8 @@ static void WriteRegisterValueInHexFixedWidth( if (reg_value_p) { AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), - reg_value_p->GetByteSize(), false); + reg_value_p->GetByteSize(), + byte_order == lldb::eByteOrderLittle); } else { // Zero-out any unreadable values. if (reg_info.byte_size > 0) { @@ -436,8 +439,7 @@ static void WriteRegisterValueInHexFixedWidth( } } -static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread, - bool abridged) { +static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); @@ -462,11 +464,8 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread, static const uint32_t k_expedited_registers[] = { LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM}; - static const uint32_t k_abridged_expedited_registers[] = { - LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM}; - for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers - : k_expedited_registers; + for (const uint32_t *generic_reg_p = k_expedited_registers; *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) { uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( eRegisterKindGeneric, *generic_reg_p); @@ -501,7 +500,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread, StreamString stream; WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, - ®_value); + ®_value, lldb::eByteOrderBig); register_object_sp->SetObject( llvm::to_string(reg_num), @@ -567,8 +566,10 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>(); threads_array_sp->AppendObject(thread_obj_sp); - if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged)) - thread_obj_sp->SetObject("registers", registers_sp); + if (!abridged) { + if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp)) + thread_obj_sp->SetObject("registers", registers_sp); + } thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid)); if (signum != 0) @@ -721,6 +722,41 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( "jstopinfo field for pid %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID()); } + + uint32_t i = 0; + response.PutCString("thread-pcs"); + char delimiter = ':'; + for (NativeThreadProtocolSP thread_sp; + (thread_sp = m_debugged_process_sp->GetThreadAtIndex(i)) != nullptr; + ++i) { + NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (!reg_ctx_sp) + continue; + + uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *const reg_info_p = + reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read); + + RegisterValue reg_value; + Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); + if (error.Fail()) { + if (log) + log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", + __FUNCTION__, + reg_info_p->name ? reg_info_p->name + : "<unnamed-register>", + reg_to_read, error.AsCString()); + continue; + } + + response.PutChar(delimiter); + delimiter = ','; + WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, + ®_value, endian::InlHostByteOrder()); + } + + response.PutChar(';'); } // @@ -761,7 +797,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( if (error.Success()) { response.Printf("%.02x:", *reg_num_p); WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, - ®_value); + ®_value, lldb::eByteOrderBig); response.PutChar(';'); } else { if (log) @@ -2496,12 +2532,14 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { packet, "Too short z packet, missing software/hardware specifier"); bool want_breakpoint = true; + bool want_hardware = false; const GDBStoppointType stoppoint_type = GDBStoppointType(packet.GetS32(eStoppointInvalid)); switch (stoppoint_type) { case eBreakpointHardware: want_breakpoint = true; + want_hardware = true; break; case eBreakpointSoftware: want_breakpoint = true; @@ -2544,7 +2582,8 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { if (want_breakpoint) { // Try to clear the breakpoint. - const Error error = m_debugged_process_sp->RemoveBreakpoint(addr); + const Error error = + m_debugged_process_sp->RemoveBreakpoint(addr, want_hardware); if (error.Success()) return SendOKResponse(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); @@ -2625,7 +2664,7 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read( StringExtractorGDBRemote &packet) { // *BSD impls should be able to do this too. -#if defined(__linux__) +#if defined(__linux__) || defined(__NetBSD__) Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); // Parse out the offset. @@ -2653,7 +2692,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read( "qXfer:auxv:read:: packet missing length"); // Grab the auxv data if we need it. - if (!m_active_auxv_buffer_sp) { + if (!m_active_auxv_buffer_up) { // Make sure we have a valid process. if (!m_debugged_process_sp || (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { @@ -2665,55 +2704,45 @@ GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read( } // Grab the auxv data. - m_active_auxv_buffer_sp = Host::GetAuxvData(m_debugged_process_sp->GetID()); - if (!m_active_auxv_buffer_sp || - m_active_auxv_buffer_sp->GetByteSize() == 0) { - // Hmm, no auxv data, call that an error. - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data " - "retrieved", - __FUNCTION__); - m_active_auxv_buffer_sp.reset(); - return SendErrorResponse(0x11); + auto buffer_or_error = m_debugged_process_sp->GetAuxvData(); + if (!buffer_or_error) { + std::error_code ec = buffer_or_error.getError(); + LLDB_LOG(log, "no auxv data retrieved: {0}", ec.message()); + return SendErrorResponse(ec.value()); } + m_active_auxv_buffer_up = std::move(*buffer_or_error); } - // FIXME find out if/how I lock the stream here. - StreamGDBRemote response; bool done_with_buffer = false; - if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize()) { + llvm::StringRef buffer = m_active_auxv_buffer_up->getBuffer(); + if (auxv_offset >= buffer.size()) { // We have nothing left to send. Mark the buffer as complete. response.PutChar('l'); done_with_buffer = true; } else { // Figure out how many bytes are available starting at the given offset. - const uint64_t bytes_remaining = - m_active_auxv_buffer_sp->GetByteSize() - auxv_offset; - - // Figure out how many bytes we're going to read. - const uint64_t bytes_to_read = - (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length; + buffer = buffer.drop_front(auxv_offset); // Mark the response type according to whether we're reading the remainder // of the auxv data. - if (bytes_to_read >= bytes_remaining) { + if (auxv_length >= buffer.size()) { // There will be nothing left to read after this response.PutChar('l'); done_with_buffer = true; } else { // There will still be bytes to read after this request. response.PutChar('m'); + buffer = buffer.take_front(auxv_length); } // Now write the data in encoded binary form. - response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset, - bytes_to_read); + response.PutEscapedBytes(buffer.data(), buffer.size()); } if (done_with_buffer) - m_active_auxv_buffer_sp.reset(); + m_active_auxv_buffer_up.reset(); return SendPacketNoLock(response.GetString()); #else @@ -3002,9 +3031,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( if (packet.GetChar() != ':') return SendErrorResponse(67); - uint32_t num = m_debugged_process_sp->GetMaxWatchpoints(); + auto hw_debug_cap = m_debugged_process_sp->GetHardwareDebugSupportInfo(); + StreamGDBRemote response; - response.Printf("num:%d;", num); + if (hw_debug_cap == llvm::None) + response.Printf("num:0;"); + else + response.Printf("num:%d;", hw_debug_cap->second); + return SendPacketNoLock(response.GetString()); } @@ -3037,6 +3071,40 @@ GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( return SendPacketNoLock(response.GetString()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( + StringExtractorGDBRemote &packet) { + std::vector<int> signals; + packet.SetFilePos(strlen("QPassSignals:")); + + // Read sequence of hex signal numbers divided by a semicolon and + // optionally spaces. + while (packet.GetBytesLeft() > 0) { + int signal = packet.GetS32(-1, 16); + if (signal < 0) + return SendIllFormedResponse(packet, "Failed to parse signal number."); + signals.push_back(signal); + + packet.SkipSpaces(); + char separator = packet.GetChar(); + if (separator == '\0') + break; // End of string + if (separator != ';') + return SendIllFormedResponse(packet, "Invalid separator," + " expected semicolon."); + } + + // Fail if we don't have a current process. + if (!m_debugged_process_sp) + return SendErrorResponse(68); + + Error error = m_debugged_process_sp->IgnoreSignals(signals); + if (error.Fail()) + return SendErrorResponse(69); + + return SendOKResponse(); +} + void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); @@ -3136,20 +3204,10 @@ uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { } void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | GDBR_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__); + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -// Clear any auxv cached data. -// *BSD impls should be able to do this too. -#if defined(__linux__) - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer " - "(previously %s)", - __FUNCTION__, - m_active_auxv_buffer_sp ? "was set" : "was not set"); - m_active_auxv_buffer_sp.reset(); -#endif + LLDB_LOG(log, "clearing auxv buffer: {0}", m_active_auxv_buffer_up.get()); + m_active_auxv_buffer_up.reset(); } FileSpec diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index fa52cdaab493f..a47927e1c6408 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -117,7 +117,7 @@ protected: MainLoop::ReadHandleUP m_stdio_handle_up; lldb::StateType m_inferior_prev_state; - lldb::DataBufferSP m_active_auxv_buffer_sp; + std::unique_ptr<llvm::MemoryBuffer> m_active_auxv_buffer_up; std::mutex m_saved_registers_mutex; std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map; uint32_t m_next_saved_registers_id; @@ -203,6 +203,8 @@ protected: PacketResult Handle_qFileLoadAddress(StringExtractorGDBRemote &packet); + PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet); + void SetCurrentThreadID(lldb::tid_t tid); lldb::tid_t GetCurrentThreadID() const; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 11069749186a8..ae1c1adb5b458 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -20,25 +20,25 @@ // Other libraries and framework includes #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Threading.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamGDBRemote.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/StructuredData.h" #include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/JSON.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/UriParser.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" -#include "Utility/UriParser.h" using namespace lldb; using namespace lldb_private; @@ -82,8 +82,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform( &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, - [this](StringExtractorGDBRemote packet, Error &error, - bool &interrupt, bool &quit) { + [](StringExtractorGDBRemote packet, Error &error, + bool &interrupt, bool &quit) { error.SetErrorString("interrupt received"); interrupt = true; return PacketResult::Success; @@ -353,15 +353,13 @@ GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir( StringExtractorGDBRemote &packet) { - // If this packet is sent to a platform, then change the current working - // directory - char cwd[PATH_MAX]; - if (getcwd(cwd, sizeof(cwd)) == NULL) - return SendErrorResponse(errno); + llvm::SmallString<64> cwd; + if (std::error_code ec = llvm::sys::fs::current_path(cwd)) + return SendErrorResponse(ec.value()); StreamString response; - response.PutBytesAsRawHex8(cwd, strlen(cwd)); + response.PutBytesAsRawHex8(cwd.data(), cwd.size()); return SendPacketNoLock(response.GetString()); } @@ -372,10 +370,8 @@ GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir( std::string path; packet.GetHexByteString(path); - // If this packet is sent to a platform, then change the current working - // directory - if (::chdir(path.c_str()) != 0) - return SendErrorResponse(errno); + if (std::error_code ec = llvm::sys::fs::set_current_path(path)) + return SendErrorResponse(ec.value()); return SendOKResponse(); } @@ -532,9 +528,9 @@ bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) { const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { static FileSpec g_domainsocket_dir; - static std::once_flag g_once_flag; + static llvm::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + llvm::call_once(g_once_flag, []() { const char *domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); if (domainsocket_dir_env != nullptr) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 27ce67ded7835..ea4acc74893a1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -12,14 +12,13 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" -#include "lldb/Core/StreamString.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/Utils.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/StreamString.h" // Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 5b3e04eb588e0..8ef91af55e0f8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -17,9 +17,9 @@ // Other libraries and framework includes // Project includes #include "Plugins/Process/Utility/DynamicRegisterInfo.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 4b4d62d2e6a92..10e6b03647836 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -35,14 +35,13 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/Value.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostThread.h" +#include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/Symbols.h" #include "lldb/Host/ThreadLauncher.h" @@ -65,7 +64,8 @@ #include "lldb/Target/TargetList.h" #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/CleanUp.h" -#include "lldb/Utility/PseudoTerminal.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" // Project includes #include "GDBRemoteRegisterContext.h" @@ -80,6 +80,7 @@ #include "lldb/Host/Host.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" #define DEBUGSERVER_BASENAME "debugserver" @@ -576,7 +577,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); assert(dwarf_opcode_len == ret_val); - + UNUSED_IF_ASSERT_DISABLED(ret_val); reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data(); } } @@ -1616,9 +1617,7 @@ bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { // locker will keep a mutex locked until it goes out of scope Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_THREAD)); - if (log && log->GetMask().Test(GDBR_LOG_VERBOSE)) - log->Printf("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, - GetID()); + LLDB_LOGV(log, "pid = {0}", GetID()); size_t num_thread_ids = m_thread_ids.size(); // The "m_thread_ids" thread ID list should always be updated after each stop @@ -1637,39 +1636,14 @@ bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list, old_thread_list_copy.RemoveThreadByProtocolID(tid, false)); if (!thread_sp) { thread_sp.reset(new ThreadGDBRemote(*this, tid)); - if (log && log->GetMask().Test(GDBR_LOG_VERBOSE)) - log->Printf("ProcessGDBRemote::%s Making new thread: %p for thread " - "ID: 0x%" PRIx64 ".\n", - __FUNCTION__, static_cast<void *>(thread_sp.get()), - thread_sp->GetID()); + LLDB_LOGV(log, "Making new thread: {0} for thread ID: {1:x}.", + thread_sp.get(), thread_sp->GetID()); } else { - if (log && log->GetMask().Test(GDBR_LOG_VERBOSE)) - log->Printf("ProcessGDBRemote::%s Found old thread: %p for thread " - "ID: 0x%" PRIx64 ".\n", - __FUNCTION__, static_cast<void *>(thread_sp.get()), - thread_sp->GetID()); - } - // The m_thread_pcs vector has pc values in big-endian order, not - // target-endian, unlike most - // of the register read/write packets in gdb-remote protocol. - // Early in the process startup, we may not yet have set the process - // ByteOrder so we ignore these; - // they are a performance improvement over fetching thread register values - // individually, the - // method we will fall back to if needed. - if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() && - GetByteOrder() != eByteOrderInvalid) { - ThreadGDBRemote *gdb_thread = - static_cast<ThreadGDBRemote *>(thread_sp.get()); - RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); - if (reg_ctx_sp) { - uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( - eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - if (pc_regnum != LLDB_INVALID_REGNUM) { - gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[i]); - } - } + LLDB_LOGV(log, "Found old thread: {0} for thread ID: {1:x}.", + thread_sp.get(), thread_sp->GetID()); } + + SetThreadPc(thread_sp, i); new_thread_list.AddThreadSortedByIndexID(thread_sp); } } @@ -1689,6 +1663,22 @@ bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list, return true; } +void ProcessGDBRemote::SetThreadPc(const ThreadSP &thread_sp, uint64_t index) { + if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() && + GetByteOrder() != eByteOrderInvalid) { + ThreadGDBRemote *gdb_thread = + static_cast<ThreadGDBRemote *>(thread_sp.get()); + RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); + if (reg_ctx_sp) { + uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + if (pc_regnum != LLDB_INVALID_REGNUM) { + gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[index]); + } + } + } +} + bool ProcessGDBRemote::GetThreadStopInfoFromJSON( ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) { // See if we got thread stop infos for all threads via the "jThreadsInfo" @@ -1774,6 +1764,11 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( static_cast<ThreadGDBRemote *>(thread_sp.get()); gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true); + auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid); + if (iter != m_thread_ids.end()) { + SetThreadPc(thread_sp, iter - m_thread_ids.begin()); + } + for (const auto &pair : expedited_register_map) { StringExtractor reg_value_extractor; reg_value_extractor.GetStringRef() = pair.second; @@ -2731,16 +2726,19 @@ void ProcessGDBRemote::WillPublicStop() { size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, Error &error) { GetMaxMemorySize(); - if (size > m_max_memory_size) { + bool binary_memory_read = m_gdb_comm.GetxPacketSupported(); + // M and m packets take 2 bytes for 1 byte of memory + size_t max_memory_size = + binary_memory_read ? m_max_memory_size : m_max_memory_size / 2; + if (size > max_memory_size) { // Keep memory read sizes down to a sane limit. This function will be // called multiple times in order to complete the task by // lldb_private::Process so it is ok to do this. - size = m_max_memory_size; + size = max_memory_size; } char packet[64]; int packet_len; - bool binary_memory_read = m_gdb_comm.GetxPacketSupported(); packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64, binary_memory_read ? 'x' : 'm', (uint64_t)addr, (uint64_t)size); @@ -2787,11 +2785,13 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, size_t size, Error &error) { GetMaxMemorySize(); - if (size > m_max_memory_size) { + // M and m packets take 2 bytes for 1 byte of memory + size_t max_memory_size = m_max_memory_size / 2; + if (size > max_memory_size) { // Keep memory read sizes down to a sane limit. This function will be // called multiple times in order to complete the task by // lldb_private::Process so it is ok to do this. - size = m_max_memory_size; + size = max_memory_size; } StreamString packet; @@ -3429,9 +3429,9 @@ void ProcessGDBRemote::KillDebugserverProcess() { } void ProcessGDBRemote::Initialize() { - static std::once_flag g_once_flag; + static llvm::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, DebuggerInitialize); @@ -3741,6 +3741,43 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit( return false; } +Error ProcessGDBRemote::UpdateAutomaticSignalFiltering() { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG(log, "Check if need to update ignored signals"); + + // QPassSignals package is not supported by the server, + // there is no way we can ignore any signals on server side. + if (!m_gdb_comm.GetQPassSignalsSupported()) + return Error(); + + // No signals, nothing to send. + if (m_unix_signals_sp == nullptr) + return Error(); + + // Signals' version hasn't changed, no need to send anything. + uint64_t new_signals_version = m_unix_signals_sp->GetVersion(); + if (new_signals_version == m_last_signals_version) { + LLDB_LOG(log, "Signals' version hasn't changed. version={0}", + m_last_signals_version); + return Error(); + } + + auto signals_to_ignore = + m_unix_signals_sp->GetFilteredSignals(false, false, false); + Error error = m_gdb_comm.SendSignalsToIgnore(signals_to_ignore); + + LLDB_LOG(log, + "Signals' version changed. old version={0}, new version={1}, " + "signals ignored={2}, update result={3}", + m_last_signals_version, new_signals_version, + signals_to_ignore.size(), error); + + if (error.Success()) + m_last_signals_version = new_signals_version; + + return error; +} + bool ProcessGDBRemote::StartNoticingNewThreads() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (m_thread_create_bp_sp) { @@ -3990,6 +4027,21 @@ void ProcessGDBRemote::GetMaxMemorySize() { stub_max_size = reasonable_largeish_default; } + // Memory packet have other overheads too like Maddr,size:#NN + // Instead of calculating the bytes taken by size and addr every + // time, we take a maximum guess here. + if (stub_max_size > 70) + stub_max_size -= 32 + 32 + 6; + else { + // In unlikely scenario that max packet size is less then 70, we will + // hope that data being written is small enough to fit. + Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( + GDBR_LOG_COMM | GDBR_LOG_MEMORY)); + if (log) + log->Warning("Packet size is too small. " + "LLDB may face problems while writing memory"); + } + m_max_memory_size = stub_max_size; } else { m_max_memory_size = conservative_default; @@ -4134,8 +4186,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, ®_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, - ®_info, &cur_reg_num, ®_offset, - &dwarf_opcode_bytes]( + ®_info, ®_offset, &dwarf_opcode_bytes]( const llvm::StringRef &name, const llvm::StringRef &value) -> bool { if (name == "name") { @@ -4215,7 +4266,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); assert(dwarf_opcode_len == ret_val); - + UNUSED_IF_ASSERT_DISABLED(ret_val); reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data(); } else { printf("unhandled attribute %s = %s\n", name.data(), value.data()); @@ -4297,7 +4348,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { XMLNode target_node = xml_document.GetRootElement("target"); if (target_node) { XMLNode feature_node; - target_node.ForEachChildElement([&target_info, this, &feature_node]( + target_node.ForEachChildElement([&target_info, &feature_node]( const XMLNode &node) -> bool { llvm::StringRef name = node.GetName(); if (name == "architecture") { @@ -4423,8 +4474,8 @@ Error ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { LoadedModuleInfoList::LoadedModuleInfo module; library.ForEachAttribute( - [log, &module](const llvm::StringRef &name, - const llvm::StringRef &value) -> bool { + [&module](const llvm::StringRef &name, + const llvm::StringRef &value) -> bool { if (name == "name") module.set_name(value.str()); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 6423abc558363..a1794d0f50508 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -22,18 +22,18 @@ // Project includes #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Broadcaster.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/Error.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/StringList.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractor.h" +#include "lldb/Utility/StringList.h" #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationClient.h" @@ -397,12 +397,15 @@ protected: lldb::addr_t base_addr, bool value_is_offset); + Error UpdateAutomaticSignalFiltering() override; + private: //------------------------------------------------------------------ // For ProcessGDBRemote only //------------------------------------------------------------------ std::string m_partial_profile_data; std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map; + uint64_t m_last_signals_version = 0; static bool NewThreadNotifyBreakpointHit(void *baton, StoppointCallbackContext *context, @@ -417,6 +420,7 @@ private: void HandleStopReply() override; void HandleAsyncStructuredDataPacket(llvm::StringRef data) override; + void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index); using ModuleCacheKey = std::pair<std::string, std::string>; // KeyInfo for the cached module spec DenseMap. // The invariant is that all real keys will have the file and architecture diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp index 899037ae98aa4..8f16b83907cf6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp @@ -8,210 +8,37 @@ //===----------------------------------------------------------------------===// #include "ProcessGDBRemoteLog.h" - -#include <mutex> - -#include "lldb/Core/StreamFile.h" -#include "lldb/Interpreter/Args.h" - #include "ProcessGDBRemote.h" +#include "llvm/Support/Threading.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static bool g_log_enabled = false; -static Log *g_log = NULL; -static Log *GetLog() { - if (!g_log_enabled) - return NULL; - return g_log; -} +static constexpr Log::Category g_categories[] = { + {{"async"}, {"log asynchronous activity"}, GDBR_LOG_ASYNC}, + {{"break"}, {"log breakpoints"}, GDBR_LOG_BREAKPOINTS}, + {{"comm"}, {"log communication activity"}, GDBR_LOG_COMM}, + {{"packets"}, {"log gdb remote packets"}, GDBR_LOG_PACKETS}, + {{"memory"}, {"log memory reads and writes"}, GDBR_LOG_MEMORY}, + {{"data-short"}, + {"log memory bytes for memory reads and writes for short transactions " + "only"}, + GDBR_LOG_MEMORY_DATA_SHORT}, + {{"data-long"}, + {"log memory bytes for memory reads and writes for all transactions"}, + GDBR_LOG_MEMORY_DATA_LONG}, + {{"process"}, {"log process events and activities"}, GDBR_LOG_PROCESS}, + {{"step"}, {"log step related activities"}, GDBR_LOG_STEP}, + {{"thread"}, {"log thread events and activities"}, GDBR_LOG_THREAD}, + {{"watch"}, {"log watchpoint related activities"}, GDBR_LOG_WATCHPOINTS}, +}; -void ProcessGDBRemoteLog::Initialize() { - static ConstString g_name("gdb-remote"); - static std::once_flag g_once_flag; - - std::call_once(g_once_flag, []() { - Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories}; +Log::Channel ProcessGDBRemoteLog::g_channel(g_categories, GDBR_LOG_DEFAULT); - Log::RegisterLogChannel(g_name, log_callbacks); +void ProcessGDBRemoteLog::Initialize() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + Log::Register("gdb-remote", g_channel); }); } - -Log *ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(uint32_t mask) { - Log *log(GetLog()); - if (log && mask) { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return NULL; - } - return log; -} - -Log *ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(uint32_t mask) { - Log *log(GetLog()); - if (log && log->GetMask().Get() & mask) - return log; - return NULL; -} - -void ProcessGDBRemoteLog::DisableLog(const char **categories, - Stream *feedback_strm) { - Log *log(GetLog()); - if (log) { - uint32_t flag_bits = 0; - - if (categories && categories[0]) { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; categories[i] != NULL; ++i) { - const char *arg = categories[i]; - - if (::strcasecmp(arg, "all") == 0) - flag_bits &= ~GDBR_LOG_ALL; - else if (::strcasecmp(arg, "async") == 0) - flag_bits &= ~GDBR_LOG_ASYNC; - else if (::strncasecmp(arg, "break", 5) == 0) - flag_bits &= ~GDBR_LOG_BREAKPOINTS; - else if (::strncasecmp(arg, "comm", 4) == 0) - flag_bits &= ~GDBR_LOG_COMM; - else if (::strcasecmp(arg, "default") == 0) - flag_bits &= ~GDBR_LOG_DEFAULT; - else if (::strcasecmp(arg, "packets") == 0) - flag_bits &= ~GDBR_LOG_PACKETS; - else if (::strcasecmp(arg, "memory") == 0) - flag_bits &= ~GDBR_LOG_MEMORY; - else if (::strcasecmp(arg, "data-short") == 0) - flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp(arg, "data-long") == 0) - flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp(arg, "process") == 0) - flag_bits &= ~GDBR_LOG_PROCESS; - else if (::strcasecmp(arg, "step") == 0) - flag_bits &= ~GDBR_LOG_STEP; - else if (::strcasecmp(arg, "thread") == 0) - flag_bits &= ~GDBR_LOG_THREAD; - else if (::strcasecmp(arg, "verbose") == 0) - flag_bits &= ~GDBR_LOG_VERBOSE; - else if (::strncasecmp(arg, "watch", 5) == 0) - flag_bits &= ~GDBR_LOG_WATCHPOINTS; - else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories(feedback_strm); - } - } - } - - if (flag_bits == 0) - g_log_enabled = false; - else - log->GetMask().Reset(flag_bits); - } - - return; -} - -Log *ProcessGDBRemoteLog::EnableLog(StreamSP &log_stream_sp, - uint32_t log_options, - const char **categories, - Stream *feedback_strm) { - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the - // same. - uint32_t flag_bits = 0; - if (g_log) - flag_bits = g_log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) { - if (g_log) - g_log->SetStream(log_stream_sp); - else - g_log = new Log(log_stream_sp); - } - - if (g_log) { - bool got_unknown_category = false; - for (size_t i = 0; categories[i] != NULL; ++i) { - const char *arg = categories[i]; - - if (::strcasecmp(arg, "all") == 0) - flag_bits |= GDBR_LOG_ALL; - else if (::strcasecmp(arg, "async") == 0) - flag_bits |= GDBR_LOG_ASYNC; - else if (::strncasecmp(arg, "break", 5) == 0) - flag_bits |= GDBR_LOG_BREAKPOINTS; - else if (::strncasecmp(arg, "comm", 4) == 0) - flag_bits |= GDBR_LOG_COMM; - else if (::strcasecmp(arg, "default") == 0) - flag_bits |= GDBR_LOG_DEFAULT; - else if (::strcasecmp(arg, "packets") == 0) - flag_bits |= GDBR_LOG_PACKETS; - else if (::strcasecmp(arg, "memory") == 0) - flag_bits |= GDBR_LOG_MEMORY; - else if (::strcasecmp(arg, "data-short") == 0) - flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp(arg, "data-long") == 0) - flag_bits |= GDBR_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp(arg, "process") == 0) - flag_bits |= GDBR_LOG_PROCESS; - else if (::strcasecmp(arg, "step") == 0) - flag_bits |= GDBR_LOG_STEP; - else if (::strcasecmp(arg, "thread") == 0) - flag_bits |= GDBR_LOG_THREAD; - else if (::strcasecmp(arg, "verbose") == 0) - flag_bits |= GDBR_LOG_VERBOSE; - else if (::strncasecmp(arg, "watch", 5) == 0) - flag_bits |= GDBR_LOG_WATCHPOINTS; - else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) { - got_unknown_category = true; - ListLogCategories(feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = GDBR_LOG_DEFAULT; - g_log->GetMask().Reset(flag_bits); - g_log->GetOptions().Reset(log_options); - } - g_log_enabled = true; - return g_log; -} - -void ProcessGDBRemoteLog::ListLogCategories(Stream *strm) { - strm->Printf( - "Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short " - "transactions only\n" - " data-long - log memory bytes for memory reads and writes for all " - "transactions\n" - " process - log process events and activities\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", - ProcessGDBRemote::GetPluginNameStatic().GetCString()); -} - -void ProcessGDBRemoteLog::LogIf(uint32_t mask, const char *format, ...) { - Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(mask)); - if (log) { - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index f5e92b4506143..3c58011766908 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -15,9 +15,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/Log.h" +#include "lldb/Utility/Log.h" -#define GDBR_LOG_VERBOSE (1u << 0) #define GDBR_LOG_PROCESS (1u << 1) #define GDBR_LOG_THREAD (1u << 2) #define GDBR_LOG_PACKETS (1u << 3) @@ -37,21 +36,13 @@ namespace lldb_private { namespace process_gdb_remote { class ProcessGDBRemoteLog { + static Log::Channel g_channel; + public: static void Initialize(); - static Log *GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static Log *GetLogIfAnyCategoryIsSet(uint32_t mask); - - static void DisableLog(const char **categories, Stream *feedback_strm); - - static Log *EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options, - const char **categories, Stream *feedback_strm); - - static void ListLogCategories(Stream *strm); - - static void LogIf(uint32_t mask, const char *format, ...); + static Log *GetLogIfAllCategoriesSet(uint32_t mask) { return g_channel.GetLogIfAll(mask); } + static Log *GetLogIfAnyCategoryIsSet(uint32_t mask) { return g_channel.GetLogIfAny(mask); } }; } // namespace process_gdb_remote diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index ab552145a18bd..5197e8f9adfcc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -11,9 +11,7 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/State.h" -#include "lldb/Core/StreamString.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -22,6 +20,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/StreamString.h" #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" @@ -41,18 +41,16 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid) m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown), m_queue_serial_number(LLDB_INVALID_QUEUE_ID), m_associated_with_libdispatch_queue(eLazyBoolCalculate) { - ProcessGDBRemoteLog::LogIf( - GDBR_LOG_THREAD, - "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, - process.GetID(), GetID()); + Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); + LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(), + GetID()); } ThreadGDBRemote::~ThreadGDBRemote() { ProcessSP process_sp(GetProcess()); - ProcessGDBRemoteLog::LogIf( - GDBR_LOG_THREAD, - "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, - process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID()); + Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); + LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, + process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID()); DestroyThread(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/CMakeLists.txt b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/CMakeLists.txt index ddc89cbd92c15..61ce16830c9b9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/CMakeLists.txt +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/CMakeLists.txt @@ -1,10 +1,19 @@ include_directories(../Utility) -add_lldb_library(lldbPluginProcessMinidump +add_lldb_library(lldbPluginProcessMinidump PLUGIN MinidumpTypes.cpp MinidumpParser.cpp RegisterContextMinidump_x86_32.cpp RegisterContextMinidump_x86_64.cpp ProcessMinidump.cpp ThreadMinidump.cpp + + LINK_LIBS + lldbCore + lldbTarget + lldbUtility + lldbPluginProcessUtility + lldbPluginProcessElfCore + LINK_COMPONENTS + Support ) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 67523a72ad115..189aeb3d64e64 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -16,8 +16,8 @@ // Other libraries and framework includes #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataBuffer.h" -#include "lldb/Core/Error.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/Error.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h index 46871a1b84d88..42de7eaaca037 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h @@ -13,7 +13,7 @@ // Project includes // Other libraries and framework includes -#include "lldb/Core/Error.h" +#include "lldb/Utility/Error.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitmaskEnum.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 46d8df8b16f12..f3f4664ad6e1d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -12,8 +12,6 @@ #include "ThreadMinidump.h" // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" @@ -23,7 +21,12 @@ #include "lldb/Target/MemoryRegionInfo.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 "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Threading.h" // C includes // C++ includes @@ -48,20 +51,25 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, lldb::ProcessSP process_sp; // Read enough data for the Minidump header - const size_t header_size = sizeof(MinidumpHeader); - lldb::DataBufferSP data_sp(crash_file->MemoryMapFileContents(0, header_size)); - if (!data_sp) + constexpr size_t header_size = sizeof(MinidumpHeader); + auto DataPtr = + DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0); + if (!DataPtr) return nullptr; + assert(DataPtr->GetByteSize() == header_size); + // first, only try to parse the header, beacuse we need to be fast - llvm::ArrayRef<uint8_t> header_data(data_sp->GetBytes(), header_size); - const MinidumpHeader *header = MinidumpHeader::Parse(header_data); + llvm::ArrayRef<uint8_t> HeaderBytes = DataPtr->GetData(); + const MinidumpHeader *header = MinidumpHeader::Parse(HeaderBytes); + if (header == nullptr) + return nullptr; - if (data_sp->GetByteSize() != header_size || header == nullptr) + auto AllData = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), -1, 0); + if (!AllData) return nullptr; - lldb::DataBufferSP all_data_sp(crash_file->MemoryMapFileContents()); - auto minidump_parser = MinidumpParser::Create(all_data_sp); + auto minidump_parser = MinidumpParser::Create(AllData); // check if the parser object is valid if (!minidump_parser) return nullptr; @@ -92,9 +100,9 @@ ProcessMinidump::~ProcessMinidump() { } void ProcessMinidump::Initialize() { - static std::once_flag g_once_flag; + static llvm::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), ProcessMinidump::CreateInstance); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 78eadc809a4de..62407f9275516 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -15,11 +15,11 @@ #include "MinidumpTypes.h" // Other libraries and framework includes -#include "lldb/Core/ConstString.h" -#include "lldb/Core/Error.h" #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Error.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 7f3768216f3a9..7605f8b143af6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -11,7 +11,7 @@ #include "RegisterContextMinidump_x86_32.h" // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Utility/DataBufferHeap.h" // C includes // C++ includes diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index 881c26a5774a6..ba1cb6dbf3efd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -11,7 +11,7 @@ #include "RegisterContextMinidump_x86_64.h" // Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Utility/DataBufferHeap.h" // C includes // C++ includes diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp index e42108b9261a8..9c21cc92376fc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -20,12 +20,12 @@ #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" // C Includes // C++ Includes |
