diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
commit | ead246455adf1a215ec2715dad6533073a6beb4e (patch) | |
tree | f3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Plugins/Process | |
parent | fdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff) |
Notes
Diffstat (limited to 'source/Plugins/Process')
71 files changed, 3238 insertions, 3057 deletions
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp index 3ec410fe7d768..f70ef97a2bc59 100644 --- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp +++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp @@ -254,9 +254,8 @@ CreatePosixSpawnFileAction(const FileAction &action, case FileAction::eFileActionNone: default: - if (log) - log->Printf("%s(): unsupported file action %u", __FUNCTION__, - action.GetAction()); + LLDB_LOGF(log, "%s(): unsupported file action %u", __FUNCTION__, + action.GetAction()); break; } @@ -288,8 +287,7 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path, int error_code; if ((error_code = ::posix_spawnattr_init(&attr)) != 0) { - if (log) - log->Printf("::posix_spawnattr_init(&attr) failed"); + LLDB_LOGF(log, "::posix_spawnattr_init(&attr) failed"); error.SetError(error_code, eErrorTypePOSIX); return error; } @@ -378,10 +376,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path, error = CreatePosixSpawnFileAction(*action, &file_actions); if (!error.Success()) { - if (log) - log->Printf("%s(): error converting FileAction to posix_spawn " - "file action: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "%s(): error converting FileAction to posix_spawn " + "file action: %s", + __FUNCTION__, error.AsCString()); return error; } } @@ -416,10 +414,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path, if (actual_cpu_type) { *actual_cpu_type = GetCPUTypeForLocalProcess(*pid); - if (log) - log->Printf("%s(): cpu type for launched process pid=%i: " - "cpu_type=0x%8.8x", - __FUNCTION__, *pid, *actual_cpu_type); + LLDB_LOGF(log, + "%s(): cpu type for launched process pid=%i: " + "cpu_type=0x%8.8x", + __FUNCTION__, *pid, *actual_cpu_type); } return error; @@ -477,23 +475,21 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd, char resolved_path[PATH_MAX]; resolved_path[0] = '\0'; - if (log) - log->Printf("%s(): attempting to resolve given binary path: \"%s\"", - __FUNCTION__, given_path); + LLDB_LOGF(log, "%s(): attempting to resolve given binary path: \"%s\"", + __FUNCTION__, given_path); // If we fail to resolve the path to our executable, then just use what we // were given and hope for the best if (!ResolveExecutablePath(given_path, resolved_path, sizeof(resolved_path))) { - if (log) - log->Printf("%s(): failed to resolve binary path, using " - "what was given verbatim and hoping for the best", - __FUNCTION__); + LLDB_LOGF(log, + "%s(): failed to resolve binary path, using " + "what was given verbatim and hoping for the best", + __FUNCTION__); ::strncpy(resolved_path, given_path, sizeof(resolved_path)); } else { - if (log) - log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__, - resolved_path); + LLDB_LOGF(log, "%s(): resolved given binary path to: \"%s\"", __FUNCTION__, + resolved_path); } char launch_err_str[PATH_MAX]; diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp index 70ad6736a7487..073ad64b300c1 100644 --- a/source/Plugins/Process/Darwin/MachException.cpp +++ b/source/Plugins/Process/Darwin/MachException.cpp @@ -67,10 +67,11 @@ extern "C" kern_return_t catch_mach_exception_raise_state( // TODO change to LIBLLDB_LOG_EXCEPTION Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); if (log) { - log->Printf("::%s(exc_port = 0x%4.4x, exc_type = %d (%s), " - "exc_data = 0x%llx, exc_data_count = %d)", - __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type), - (uint64_t)exc_data, exc_data_count); + LLDB_LOGF(log, + "::%s(exc_port = 0x%4.4x, exc_type = %d (%s), " + "exc_data = 0x%llx, exc_data_count = %d)", + __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type), + (uint64_t)exc_data, exc_data_count); } return KERN_FAILURE; } @@ -83,13 +84,14 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity( thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); if (log) { - log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, " - "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = " - "{ 0x%llx, 0x%llx })", - __FUNCTION__, exc_port, thread_port, task_port, exc_type, - MachException::Name(exc_type), exc_data_count, - (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD), - (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD)); + LLDB_LOGF(log, + "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, " + "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = " + "{ 0x%llx, 0x%llx })", + __FUNCTION__, exc_port, thread_port, task_port, exc_type, + MachException::Name(exc_type), exc_data_count, + (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD), + (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD)); } return KERN_FAILURE; @@ -102,13 +104,14 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port, mach_msg_type_number_t exc_data_count) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); if (log) { - log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, " - "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] " - "= { 0x%llx, 0x%llx })", - __FUNCTION__, exc_port, thread_port, task_port, exc_type, - MachException::Name(exc_type), exc_data_count, - (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD), - (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD)); + LLDB_LOGF(log, + "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, " + "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] " + "= { 0x%llx, 0x%llx })", + __FUNCTION__, exc_port, thread_port, task_port, exc_type, + MachException::Name(exc_type), exc_data_count, + (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD), + (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD)); } if (task_port == g_message->task_port) { @@ -187,15 +190,16 @@ Status MachException::Message::Receive(mach_port_t port, options & MACH_RCV_TIMEOUT ? timeout : 0; if (log && ((options & MACH_RCV_TIMEOUT) == 0)) { // Dump this log message if we have no timeout in case it never returns - log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, " - "local_port = %#x, reserved = 0x%x, id = 0x%x}, " - "option = %#x, send_size = 0, rcv_size = %llu, " - "rcv_name = %#x, timeout = %u, notify = %#x)", - exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size, - exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port, - exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, - (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout, - notify_port); + LLDB_LOGF(log, + "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, " + "local_port = %#x, reserved = 0x%x, id = 0x%x}, " + "option = %#x, send_size = 0, rcv_size = %llu, " + "rcv_name = %#x, timeout = %u, notify = %#x)", + exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size, + exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port, + exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, + (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout, + notify_port); } mach_msg_return_t mach_err = @@ -213,15 +217,16 @@ Status MachException::Message::Receive(mach_port_t port, // Dump any errors we get if (error.Fail() && log) { - log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, " - "local_port = %#x, reserved = 0x%x, id = 0x%x}, " - "option = %#x, send_size = %u, rcv_size = %lu, rcv_name " - "= %#x, timeout = %u, notify = %#x) failed: %s", - exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size, - exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port, - exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0, - sizeof(exc_msg.data), port, mach_msg_timeout, notify_port, - error.AsCString()); + LLDB_LOGF(log, + "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, " + "local_port = %#x, reserved = 0x%x, id = 0x%x}, " + "option = %#x, send_size = %u, rcv_size = %lu, rcv_name " + "= %#x, timeout = %u, notify = %#x) failed: %s", + exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size, + exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port, + exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0, + sizeof(exc_msg.data), port, mach_msg_timeout, notify_port, + error.AsCString()); } return error; } @@ -264,10 +269,10 @@ bool MachException::Message::CatchExceptionRaise(task_t task) { } else { Log *log( GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf("MachException::Message::%s(): mach_exc_server " - "returned zero...", - __FUNCTION__); + LLDB_LOGF(log, + "MachException::Message::%s(): mach_exc_server " + "returned zero...", + __FUNCTION__); } g_message = NULL; return success; @@ -293,10 +298,10 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task, auto mach_err = ::pid_for_task(state.task_port, &state_pid); if (mach_err) { error.SetError(mach_err, eErrorTypeMachKernel); - if (log) - log->Printf("MachException::Message::%s(): pid_for_task() " - "failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "MachException::Message::%s(): pid_for_task() " + "failed: %s", + __FUNCTION__, error.AsCString()); return error; } } @@ -309,25 +314,25 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task, error.SetError(errno, eErrorTypePOSIX); if (!error.Success()) { - if (log) - log->Printf("::ptrace(request = PT_THUPDATE, pid = " - "0x%4.4x, tid = 0x%4.4x, signal = %i)", - state_pid, state.thread_port, soft_signal); + LLDB_LOGF(log, + "::ptrace(request = PT_THUPDATE, pid = " + "0x%4.4x, tid = 0x%4.4x, signal = %i)", + state_pid, state.thread_port, soft_signal); return error; } } } - if (log) - log->Printf("::mach_msg ( msg->{bits = %#x, size = %u, remote_port " - "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, " - "option = %#x, send_size = %u, rcv_size = %u, rcv_name " - "= %#x, timeout = %u, notify = %#x)", - reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size, - reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port, - reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id, - MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0, - MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + LLDB_LOGF(log, + "::mach_msg ( msg->{bits = %#x, size = %u, remote_port " + "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, " + "option = %#x, send_size = %u, rcv_size = %u, rcv_name " + "= %#x, timeout = %u, notify = %#x)", + reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size, + reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port, + reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id, + MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0, + MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); auto mach_err = ::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT, @@ -342,12 +347,13 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task, log->PutCString("::mach_msg() - send interrupted"); // TODO: keep retrying to reply??? } else if (state.task_port == inferior_task) { - log->Printf("mach_msg(): returned an error when replying " - "to a mach exception: error = %u (%s)", - error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "mach_msg(): returned an error when replying " + "to a mach exception: error = %u (%s)", + error.GetError(), error.AsCString()); } else { - log->Printf("::mach_msg() - failed (child of task): %u (%s)", - error.GetError(), error.AsCString()); + LLDB_LOGF(log, "::mach_msg() - failed (child of task): %u (%s)", + error.GetError(), error.AsCString()); } } @@ -377,9 +383,8 @@ Status MachException::PortInfo::Save(task_t task) { Status error; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__, - task); + LLDB_LOGF(log, "MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__, + task); // Be careful to be able to have debugserver built on a newer OS than what it // is currently running on by being able to start with all exceptions and @@ -394,13 +399,15 @@ Status MachException::PortInfo::Save(task_t task) { if (log) { if (error.Success()) { - log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = " - "0x%x, maskCnt => %u, ports, behaviors, flavors)", - task, mask, count); + LLDB_LOGF(log, + "::task_get_exception_ports(task = 0x%4.4x, mask = " + "0x%x, maskCnt => %u, ports, behaviors, flavors)", + task, mask, count); } else { - log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, " - "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)", - task, mask, count, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, " + "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)", + task, mask, count, error.GetError(), error.AsCString()); } } @@ -413,15 +420,17 @@ Status MachException::PortInfo::Save(task_t task) { error.SetError(mach_err, eErrorTypeMachKernel); if (log) { if (error.Success()) { - log->Printf("::task_get_exception_ports(task = 0x%4.4x, " - "mask = 0x%x, maskCnt => %u, ports, behaviors, " - "flavors)", - task, mask, count); + LLDB_LOGF(log, + "::task_get_exception_ports(task = 0x%4.4x, " + "mask = 0x%x, maskCnt => %u, ports, behaviors, " + "flavors)", + task, mask, count); } else { - log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = " - "0x%x, maskCnt => %u, ports, behaviors, flavors) " - "error: %u (%s)", - task, mask, count, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "::task_get_exception_ports(task = 0x%4.4x, mask = " + "0x%x, maskCnt => %u, ports, behaviors, flavors) " + "error: %u (%s)", + task, mask, count, error.GetError(), error.AsCString()); } } } @@ -437,8 +446,7 @@ Status MachException::PortInfo::Restore(task_t task) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf("MachException::PortInfo::Restore(task = 0x%4.4x)", task); + LLDB_LOGF(log, "MachException::PortInfo::Restore(task = 0x%4.4x)", task); uint32_t i = 0; if (count > 0) { @@ -449,17 +457,19 @@ Status MachException::PortInfo::Restore(task_t task) { error.SetError(mach_err, eErrorTypeMachKernel); if (log) { if (error.Success()) { - log->Printf("::task_set_exception_ports(task = 0x%4.4x, " - "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " - "behavior = 0x%8.8x, new_flavor = 0x%8.8x)", - task, masks[i], ports[i], behaviors[i], flavors[i]); + LLDB_LOGF(log, + "::task_set_exception_ports(task = 0x%4.4x, " + "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " + "behavior = 0x%8.8x, new_flavor = 0x%8.8x)", + task, masks[i], ports[i], behaviors[i], flavors[i]); } else { - log->Printf("::task_set_exception_ports(task = 0x%4.4x, " - "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " - "behavior = 0x%8.8x, new_flavor = 0x%8.8x): " - "error %u (%s)", - task, masks[i], ports[i], behaviors[i], flavors[i], - error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "::task_set_exception_ports(task = 0x%4.4x, " + "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " + "behavior = 0x%8.8x, new_flavor = 0x%8.8x): " + "error %u (%s)", + task, masks[i], ports[i], behaviors[i], flavors[i], + error.GetError(), error.AsCString()); } } diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp index fe7de27e0ee68..18dbdda9a33b2 100644 --- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp +++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp @@ -75,19 +75,19 @@ Status NativeProcessProtocol::Launch( // Handle launch failure. if (!error.Success()) { - if (log) - log->Printf("NativeProcessDarwin::%s() failed to launch process: " - "%s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() failed to launch process: " + "%s", + __FUNCTION__, error.AsCString()); return error; } // Handle failure to return a pid. if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) { - if (log) - log->Printf("NativeProcessDarwin::%s() launch succeeded but no " - "pid was returned! Aborting.", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() launch succeeded but no " + "pid was returned! Aborting.", + __FUNCTION__); return error; } @@ -104,10 +104,10 @@ Status NativeProcessProtocol::Launch( // NativeProcessDarwin instance. error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop); if (!error.Success()) { - if (log) - log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize" - " the launching of the process: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() aborting, failed to finalize" + " the launching of the process: %s", + __FUNCTION__, error.AsCString()); return error; } @@ -120,9 +120,8 @@ Status NativeProcessProtocol::Attach( lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__, - pid); + LLDB_LOGF(log, "NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__, + pid); // Retrieve the architecture for the running process. ArchSpec process_arch; @@ -173,10 +172,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor, error = StartExceptionThread(); if (!error.Success()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failure starting the " - "mach exception port monitor thread: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failure starting the " + "mach exception port monitor thread: %s", + __FUNCTION__, error.AsCString()); // Terminate the inferior process. There's nothing meaningful we can do if // we can't receive signals and exceptions. Since we launched the process, @@ -195,33 +194,31 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor, int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0); if (err == 0) { // m_flags |= eMachProcessFlagsAttached; - if (log) - log->Printf("NativeProcessDarwin::%s(): successfully spawned " - "process with pid %" PRIu64, - __FUNCTION__, m_pid); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): successfully spawned " + "process with pid %" PRIu64, + __FUNCTION__, m_pid); } else { error.SetErrorToErrno(); SetState(eStateExited); - if (log) - log->Printf("NativeProcessDarwin::%s(): error: failed to " - "attach to spawned pid %" PRIu64 " (error=%d (%s))", - __FUNCTION__, m_pid, (int)error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): error: failed to " + "attach to spawned pid %" PRIu64 " (error=%d (%s))", + __FUNCTION__, m_pid, (int)error.GetError(), error.AsCString()); return error; } } - if (log) - log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...", - __FUNCTION__, m_pid); + LLDB_LOGF(log, "NativeProcessDarwin::%s(): new pid is %" PRIu64 "...", + __FUNCTION__, m_pid); // Spawn a thread to reap our child inferior process... error = StartWaitpidThread(main_loop); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() " - "thread: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to start waitpid() " + "thread: %s", + __FUNCTION__, error.AsCString()); kill(SIGKILL, static_cast<::pid_t>(m_pid)); return error; } @@ -230,10 +227,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor, // We failed to get the task for our process ID which is bad. Kill our // process; otherwise, it will be stopped at the entry point and get // reparented to someone else and never go away. - if (log) - log->Printf("NativeProcessDarwin::%s(): could not get task port " - "for process, sending SIGKILL and exiting: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): could not get task port " + "for process, sending SIGKILL and exiting: %s", + __FUNCTION__, error.AsCString()); kill(SIGKILL, static_cast<::pid_t>(m_pid)); return error; } @@ -278,18 +275,17 @@ void NativeProcessDarwin::ExceptionMessageReceived( // the exception to our internal exception stack m_exception_messages.push_back(message); - if (log) - log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu", - __FUNCTION__, m_exception_messages.size()); + LLDB_LOGF(log, "NativeProcessDarwin::%s(): new queued message count: %lu", + __FUNCTION__, m_exception_messages.size()); } void *NativeProcessDarwin::ExceptionThread(void *arg) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); if (!arg) { - if (log) - log->Printf("NativeProcessDarwin::%s(): cannot run mach exception " - "thread, mandatory process arg was null", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): cannot run mach exception " + "thread, mandatory process arg was null", + __FUNCTION__); return nullptr; } @@ -299,9 +295,8 @@ void *NativeProcessDarwin::ExceptionThread(void *arg) { void *NativeProcessDarwin::DoExceptionThread() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...", - __FUNCTION__, this); + LLDB_LOGF(log, "NativeProcessDarwin::%s(arg=%p) starting thread...", + __FUNCTION__, this); pthread_setname_np("exception monitoring thread"); @@ -344,20 +339,20 @@ void *NativeProcessDarwin::DoExceptionThread() { if (process->ProcessUsingSpringBoard()) { // Request a renewal for every 60 seconds if we attached using SpringBoard. watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60)); - if (log) - log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) " - "=> %p", - pid, watchdog.get()); + LLDB_LOGF(log, + "::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) " + "=> %p", + pid, watchdog.get()); if (watchdog.get()) { ::SBSWatchdogAssertionRenew(watchdog.get()); CFTimeInterval watchdogRenewalInterval = ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get()); - if (log) - log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => " - "%g seconds", - watchdog.get(), watchdogRenewalInterval); + LLDB_LOGF(log, + "::SBSWatchdogAssertionGetRenewalInterval(%p) => " + "%g seconds", + watchdog.get(), watchdogRenewalInterval); if (watchdogRenewalInterval > 0.0) { watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000; if (watchdog_timeout > 3000) { @@ -425,11 +420,11 @@ void *NativeProcessDarwin::DoExceptionThread() { // If we have no task port we should exit this thread, as it implies // the inferior went down. if (!IsExceptionPortValid()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): the inferior " - "exception port is no longer valid, " - "canceling exception thread...", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): the inferior " + "exception port is no longer valid, " + "canceling exception thread...", + __FUNCTION__); // Should we be setting a process state here? break; } @@ -437,19 +432,19 @@ void *NativeProcessDarwin::DoExceptionThread() { // Make sure the inferior task is still valid. if (IsTaskValid()) { // Task is still ok. - if (log) - log->Printf("NativeProcessDarwin::%s(): interrupted, but " - "the inferior task iss till valid, " - "continuing...", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): interrupted, but " + "the inferior task iss till valid, " + "continuing...", + __FUNCTION__); continue; } else { // The inferior task is no longer valid. Time to exit as the process // has gone away. - if (log) - log->Printf("NativeProcessDarwin::%s(): the inferior task " - "has exited, and so will we...", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): the inferior task " + "has exited, and so will we...", + __FUNCTION__); // Does this race at all with our waitpid()? SetState(eStateExited); break; @@ -471,18 +466,18 @@ void *NativeProcessDarwin::DoExceptionThread() { // our task is still valid. if (IsTaskValid(task)) { // Task is still ok. - if (log) - log->Printf("NativeProcessDarwin::%s(): got a timeout, " - "continuing...", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): got a timeout, " + "continuing...", + __FUNCTION__); continue; } else { // The inferior task is no longer valid. Time to exit as the // process has gone away. - if (log) - log->Printf("NativeProcessDarwin::%s(): the inferior " - "task has exited, and so will we...", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): the inferior " + "task has exited, and so will we...", + __FUNCTION__); // Does this race at all with our waitpid()? SetState(eStateExited); break; @@ -493,18 +488,17 @@ void *NativeProcessDarwin::DoExceptionThread() { if (watchdog.get()) { watchdog_elapsed += periodic_timeout; if (watchdog_elapsed >= watchdog_timeout) { - if (log) - log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get()); + LLDB_LOGF(log, "SBSWatchdogAssertionRenew(%p)", watchdog.get()); ::SBSWatchdogAssertionRenew(watchdog.get()); watchdog_elapsed = 0; } } #endif } else { - if (log) - log->Printf("NativeProcessDarwin::%s(): continuing after " - "receiving an unexpected error: %u (%s)", - __FUNCTION__, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): continuing after " + "receiving an unexpected error: %u (%s)", + __FUNCTION__, error.GetError(), error.AsCString()); // TODO: notify of error? } } @@ -523,17 +517,15 @@ void *NativeProcessDarwin::DoExceptionThread() { } #endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS) - if (log) - log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__, - this); + LLDB_LOGF(log, "NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__, + this); return nullptr; } Status NativeProcessDarwin::StartExceptionThread() { Status error; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__); + LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__); // Make sure we've looked up the inferior port. TaskPortForProcessID(error); @@ -554,11 +546,11 @@ Status NativeProcessDarwin::StartExceptionThread() { &m_exception_port); error.SetError(mach_err, eErrorTypeMachKernel); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): mach_port_allocate(" - "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, " - "&m_exception_port) failed: %u (%s)", - __FUNCTION__, task_self, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): mach_port_allocate(" + "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, " + "&m_exception_port) failed: %u (%s)", + __FUNCTION__, task_self, error.GetError(), error.AsCString()); return error; } @@ -567,23 +559,23 @@ Status NativeProcessDarwin::StartExceptionThread() { task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND); error.SetError(mach_err, eErrorTypeMachKernel); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right(" - "task_self=0x%4.4x, m_exception_port=0x%4.4x, " - "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) " - "failed: %u (%s)", - __FUNCTION__, task_self, m_exception_port, m_exception_port, - error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): mach_port_insert_right(" + "task_self=0x%4.4x, m_exception_port=0x%4.4x, " + "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) " + "failed: %u (%s)", + __FUNCTION__, task_self, m_exception_port, m_exception_port, + error.GetError(), error.AsCString()); return error; } // Save the original state of the exception ports for our child process. error = SaveExceptionPortInfo(); if (error.Fail() || (m_exc_port_info.mask == 0)) { - if (log) - log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() " - "failed, cannot install exception handler: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): SaveExceptionPortInfo() " + "failed, cannot install exception handler: %s", + __FUNCTION__, error.AsCString()); return error; } @@ -593,14 +585,14 @@ Status NativeProcessDarwin::StartExceptionThread() { EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE); error.SetError(mach_err, eErrorTypeMachKernel); if (error.Fail()) { - if (log) - log->Printf("::task_set_exception_ports (task = 0x%4.4x, " - "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " - "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: " - "%u (%s)", - m_task, m_exc_port_info.mask, m_exception_port, - (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE, - error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "::task_set_exception_ports (task = 0x%4.4x, " + "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " + "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: " + "%u (%s)", + m_task, m_exc_port_info.mask, m_exception_port, + (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE, + error.GetError(), error.AsCString()); return error; } @@ -609,10 +601,10 @@ Status NativeProcessDarwin::StartExceptionThread() { ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this); error.SetError(pthread_err, eErrorTypePOSIX); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to create Mach " - "exception-handling thread: %u (%s)", - __FUNCTION__, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to create Mach " + "exception-handling thread: %u (%s)", + __FUNCTION__, error.GetError(), error.AsCString()); } return error; @@ -677,10 +669,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex); - if (log) - log->Printf("NativeProcessDarwin::%s(): processing %lu exception " - "messages.", - __FUNCTION__, m_exception_messages.size()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): processing %lu exception " + "messages.", + __FUNCTION__, m_exception_messages.size()); if (m_exception_messages.empty()) { // Not particularly useful... @@ -733,18 +725,18 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { const bool force_update = true; const task_t new_task = TaskPortForProcessID(error, force_update); if (old_task != new_task) { - if (log) - log->Printf("exec: inferior task port changed " - "from 0x%4.4x to 0x%4.4x", - old_task, new_task); + LLDB_LOGF(log, + "exec: inferior task port changed " + "from 0x%4.4x to 0x%4.4x", + old_task, new_task); } } } else { - if (log) - log->Printf("NativeProcessDarwin::%s() warning: " - "failed to read all_image_infos." - "infoArrayCount from 0x%8.8llx", - __FUNCTION__, info_array_count_addr); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() warning: " + "failed to read all_image_infos." + "infoArrayCount from 0x%8.8llx", + __FUNCTION__, info_array_count_addr); } } else if ((m_sent_interrupt_signo != 0) && (signo == m_sent_interrupt_signo)) { @@ -756,10 +748,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { if (m_did_exec) { cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid); if (m_cpu_type != process_cpu_type) { - if (log) - log->Printf("NativeProcessDarwin::%s(): arch changed from " - "0x%8.8x to 0x%8.8x", - __FUNCTION__, m_cpu_type, process_cpu_type); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): arch changed from " + "0x%8.8x to 0x%8.8x", + __FUNCTION__, m_cpu_type, process_cpu_type); m_cpu_type = process_cpu_type; // TODO figure out if we need to do something here. // DNBArchProtocol::SetArchitecture (process_cpu_type); @@ -772,10 +764,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { if (m_sent_interrupt_signo != 0) { if (received_interrupt) { - if (log) - log->Printf("NativeProcessDarwin::%s(): process " - "successfully interrupted with signal %i", - __FUNCTION__, m_sent_interrupt_signo); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): process " + "successfully interrupted with signal %i", + __FUNCTION__, m_sent_interrupt_signo); // Mark that we received the interrupt signal m_sent_interrupt_signo = 0; @@ -792,19 +784,19 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { // Only auto_resume if we stopped with _only_ the interrupt signal. if (num_task_exceptions == 1) { auto_resume = true; - if (log) - log->Printf("NativeProcessDarwin::%s(): auto " - "resuming due to unhandled interrupt " - "signal %i", - __FUNCTION__, m_auto_resume_signo); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): auto " + "resuming due to unhandled interrupt " + "signal %i", + __FUNCTION__, m_auto_resume_signo); } m_auto_resume_signo = 0; } } else { - if (log) - log->Printf("NativeProcessDarwin::%s(): didn't get signal " - "%i after MachProcess::Interrupt()", - __FUNCTION__, m_sent_interrupt_signo); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): didn't get signal " + "%i after MachProcess::Interrupt()", + __FUNCTION__, m_sent_interrupt_signo); } } } @@ -878,10 +870,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) { const bool child_inherits = false; error = m_waitpid_pipe.CreateNew(child_inherits); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to create waitpid " - "communication pipe: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to create waitpid " + "communication pipe: %s", + __FUNCTION__, error.AsCString()); return error; } @@ -889,8 +881,8 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) { // TODO make PipePOSIX derive from IOObject. This is goofy here. const bool transfer_ownership = false; - auto io_sp = IOObjectSP( - new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership)); + auto io_sp = IOObjectSP(new NativeFile(m_waitpid_pipe.GetReadFileDescriptor(), + transfer_ownership)); m_waitpid_reader_handle = main_loop.RegisterReadObject( io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error); @@ -899,10 +891,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) { ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this); error.SetError(pthread_err, eErrorTypePOSIX); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to create waitpid " - "handling thread: %u (%s)", - __FUNCTION__, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to create waitpid " + "handling thread: %u (%s)", + __FUNCTION__, error.GetError(), error.AsCString()); return error; } @@ -912,10 +904,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) { void *NativeProcessDarwin::WaitpidThread(void *arg) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); if (!arg) { - if (log) - log->Printf("NativeProcessDarwin::%s(): cannot run waitpid " - "thread, mandatory process arg was null", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): cannot run waitpid " + "thread, mandatory process arg was null", + __FUNCTION__); return nullptr; } @@ -938,10 +930,10 @@ void *NativeProcessDarwin::DoWaitpidThread() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); if (m_pid == LLDB_INVALID_PROCESS_ID) { - if (log) - log->Printf("NativeProcessDarwin::%s(): inferior process ID is " - "not set, cannot waitpid on it", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): inferior process ID is " + "not set, cannot waitpid on it", + __FUNCTION__); return nullptr; } @@ -962,41 +954,41 @@ void *NativeProcessDarwin::DoWaitpidThread() { if (error.Fail()) { if (error.GetError() == EINTR) { // This is okay, we can keep going. - if (log) - log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 - ", &status, 0) interrupted, continuing", - __FUNCTION__, m_pid); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 + ", &status, 0) interrupted, continuing", + __FUNCTION__, m_pid); continue; } // This error is not okay, abort. - if (log) - log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 - ", &status, 0) aborting due to error: %u (%s)", - __FUNCTION__, m_pid, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 + ", &status, 0) aborting due to error: %u (%s)", + __FUNCTION__, m_pid, error.GetError(), error.AsCString()); break; } // Log the successful result. - if (log) - log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 - ", &status, 0) => %i, status = %i", - __FUNCTION__, m_pid, child_pid, status); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 + ", &status, 0) => %i, status = %i", + __FUNCTION__, m_pid, child_pid, status); // Handle the result. if (WIFSTOPPED(status)) { - if (log) - log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 - ") received a stop, continuing waitpid() loop", - __FUNCTION__, m_pid); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 + ") received a stop, continuing waitpid() loop", + __FUNCTION__, m_pid); continue; } else // if (WIFEXITED(status) || WIFSIGNALED(status)) { - if (log) - log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): " - "waitpid thread is setting exit status for pid = " - "%i to %i", - __FUNCTION__, m_pid, child_pid, status); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(pid = %" PRIu64 "): " + "waitpid thread is setting exit status for pid = " + "%i to %i", + __FUNCTION__, m_pid, child_pid, status); error = SendInferiorExitStatusToMainLoop(child_pid, status); return nullptr; @@ -1005,12 +997,11 @@ void *NativeProcessDarwin::DoWaitpidThread() { // We should never exit as long as our child process is alive. If we get // here, something completely unexpected went wrong and we should exit. - if (log) - log->Printf( - "NativeProcessDarwin::%s(): internal error: waitpid thread " - "exited out of its main loop in an unexpected way. pid = %" PRIu64 - ". Sending exit status of -1.", - __FUNCTION__, m_pid); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): internal error: waitpid thread " + "exited out of its main loop in an unexpected way. pid = %" PRIu64 + ". Sending exit status of -1.", + __FUNCTION__, m_pid); error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1); return nullptr; @@ -1026,11 +1017,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid, // Send the pid. error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written); if (error.Fail() || (bytes_written < sizeof(pid))) { - if (log) - log->Printf("NativeProcessDarwin::%s() - failed to write " - "waitpid exiting pid to the pipe. Client will not " - "hear about inferior exit status!", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() - failed to write " + "waitpid exiting pid to the pipe. Client will not " + "hear about inferior exit status!", + __FUNCTION__); return error; } @@ -1038,11 +1029,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid, bytes_written = 0; error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written); if (error.Fail() || (bytes_written < sizeof(status))) { - if (log) - log->Printf("NativeProcessDarwin::%s() - failed to write " - "waitpid exit result to the pipe. Client will not " - "hear about inferior exit status!", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() - failed to write " + "waitpid exit result to the pipe. Client will not " + "hear about inferior exit status!", + __FUNCTION__); } return error; } @@ -1058,11 +1049,11 @@ Status NativeProcessDarwin::HandleWaitpidResult() { size_t bytes_read = 0; error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read); if (error.Fail() || (bytes_read < sizeof(pid))) { - if (log) - log->Printf("NativeProcessDarwin::%s() - failed to read " - "waitpid exiting pid from the pipe. Will notify " - "as if parent process died with exit status -1.", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() - failed to read " + "waitpid exiting pid from the pipe. Will notify " + "as if parent process died with exit status -1.", + __FUNCTION__); SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status); return error; } @@ -1071,21 +1062,21 @@ Status NativeProcessDarwin::HandleWaitpidResult() { int status = -1; error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read); if (error.Fail() || (bytes_read < sizeof(status))) { - if (log) - log->Printf("NativeProcessDarwin::%s() - failed to read " - "waitpid exit status from the pipe. Will notify " - "as if parent process died with exit status -1.", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s() - failed to read " + "waitpid exit status from the pipe. Will notify " + "as if parent process died with exit status -1.", + __FUNCTION__); SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status); return error; } // Notify the monitor that our state has changed. - if (log) - log->Printf("NativeProcessDarwin::%s(): main loop received waitpid " - "exit status info: pid=%i (%s), status=%i", - __FUNCTION__, pid, - (pid == m_pid) ? "the inferior" : "not the inferior", status); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): main loop received waitpid " + "exit status info: pid=%i (%s), status=%i", + __FUNCTION__, pid, + (pid == m_pid) ? "the inferior" : "not the inferior", status); SetExitStatus(WaitStatus::Decode(status), notify_status); return error; @@ -1096,10 +1087,10 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error, if ((m_task == TASK_NULL) || force) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); if (m_pid == LLDB_INVALID_PROCESS_ID) { - if (log) - log->Printf("NativeProcessDarwin::%s(): cannot get task due " - "to invalid pid", - __FUNCTION__); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): cannot get task due " + "to invalid pid", + __FUNCTION__); return TASK_NULL; } @@ -1115,19 +1106,21 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error, // Succeeded. Save and return it. error.Clear(); m_task = task; - log->Printf("NativeProcessDarwin::%s(): ::task_for_pid(" - "stub_port = 0x%4.4x, pid = %llu, &task) " - "succeeded: inferior task port = 0x%4.4x", - __FUNCTION__, task_self, m_pid, m_task); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): ::task_for_pid(" + "stub_port = 0x%4.4x, pid = %llu, &task) " + "succeeded: inferior task port = 0x%4.4x", + __FUNCTION__, task_self, m_pid, m_task); return m_task; } else { // Failed to get the task for the inferior process. error.SetError(err, eErrorTypeMachKernel); if (log) { - log->Printf("NativeProcessDarwin::%s(): ::task_for_pid(" - "stub_port = 0x%4.4x, pid = %llu, &task) " - "failed, err = 0x%8.8x (%s)", - __FUNCTION__, task_self, m_pid, err, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): ::task_for_pid(" + "stub_port = 0x%4.4x, pid = %llu, &task) " + "failed, err = 0x%8.8x (%s)", + __FUNCTION__, task_self, m_pid, err, error.AsCString()); } } @@ -1156,20 +1149,21 @@ Status NativeProcessDarwin::PrivateResume() { if (log) { if (m_auto_resume_signo) - log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with " - "unhandled interrupt signal %i)...", - __FUNCTION__, m_task, m_auto_resume_signo); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): task 0x%x resuming (with " + "unhandled interrupt signal %i)...", + __FUNCTION__, m_task, m_auto_resume_signo); else - log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...", - __FUNCTION__, m_task); + LLDB_LOGF(log, "NativeProcessDarwin::%s(): task 0x%x resuming...", + __FUNCTION__, m_task); } error = ReplyToAllExceptions(); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): aborting, failed to " - "reply to exceptions: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): aborting, failed to " + "reply to exceptions: %s", + __FUNCTION__, error.AsCString()); return error; } // bool stepOverBreakInstruction = step; @@ -1196,9 +1190,8 @@ Status NativeProcessDarwin::ReplyToAllExceptions() { TaskPortForProcessID(error); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): no task port, aborting", - __FUNCTION__); + LLDB_LOGF(log, "NativeProcessDarwin::%s(): no task port, aborting", + __FUNCTION__); return error; } @@ -1211,9 +1204,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() { size_t index = 0; for (auto &message : m_exception_messages) { if (log) { - log->Printf("NativeProcessDarwin::%s(): replying to exception " - "%zu...", - __FUNCTION__, index++); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): replying to exception " + "%zu...", + __FUNCTION__, index++); } int thread_reply_signal = 0; @@ -1234,9 +1228,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() { if (error.Fail() && log) { // We log any error here, but we don't stop the exception response // handling. - log->Printf("NativeProcessDarwin::%s(): failed to reply to " - "exception: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to reply to " + "exception: %s", + __FUNCTION__, error.AsCString()); error.Clear(); } } @@ -1253,10 +1248,10 @@ Status NativeProcessDarwin::ResumeTask() { TaskPortForProcessID(error); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to get task port " - "for process when attempting to resume: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to get task port " + "for process when attempting to resume: %s", + __FUNCTION__, error.AsCString()); return error; } if (m_task == TASK_NULL) { @@ -1265,20 +1260,20 @@ Status NativeProcessDarwin::ResumeTask() { return error; } - if (log) - log->Printf("NativeProcessDarwin::%s(): requesting resume of task " - "0x%4.4x", - __FUNCTION__, m_task); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): requesting resume of task " + "0x%4.4x", + __FUNCTION__, m_task); // Get the BasicInfo struct to verify that we're suspended before we try to // resume the task. struct task_basic_info task_info; error = GetTaskBasicInfo(m_task, &task_info); if (error.Fail()) { - if (log) - log->Printf("NativeProcessDarwin::%s(): failed to get task " - "BasicInfo when attempting to resume: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): failed to get task " + "BasicInfo when attempting to resume: %s", + __FUNCTION__, error.AsCString()); return error; } @@ -1289,16 +1284,16 @@ Status NativeProcessDarwin::ResumeTask() { error.SetError(mach_err, eErrorTypeMachKernel); if (log) { if (error.Success()) - log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task); + LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x): success", m_task); else - log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task, - error.AsCString()); + LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x) error: %s", m_task, + error.AsCString()); } } else { - if (log) - log->Printf("::task_resume(target_task = 0x%4.4x): ignored, " - "already running", - m_task); + LLDB_LOGF(log, + "::task_resume(target_task = 0x%4.4x): ignored, " + "already running", + m_task); } return error; @@ -1353,11 +1348,11 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task, auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count); error.SetError(err, eErrorTypeMachKernel); if (error.Fail()) { - if (log) - log->Printf("::task_info(target_task = 0x%4.4x, " - "flavor = TASK_BASIC_INFO, task_info_out => %p, " - "task_info_outCnt => %u) failed: %u (%s)", - m_task, info, count, error.GetError(), error.AsCString()); + LLDB_LOGF(log, + "::task_info(target_task = 0x%4.4x, " + "flavor = TASK_BASIC_INFO, task_info_out => %p, " + "task_info_outCnt => %u) failed: %u (%s)", + m_task, info, count, error.GetError(), error.AsCString()); return error; } @@ -1368,11 +1363,12 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task, (float)info->user_time.microseconds / 1000000.0f; float system = (float)info->user_time.seconds + (float)info->user_time.microseconds / 1000000.0f; - verbose_log->Printf("task_basic_info = { suspend_count = %i, " - "virtual_size = 0x%8.8llx, resident_size = " - "0x%8.8llx, user_time = %f, system_time = %f }", - info->suspend_count, (uint64_t)info->virtual_size, - (uint64_t)info->resident_size, user, system); + verbose_LLDB_LOGF(log, + "task_basic_info = { suspend_count = %i, " + "virtual_size = 0x%8.8llx, resident_size = " + "0x%8.8llx, user_time = %f, system_time = %f }", + info->suspend_count, (uint64_t)info->virtual_size, + (uint64_t)info->resident_size, user, system); } return error; } @@ -1383,16 +1379,15 @@ Status NativeProcessDarwin::SuspendTask() { if (m_task == TASK_NULL) { error.SetErrorString("task port is null, cannot suspend task"); - if (log) - log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__, - error.AsCString()); + LLDB_LOGF(log, "NativeProcessDarwin::%s() failed: %s", __FUNCTION__, + error.AsCString()); return error; } auto mach_err = ::task_suspend(m_task); error.SetError(mach_err, eErrorTypeMachKernel); if (error.Fail() && log) - log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task); + LLDB_LOGF(log, "::task_suspend(target_task = 0x%4.4x)", m_task); return error; } @@ -1401,8 +1396,7 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) { Status error; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__); + LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__); if (CanResume()) { m_thread_actions = resume_actions; @@ -1412,10 +1406,10 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) { auto state = GetState(); if (state == eStateRunning) { - if (log) - log->Printf("NativeProcessDarwin::%s(): task 0x%x is already " - "running, ignoring...", - __FUNCTION__, TaskPortForProcessID(error)); + LLDB_LOGF(log, + "NativeProcessDarwin::%s(): task 0x%x is already " + "running, ignoring...", + __FUNCTION__, TaskPortForProcessID(error)); return error; } diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp index 89de92a6df4d1..1faa5b219cbc2 100644 --- a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp +++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp @@ -301,10 +301,10 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); std::lock_guard<std::recursive_mutex> locker(m_threads_mutex); - if (log) - log->Printf("NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = " - "%u) process stop count = %u", - __FUNCTION__, process.GetID(), update, process.GetStopID()); + LLDB_LOGF(log, + "NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = " + "%u) process stop count = %u", + __FUNCTION__, process.GetID(), update, process.GetStopID()); if (process.GetStopID() == 0) { // On our first stop, we'll record details like 32/64 bitness and select @@ -346,11 +346,11 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process, auto mach_err = ::task_threads(task, &thread_list, &thread_list_count); error.SetError(mach_err, eErrorTypeMachKernel); if (error.Fail()) { - if (log) - log->Printf("::task_threads(task = 0x%4.4x, thread_list => %p, " - "thread_list_count => %u) failed: %u (%s)", - task, thread_list, thread_list_count, error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "::task_threads(task = 0x%4.4x, thread_list => %p, " + "thread_list_count => %u) failed: %u (%s)", + task, thread_list, thread_list_count, error.GetError(), + error.AsCString()); return 0; } diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 749835531279b..0a49f96f54a11 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -288,9 +288,8 @@ void FreeBSDThread::DidStop() { void FreeBSDThread::WillResume(lldb::StateType resume_state) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); - if (log) - log->Printf("tid %lu resume_state = %s", GetID(), - lldb_private::StateAsCString(resume_state)); + LLDB_LOGF(log, "tid %lu resume_state = %s", GetID(), + lldb_private::StateAsCString(resume_state)); ProcessSP process_sp(GetProcess()); ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get()); int signo = GetResumeSignal(); @@ -322,9 +321,8 @@ bool FreeBSDThread::Resume() { bool status; Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); - if (log) - log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__, - StateAsCString(resume_state)); + LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__, + StateAsCString(resume_state)); switch (resume_state) { default: @@ -352,9 +350,8 @@ bool FreeBSDThread::Resume() { void FreeBSDThread::Notify(const ProcessMessage &message) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); - if (log) - log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64, - __FUNCTION__, message.PrintKind(), GetID()); + LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64, + __FUNCTION__, message.PrintKind(), GetID()); switch (message.GetKind()) { default: @@ -457,8 +454,7 @@ void FreeBSDThread::BreakNotify(const ProcessMessage &message) { // corresponding to our current PC. assert(GetRegisterContext()); lldb::addr_t pc = GetRegisterContext()->GetPC(); - if (log) - log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); + LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); lldb::BreakpointSiteSP bp_site( GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); @@ -490,10 +486,9 @@ void FreeBSDThread::WatchNotify(const ProcessMessage &message) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); lldb::addr_t halt_addr = message.GetHWAddress(); - if (log) - log->Printf( - "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64, - __FUNCTION__, halt_addr); + LLDB_LOGF(log, + "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64, + __FUNCTION__, halt_addr); POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol(); if (reg_ctx) { @@ -527,8 +522,7 @@ void FreeBSDThread::TraceNotify(const ProcessMessage &message) { // Try to resolve the breakpoint object corresponding to the current PC. assert(GetRegisterContext()); lldb::addr_t pc = GetRegisterContext()->GetPC(); - if (log) - log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); + LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); lldb::BreakpointSiteSP bp_site( GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index 770794569f729..32e3320150f83 100644 --- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -154,9 +154,8 @@ Status ProcessFreeBSD::DoResume() { do_step = true; } - if (log) - log->Printf("process %" PRIu64 " resuming (%s)", GetID(), - do_step ? "step" : "continue"); + LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(), + do_step ? "step" : "continue"); if (do_step && !software_single_step) m_monitor->SingleStep(GetID(), m_resume_signo); else @@ -168,9 +167,8 @@ Status ProcessFreeBSD::DoResume() { bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); - if (log) - log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, - GetID()); + LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, + GetID()); std::vector<lldb::pid_t> tds; if (!GetMonitor().GetCurrentThreadIDs(tds)) { @@ -183,20 +181,18 @@ bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false)); if (!thread_sp) { thread_sp.reset(new FreeBSDThread(*this, tid)); - if (log) - log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid); + LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, + tid); } else { - if (log) - log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, - tid); + LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, + tid); } new_thread_list.AddThread(thread_sp); } for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) { ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); if (old_thread_sp) { - if (log) - log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__); + LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__); } } @@ -698,14 +694,13 @@ Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) { user_id_t watchID = wp->GetID(); addr_t addr = wp->GetLoadAddress(); Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); - if (log) - log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")", - watchID); + LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")", + watchID); if (wp->IsEnabled()) { - if (log) - log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", - watchID, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 + ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", + watchID, (uint64_t)addr); return error; } @@ -753,14 +748,13 @@ Status ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) { user_id_t watchID = wp->GetID(); addr_t addr = wp->GetLoadAddress(); Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); - if (log) - log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")", - watchID); + LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")", + watchID); if (!wp->IsEnabled()) { - if (log) - log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", - watchID, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 + ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", + watchID, (uint64_t)addr); // This is needed (for now) to keep watchpoints disabled correctly wp->SetEnabled(false, notify); return error; @@ -970,8 +964,9 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, 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); + LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr); + LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, + addr); } // Validate the address. @@ -982,11 +977,10 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, 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"); + sw_step_break->SetBreakpointKind("software-single-step"); - if (log) - log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS", - __FUNCTION__, addr); + LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS", + __FUNCTION__, addr); m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()}); return Status(); diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 4b9225db5e390..ff3fb0a75e2d0 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -37,9 +37,6 @@ using namespace lldb; using namespace lldb_private; -// We disable the tracing of ptrace calls for integration builds to avoid the -// additional indirection and checks. -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION // Wrapper for ptrace to catch errors and log calls. const char *Get_PT_IO_OP(int op) { @@ -66,13 +63,14 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); if (log) { - log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d", - reqName, pid, addr, data, file, line); + LLDB_LOGF(log, + "ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d", + reqName, pid, addr, data, file, line); if (req == PT_IO) { struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr; - log->Printf("PT_IO: op=%s offs=%zx size=%zu", Get_PT_IO_OP(pi->piod_op), - (size_t)pi->piod_offs, pi->piod_len); + LLDB_LOGF(log, "PT_IO: op=%s offs=%zx size=%zu", + Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len); } } @@ -101,7 +99,7 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, default: str = "<unknown>"; } - log->Printf("ptrace() failed; errno=%d (%s)", errno, str); + LLDB_LOGF(log, "ptrace() failed; errno=%d (%s)", errno, str); } if (log) { @@ -109,15 +107,15 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, if (req == PT_GETREGS) { struct reg *r = (struct reg *)addr; - log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx", - r->r_rip, r->r_rsp, r->r_rbp, r->r_rax); + LLDB_LOGF(log, "PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx", + r->r_rip, r->r_rsp, r->r_rbp, r->r_rax); } if (req == PT_GETDBREGS || req == PT_SETDBREGS) { struct dbreg *r = (struct dbreg *)addr; char setget = (req == PT_GETDBREGS) ? 'G' : 'S'; for (int i = 0; i <= 7; i++) - log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]); + LLDB_LOGF(log, "PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]); } #endif } @@ -136,9 +134,6 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) { #define PTRACE(req, pid, addr, data) \ PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__) -#else -PtraceWrapper((req), (pid), (addr), (data)) -#endif // Static implementations of ProcessMonitor::ReadMemory and // ProcessMonitor::WriteMemory. This enables mutual recursion between these @@ -708,7 +703,7 @@ ProcessMonitor::ProcessMonitor( const lldb_private::ProcessLaunchInfo & /* launch_info */, lldb_private::Status &error) : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) { + m_operation_thread(), m_monitor_thread(), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) { using namespace std::placeholders; std::unique_ptr<LaunchArgs> args( @@ -735,20 +730,22 @@ ProcessMonitor::ProcessMonitor( } // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( + llvm::Expected<lldb_private::HostThread> monitor_thread = + Host::StartMonitoringChildProcess( std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true); - if (!m_monitor_thread->IsJoinable()) { + if (!monitor_thread || !monitor_thread->IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process launch failed."); return; } + m_monitor_thread = *monitor_thread; } ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid, lldb_private::Status &error) : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(pid), m_terminal_fd(-1), m_operation(0) { + m_operation_thread(), m_monitor_thread(), m_pid(pid), m_terminal_fd(-1), m_operation(0) { using namespace std::placeholders; sem_init(&m_operation_pending, 0, 0); @@ -773,14 +770,16 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid, } // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( + llvm::Expected<lldb_private::HostThread> monitor_thread = + Host::StartMonitoringChildProcess( std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true); - if (!m_monitor_thread->IsJoinable()) { + if (!monitor_thread || !monitor_thread->IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process attach failed."); return; } + m_monitor_thread = *monitor_thread; } ProcessMonitor::~ProcessMonitor() { StopMonitor(); } @@ -789,13 +788,15 @@ ProcessMonitor::~ProcessMonitor() { StopMonitor(); } void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Status &error) { static const char *g_thread_name = "lldb.process.freebsd.operation"; - if (m_operation_thread->IsJoinable()) + if (m_operation_thread && m_operation_thread->IsJoinable()) return; - m_operation_thread = - ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args); - if (!m_operation_thread) - error = m_operation_thread.takeError(); + llvm::Expected<lldb_private::HostThread> operation_thread = + ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args); + if (operation_thread) + m_operation_thread = *operation_thread; + else + error = operation_thread.takeError(); } void *ProcessMonitor::LaunchOpThread(void *arg) { @@ -957,14 +958,15 @@ void ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Status &error) { static const char *g_thread_name = "lldb.process.freebsd.operation"; - if (m_operation_thread->IsJoinable()) + if (m_operation_thread && m_operation_thread->IsJoinable()) return; - m_operation_thread = - ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args); - - if (!m_operation_thread) - error = m_operation_thread.takeError(); + llvm::Expected<lldb_private::HostThread> operation_thread = + ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args); + if (operation_thread) + m_operation_thread = *operation_thread; + else + error = operation_thread.takeError(); } void *ProcessMonitor::AttachOpThread(void *arg) { @@ -1037,9 +1039,8 @@ bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); if (exited) { - if (log) - log->Printf("ProcessMonitor::%s() got exit signal, tid = %" PRIu64, - __FUNCTION__, pid); + LLDB_LOGF(log, "ProcessMonitor::%s() got exit signal, tid = %" PRIu64, + __FUNCTION__, pid); message = ProcessMessage::Exit(pid, status); process->SendMessage(message); return pid == process->GetID(); @@ -1087,10 +1088,10 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, unsigned long data = 0; if (!monitor->GetEventMessage(tid, &data)) data = -1; - if (log) - log->Printf("ProcessMonitor::%s() received exit? event, data = %lx, tid " - "= %" PRIu64, - __FUNCTION__, data, tid); + LLDB_LOGF(log, + "ProcessMonitor::%s() received exit? event, data = %lx, tid " + "= %" PRIu64, + __FUNCTION__, data, tid); message = ProcessMessage::Limbo(tid, (data >> 8)); break; } @@ -1101,26 +1102,25 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, // Map TRAP_CAP to a trace trap in the absense of a more specific handler. case TRAP_CAP: #endif - if (log) - log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64 - " : si_code = %d", - __FUNCTION__, tid, info->si_code); + LLDB_LOGF(log, + "ProcessMonitor::%s() received trace event, tid = %" PRIu64 + " : si_code = %d", + __FUNCTION__, tid, info->si_code); message = ProcessMessage::Trace(tid); break; case SI_KERNEL: case TRAP_BRKPT: if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) { - if (log) - log->Printf("ProcessMonitor::%s() received sw single step breakpoint " - "event, tid = %" PRIu64, - __FUNCTION__, tid); + LLDB_LOGF(log, + "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); + LLDB_LOGF( + log, "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, + __FUNCTION__, tid); message = ProcessMessage::Break(tid); } break; @@ -1146,22 +1146,19 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, // // Similarly, ACK signals generated by this monitor. if (info->si_code == SI_USER) { - if (log) - log->Printf( - "ProcessMonitor::%s() received signal %s with code %s, pid = %d", - __FUNCTION__, - monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo), - "SI_USER", info->si_pid); + LLDB_LOGF(log, + "ProcessMonitor::%s() received signal %s with code %s, pid = %d", + __FUNCTION__, + monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo), + "SI_USER", info->si_pid); if (info->si_pid == getpid()) return ProcessMessage::SignalDelivered(tid, signo); else return ProcessMessage::Signal(tid, signo); } - if (log) - log->Printf( - "ProcessMonitor::%s() received signal %s", __FUNCTION__, - monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo)); + LLDB_LOGF(log, "ProcessMonitor::%s() received signal %s", __FUNCTION__, + monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo)); switch (signo) { case SIGSEGV: @@ -1313,14 +1310,14 @@ bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) { m_process->GetUnixSignals()->GetSignalAsCString(signo); if (signame == nullptr) signame = "<none>"; - log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s", - __FUNCTION__, GetPID(), signame); + LLDB_LOGF(log, + "ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s", + __FUNCTION__, GetPID(), signame); } ResumeOperation op(signo, result); DoOperation(&op); - if (log) - log->Printf("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, - result ? "true" : "false"); + LLDB_LOGF(log, "ProcessMonitor::%s() resuming result = %s", __FUNCTION__, + result ? "true" : "false"); return result; } @@ -1384,7 +1381,7 @@ bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, } void ProcessMonitor::StopMonitoringChildProcess() { - if (m_monitor_thread->IsJoinable()) { + if (m_monitor_thread && m_monitor_thread->IsJoinable()) { m_monitor_thread->Cancel(); m_monitor_thread->Join(nullptr); m_monitor_thread->Reset(); @@ -1422,10 +1419,9 @@ void ProcessMonitor::StopMonitor() { bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; } void ProcessMonitor::StopOpThread() { - if (!m_operation_thread->IsJoinable()) - return; - - m_operation_thread->Cancel(); - m_operation_thread->Join(nullptr); - m_operation_thread->Reset(); + if (m_operation_thread && m_operation_thread->IsJoinable()) { + m_operation_thread->Cancel(); + m_operation_thread->Join(nullptr); + m_operation_thread->Reset(); + } } diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 2adcc449c5c63..c5edfc0be95aa 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -183,8 +183,8 @@ public: private: ProcessFreeBSD *m_process; - llvm::Expected<lldb_private::HostThread> m_operation_thread; - llvm::Expected<lldb_private::HostThread> m_monitor_thread; + llvm::Optional<lldb_private::HostThread> m_operation_thread; + llvm::Optional<lldb_private::HostThread> m_monitor_thread; lldb::pid_t m_pid; int m_terminal_fd; diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 32d20d2b1215d..8b6f9fbc33c34 100644 --- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -140,7 +140,7 @@ NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, MainLoop &mainloop) - : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) { + : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) { if (m_terminal_fd != -1) { Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); assert(status.Success()); @@ -195,6 +195,7 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) { SIGSTOP, &info.psi_siginfo); } } + SetState(StateType::eStateStopped, true); } } @@ -339,12 +340,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { } Status error; + int signal = + action->signal != LLDB_INVALID_SIGNAL_NUMBER ? action->signal : 0; switch (action->state) { case eStateRunning: { // Run the thread, possibly feeding it the signal. error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1, - action->signal); + signal); if (!error.Success()) return error; for (const auto &thread : m_threads) @@ -355,7 +358,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { case eStateStepping: // Run the thread, possibly feeding it the signal. error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1, - action->signal); + signal); if (!error.Success()) return error; for (const auto &thread : m_threads) @@ -658,7 +661,7 @@ NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) { if (m_threads.empty()) SetCurrentThreadID(thread_id); - m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id)); + m_threads.push_back(std::make_unique<NativeThreadNetBSD>(*this, thread_id)); return static_cast<NativeThreadNetBSD &>(*m_threads.back()); } diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index e85ca3b7a9250..4e7f0a1c13ab1 100644 --- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -9,12 +9,12 @@ #ifndef liblldb_NativeProcessNetBSD_H_ #define liblldb_NativeProcessNetBSD_H_ +#include "Plugins/Process/POSIX/NativeProcessELF.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" #include "NativeThreadNetBSD.h" -#include "lldb/Host/common/NativeProcessProtocol.h" namespace lldb_private { namespace process_netbsd { @@ -25,7 +25,7 @@ namespace process_netbsd { /// for debugging. /// /// Changes in the inferior process state are broadcasted. -class NativeProcessNetBSD : public NativeProcessProtocol { +class NativeProcessNetBSD : public NativeProcessELF { public: class Factory : public NativeProcessProtocol::Factory { public: diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index a7cd637bf826b..6cc2810fa235d 100644 --- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -906,8 +906,8 @@ uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint( return wp_index; } if (error.Fail() && log) { - log->Printf("NativeRegisterContextNetBSD_x86_64::%s Error: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s", + __FUNCTION__, error.AsCString()); } } return LLDB_INVALID_INDEX32; diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp index 70c2687e3b8c0..9678e48436e7d 100644 --- a/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/source/Plugins/Process/POSIX/CrashReason.cpp @@ -229,11 +229,6 @@ std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { } const char *CrashReasonAsString(CrashReason reason) { -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in ascii for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else const char *str = nullptr; switch (reason) { @@ -315,8 +310,6 @@ const char *CrashReasonAsString(CrashReason reason) { str = "eFloatSubscriptRange"; break; } -#endif - return str; } diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/source/Plugins/Process/POSIX/NativeProcessELF.cpp index 559b16c8fd692..058dc5ae23382 100644 --- a/source/Plugins/Process/POSIX/NativeProcessELF.cpp +++ b/source/Plugins/Process/POSIX/NativeProcessELF.cpp @@ -21,7 +21,7 @@ NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) { DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(), buffer_or_error.get()->getBufferSize(), GetByteOrder(), GetAddressByteSize()); - m_aux_vector = llvm::make_unique<AuxVector>(auxv_data); + m_aux_vector = std::make_unique<AuxVector>(auxv_data); } return m_aux_vector->GetAuxValue(type); @@ -107,4 +107,72 @@ lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() { return LLDB_INVALID_ADDRESS; } -} // namespace lldb_private
\ No newline at end of file +template <typename T> +llvm::Expected<SVR4LibraryInfo> +NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) { + ELFLinkMap<T> link_map; + size_t bytes_read; + auto error = + ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read); + if (!error.Success()) + return error.ToError(); + + char name_buffer[PATH_MAX]; + llvm::Expected<llvm::StringRef> string_or_error = ReadCStringFromMemory( + link_map.l_name, &name_buffer[0], sizeof(name_buffer), bytes_read); + if (!string_or_error) + return string_or_error.takeError(); + + SVR4LibraryInfo info; + info.name = string_or_error->str(); + info.link_map = link_map_addr; + info.base_addr = link_map.l_addr; + info.ld_addr = link_map.l_ld; + info.next = link_map.l_next; + + return info; +} + +llvm::Expected<std::vector<SVR4LibraryInfo>> +NativeProcessELF::GetLoadedSVR4Libraries() { + // Address of DT_DEBUG.d_ptr which points to r_debug + lldb::addr_t info_address = GetSharedLibraryInfoAddress(); + if (info_address == LLDB_INVALID_ADDRESS) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid shared library info address"); + // Address of r_debug + lldb::addr_t address = 0; + size_t bytes_read; + auto status = + ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read); + if (!status.Success()) + return status.ToError(); + if (address == 0) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid r_debug address"); + // Read r_debug.r_map + lldb::addr_t link_map = 0; + status = ReadMemory(address + GetAddressByteSize(), &link_map, + GetAddressByteSize(), bytes_read); + if (!status.Success()) + return status.ToError(); + if (address == 0) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid link_map address"); + + std::vector<SVR4LibraryInfo> library_list; + while (link_map) { + llvm::Expected<SVR4LibraryInfo> info = + GetAddressByteSize() == 8 ? ReadSVR4LibraryInfo<uint64_t>(link_map) + : ReadSVR4LibraryInfo<uint32_t>(link_map); + if (!info) + return info.takeError(); + if (!info->name.empty() && info->base_addr != 0) + library_list.push_back(*info); + link_map = info->next; + } + + return library_list; +} + +} // namespace lldb_private diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.h b/source/Plugins/Process/POSIX/NativeProcessELF.h index 84dc8d08a3406..4fb513baebf08 100644 --- a/source/Plugins/Process/POSIX/NativeProcessELF.h +++ b/source/Plugins/Process/POSIX/NativeProcessELF.h @@ -37,6 +37,13 @@ protected: template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN> lldb::addr_t GetELFImageInfoAddress(); + llvm::Expected<std::vector<SVR4LibraryInfo>> + GetLoadedSVR4Libraries() override; + + template <typename T> + llvm::Expected<SVR4LibraryInfo> + ReadSVR4LibraryInfo(lldb::addr_t link_map_addr); + std::unique_ptr<AuxVector> m_aux_vector; llvm::Optional<lldb::addr_t> m_shared_library_info_addr; }; diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp index aa8449131a689..66286dd3d9e36 100644 --- a/source/Plugins/Process/POSIX/ProcessMessage.cpp +++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp @@ -15,11 +15,6 @@ const char *ProcessMessage::PrintCrashReason() const { } const char *ProcessMessage::PrintKind(Kind kind) { -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in ascii for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else const char *str = nullptr; switch (kind) { @@ -60,8 +55,6 @@ const char *ProcessMessage::PrintKind(Kind kind) { str = "eExecMessage"; break; } -#endif - return str; } diff --git a/source/Plugins/Process/Utility/AuxVector.cpp b/source/Plugins/Process/Utility/AuxVector.cpp index aab164ff93a64..25a1d0b5af060 100644 --- a/source/Plugins/Process/Utility/AuxVector.cpp +++ b/source/Plugins/Process/Utility/AuxVector.cpp @@ -43,9 +43,9 @@ void AuxVector::DumpToLog(lldb_private::Log *log) const { log->PutCString("AuxVector: "); for (auto entry : m_auxv_entries) { - log->Printf(" %s [%" PRIu64 "]: %" PRIx64, - GetEntryName(static_cast<EntryType>(entry.first)), entry.first, - entry.second); + LLDB_LOGF(log, " %s [%" PRIu64 "]: %" PRIx64, + GetEntryName(static_cast<EntryType>(entry.first)), entry.first, + entry.second); } } diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 1afe4d920599d..a86880af22600 100644 --- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -137,76 +137,67 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, // ends at static RegularExpression g_bitfield_regex( llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]")); - RegularExpression::Match regex_match(3); - if (g_bitfield_regex.Execute(slice_str, ®ex_match)) { - llvm::StringRef reg_name_str; - std::string msbit_str; - std::string lsbit_str; - if (regex_match.GetMatchAtIndex(slice_str, 1, reg_name_str) && - regex_match.GetMatchAtIndex(slice_str, 2, msbit_str) && - regex_match.GetMatchAtIndex(slice_str, 3, lsbit_str)) { - const uint32_t msbit = - StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); - const uint32_t lsbit = - StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); - if (msbit != UINT32_MAX && lsbit != UINT32_MAX) { - if (msbit > lsbit) { - const uint32_t msbyte = msbit / 8; - const uint32_t lsbyte = lsbit / 8; - - ConstString containing_reg_name(reg_name_str); - - const RegisterInfo *containing_reg_info = - GetRegisterInfo(containing_reg_name); - if (containing_reg_info) { - const uint32_t max_bit = containing_reg_info->byte_size * 8; - if (msbit < max_bit && lsbit < max_bit) { - m_invalidate_regs_map[containing_reg_info - ->kinds[eRegisterKindLLDB]] - .push_back(i); - m_value_regs_map[i].push_back( - containing_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[i].push_back( - containing_reg_info->kinds[eRegisterKindLLDB]); - - if (byte_order == eByteOrderLittle) { - success = true; - reg_info.byte_offset = - containing_reg_info->byte_offset + lsbyte; - } else if (byte_order == eByteOrderBig) { - success = true; - reg_info.byte_offset = - containing_reg_info->byte_offset + msbyte; - } else { - llvm_unreachable("Invalid byte order"); - } + llvm::SmallVector<llvm::StringRef, 4> matches; + if (g_bitfield_regex.Execute(slice_str, &matches)) { + std::string reg_name_str = matches[1].str(); + std::string msbit_str = matches[2].str(); + std::string lsbit_str = matches[3].str(); + const uint32_t msbit = + StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); + const uint32_t lsbit = + StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); + if (msbit != UINT32_MAX && lsbit != UINT32_MAX) { + if (msbit > lsbit) { + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + ConstString containing_reg_name(reg_name_str); + + const RegisterInfo *containing_reg_info = + GetRegisterInfo(containing_reg_name); + if (containing_reg_info) { + const uint32_t max_bit = containing_reg_info->byte_size * 8; + if (msbit < max_bit && lsbit < max_bit) { + m_invalidate_regs_map[containing_reg_info + ->kinds[eRegisterKindLLDB]] + .push_back(i); + m_value_regs_map[i].push_back( + containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[i].push_back( + containing_reg_info->kinds[eRegisterKindLLDB]); + + if (byte_order == eByteOrderLittle) { + success = true; + reg_info.byte_offset = + containing_reg_info->byte_offset + lsbyte; + } else if (byte_order == eByteOrderBig) { + success = true; + reg_info.byte_offset = + containing_reg_info->byte_offset + msbyte; } else { - if (msbit > max_bit) - printf("error: msbit (%u) must be less than the bitsize " - "of the register (%u)\n", - msbit, max_bit); - else - printf("error: lsbit (%u) must be less than the bitsize " - "of the register (%u)\n", - lsbit, max_bit); + llvm_unreachable("Invalid byte order"); } } else { - printf("error: invalid concrete register \"%s\"\n", - containing_reg_name.GetCString()); + if (msbit > max_bit) + printf("error: msbit (%u) must be less than the bitsize " + "of the register (%u)\n", + msbit, max_bit); + else + printf("error: lsbit (%u) must be less than the bitsize " + "of the register (%u)\n", + lsbit, max_bit); } } else { - printf("error: msbit (%u) must be greater than lsbit (%u)\n", - msbit, lsbit); + printf("error: invalid concrete register \"%s\"\n", + containing_reg_name.GetCString()); } } else { - printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, - lsbit); + printf("error: msbit (%u) must be greater than lsbit (%u)\n", + msbit, lsbit); } } else { - // TODO: print error invalid slice string that doesn't follow the - // format - printf("error: failed to extract regex matches for parsing the " - "register bitfield regex\n"); + printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, + lsbit); } } else { // TODO: print error invalid slice string that doesn't follow the @@ -545,6 +536,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { if (!generic_regs_specified) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: case llvm::Triple::aarch64_be: for (auto ® : m_regs) { if (strcmp(reg.name, "pc") == 0) diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp index 3cb5831726232..295c17e474fba 100644 --- a/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/source/Plugins/Process/Utility/HistoryThread.cpp @@ -32,17 +32,15 @@ HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, m_queue_id(LLDB_INVALID_QUEUE_ID) { m_unwinder_up.reset(new HistoryUnwind(*this, pcs)); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - if (log) - log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this)); + LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this)); } // Destructor HistoryThread::~HistoryThread() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - if (log) - log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", - static_cast<void *>(this), GetID()); + LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", + static_cast<void *>(this), GetID()); DestroyThread(); } diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp index 7d473bff8200a..83fdb011f5a1a 100644 --- a/source/Plugins/Process/Utility/HistoryUnwind.cpp +++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -51,13 +51,15 @@ HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) { } bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc) { + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) { // FIXME do not throw away the lock after we acquire it.. std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex); guard.unlock(); if (frame_idx < m_pcs.size()) { cfa = frame_idx; pc = m_pcs[frame_idx]; + behaves_like_zeroth_frame = (frame_idx == 0); return true; } return false; diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h index 6c4522e6b35b9..4d16608bd8c27 100644 --- a/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/source/Plugins/Process/Utility/HistoryUnwind.h @@ -29,7 +29,8 @@ protected: DoCreateRegisterContextForFrame(StackFrame *frame) override; bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc) override; + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) override; uint32_t DoGetFrameCount() override; private: diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 9beaf2fc7ac87..2ccbeacc49608 100644 --- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -12,7 +12,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Host/Config.h" -#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" @@ -41,13 +41,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, if (thread == nullptr) return false; - const bool append = true; const bool include_symbols = true; const bool include_inlines = false; SymbolContextList sc_list; - const uint32_t count = process->GetTarget().GetImages().FindFunctions( + process->GetTarget().GetImages().FindFunctions( ConstString("mmap"), eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); + const uint32_t count = sc_list.GetSize(); if (count > 0) { SymbolContext sc; if (sc_list.GetContextAtIndex(0, sc)) { @@ -79,17 +79,23 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, AddressRange mmap_range; if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) { - ClangASTContext *clang_ast_context = - process->GetTarget().GetScratchClangASTContext(); - CompilerType clang_void_ptr_type = - clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + auto type_system_or_err = + process->GetTarget().GetScratchTypeSystemForLanguage( + eLanguageTypeC); + if (!type_system_or_err) { + llvm::consumeError(type_system_or_err.takeError()); + return false; + } + CompilerType void_ptr_type = + type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid) + .GetPointerType(); const ArchSpec arch = process->GetTarget().GetArchitecture(); MmapArgList args = process->GetTarget().GetPlatform()->GetMmapArgumentList( arch, addr, length, prot_arg, flags, fd, offset); lldb::ThreadPlanSP call_plan_sp( new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), - clang_void_ptr_type, args, options)); + void_ptr_type, args, options)); if (call_plan_sp) { DiagnosticManager diagnostics; @@ -129,13 +135,13 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, if (thread == nullptr) return false; - const bool append = true; const bool include_symbols = true; const bool include_inlines = false; SymbolContextList sc_list; - const uint32_t count = process->GetTarget().GetImages().FindFunctions( + process->GetTarget().GetImages().FindFunctions( ConstString("munmap"), eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); + const uint32_t count = sc_list.GetSize(); if (count > 0) { SymbolContext sc; if (sc_list.GetContextAtIndex(0, sc)) { @@ -178,60 +184,3 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, return false; } - -// FIXME: This has nothing to do with Posix, it is just a convenience function -// that calls a -// function of the form "void * (*)(void)". We should find a better place to -// put this. - -bool lldb_private::InferiorCall(Process *process, const Address *address, - addr_t &returned_func, bool trap_exceptions) { - Thread *thread = - process->GetThreadList().GetExpressionExecutionThread().get(); - if (thread == nullptr || address == nullptr) - return false; - - EvaluateExpressionOptions options; - options.SetStopOthers(true); - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetTryAllThreads(true); - options.SetDebug(false); - options.SetTimeout(process->GetUtilityExpressionTimeout()); - options.SetTrapExceptions(trap_exceptions); - - ClangASTContext *clang_ast_context = - process->GetTarget().GetScratchClangASTContext(); - CompilerType clang_void_ptr_type = - clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); - lldb::ThreadPlanSP call_plan_sp( - new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, - llvm::ArrayRef<addr_t>(), options)); - if (call_plan_sp) { - DiagnosticManager diagnostics; - - StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); - if (frame) { - ExecutionContext exe_ctx; - frame->CalculateExecutionContext(exe_ctx); - ExpressionResults result = - process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); - if (result == eExpressionCompleted) { - returned_func = - call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( - LLDB_INVALID_ADDRESS); - - if (process->GetAddressByteSize() == 4) { - if (returned_func == UINT32_MAX) - return false; - } else if (process->GetAddressByteSize() == 8) { - if (returned_func == UINT64_MAX) - return false; - } - return true; - } - } - } - - return false; -} diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/source/Plugins/Process/Utility/InferiorCallPOSIX.h index 04316801b351d..2008c5fe0b912 100644 --- a/source/Plugins/Process/Utility/InferiorCallPOSIX.h +++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.h @@ -30,9 +30,6 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length); -bool InferiorCall(Process *proc, const Address *address, - lldb::addr_t &returned_func, bool trap_exceptions = false); - } // namespace lldb_private #endif // lldb_InferiorCallPOSIX_h_ diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index e804a4d251f73..4ca33c248c6f8 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -1111,9 +1111,10 @@ int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) { void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) { if (log) { for (uint32_t i = 0; i < 16; i++) - log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { " - "0x%8.8x, 0x%8.8x }", - i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); + LLDB_LOGF(log, + "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { " + "0x%8.8x, 0x%8.8x }", + i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); } } @@ -1514,8 +1515,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() { // Zero is reserved for the BRP count, so don't increment it if it is zero if (g_num_supported_hw_breakpoints > 0) g_num_supported_hw_breakpoints++; - // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", - // register_DBGDIDR, g_num_supported_hw_breakpoints); } return g_num_supported_hw_breakpoints; #else @@ -1642,8 +1641,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() { uint32_t register_DBGDIDR; asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR)); g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1; - // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", - // register_DBGDIDR, g_num_supported_hw_watchpoints); } return g_num_supported_hw_watchpoints; #else @@ -1656,10 +1653,6 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) { - // if (log) log->Printf - // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size - // = %u, read = %u, write = %u)", addr, size, read, write); - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); // Can't watch zero bytes diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 85d518a487bf1..b3ec24d8905de 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -25,6 +25,11 @@ #include <memory> +#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + // Support building against older versions of LLVM, this macro was added // recently. #ifndef LLVM_EXTENSION @@ -285,10 +290,11 @@ int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) { void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) { if (log) { for (uint32_t i = 0; i < 16; i++) - log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 - " } WVR%-2u/WCR%-2u " - "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }", - i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); + LLDB_LOGF(log, + "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 + " } WVR%-2u/WCR%-2u " + "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }", + i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); } } @@ -423,7 +429,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, case fpu_v29: case fpu_v30: case fpu_v31: - value.SetBytes(fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size, + value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size, endian::InlHostByteOrder()); break; @@ -502,7 +508,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, case fpu_d31: { ProcessSP process_sp(m_thread.GetProcess()); if (process_sp.get()) { - DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(), + DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); offset_t offset = 0; value.SetDouble(regdata.GetDouble(&offset)); @@ -615,7 +621,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, case fpu_v29: case fpu_v30: case fpu_v31: - ::memcpy(fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(), + ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(), value.GetByteSize()); break; diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index 2f691c807d50b..abb87e3c23483 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -73,7 +73,7 @@ public: }; struct VReg { - llvm::AlignedCharArray<16, 16> bytes; + alignas(16) char bytes[16]; }; // mirrors <mach/arm/thread_status.h> arm_neon_state64_t diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 820d280c37f7b..873713fd83739 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -496,11 +496,11 @@ int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) { void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) { if (log) { if (title) - log->Printf("%s", title); + LLDB_LOGF(log, "%s", title); for (uint32_t i = 0; i < k_num_gpr_registers; i++) { uint32_t reg = gpr_eax + i; - log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, - (&gpr.eax)[reg]); + LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name, + (&gpr.eax)[reg]); } } } diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 62e512adc9f7f..47758ce85eb28 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -554,22 +554,6 @@ int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) { return -1; } -void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) { - if (log) { - if (format) { - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } - for (uint32_t i = 0; i < k_num_gpr_registers; i++) { - uint32_t reg = gpr_rax + i; - log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, - (&gpr.rax)[reg]); - } - } -} - int RegisterContextDarwin_x86_64::ReadGPR(bool force) { int set = GPRRegSet; if (force || !RegisterSetIsCached(set)) { diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 76646d8897d19..49a589f14989d 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -12,12 +12,14 @@ #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ArmUnwindInfo.h" +#include "lldb/Symbol/CallFrameInfo.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" @@ -150,15 +152,8 @@ void RegisterContextLLDB::InitializeZerothFrame() { UnwindLogMsg("using architectural default unwind method"); } - // We require either a symbol or function in the symbols context to be - // successfully filled in or this context is of no use to us. - const SymbolContextItem resolve_scope = - eSymbolContextFunction | eSymbolContextSymbol; - if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress( - m_current_pc, resolve_scope, m_sym_ctx) & - resolve_scope)) { - m_sym_ctx_valid = true; - } + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); if (m_sym_ctx.symbol) { UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", @@ -172,9 +167,6 @@ void RegisterContextLLDB::InitializeZerothFrame() { current_pc); } - AddressRange addr_range; - m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range); - if (IsTrapHandlerSymbol(process, m_sym_ctx)) { m_frame_type = eTrapHandlerFrame; } else { @@ -436,24 +428,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { return; } - bool resolve_tail_call_address = false; // m_current_pc can be one past the - // address range of the function... - // If the saved pc does not point to a function/symbol because it is beyond - // the bounds of the correct function and there's no symbol there, we do - // *not* want ResolveSymbolContextForAddress to back up the pc by 1, because - // then we might not find the correct unwind information later. Instead, let - // ResolveSymbolContextForAddress fail, and handle the case via - // decr_pc_and_recompute_addr_range below. - const SymbolContextItem resolve_scope = - eSymbolContextFunction | eSymbolContextSymbol; - uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress( - m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address); - - // We require either a symbol or function in the symbols context to be - // successfully filled in or this context is of no use to us. - if (resolve_scope & resolved_scope) { - m_sym_ctx_valid = true; - } + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); if (m_sym_ctx.symbol) { UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc, @@ -467,25 +443,30 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { pc); } - AddressRange addr_range; - if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) { - m_sym_ctx_valid = false; - } + bool decr_pc_and_recompute_addr_range; - bool decr_pc_and_recompute_addr_range = false; - - // If the symbol lookup failed... - if (!m_sym_ctx_valid) + if (!m_sym_ctx_valid) { + // Always decrement and recompute if the symbol lookup failed decr_pc_and_recompute_addr_range = true; - - // Or if we're in the middle of the stack (and not "above" an asynchronous - // event like sigtramp), and our "current" pc is the start of a function... - if (GetNextFrame()->m_frame_type != eTrapHandlerFrame && - GetNextFrame()->m_frame_type != eDebuggerFrame && - (!m_sym_ctx_valid || - (addr_range.GetBaseAddress().IsValid() && - addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() && - addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()))) { + } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame || + GetNextFrame()->m_frame_type == eDebuggerFrame) { + // Don't decrement if we're "above" an asynchronous event like + // sigtramp. + decr_pc_and_recompute_addr_range = false; + } else if (!addr_range.GetBaseAddress().IsValid() || + addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() || + addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) { + // If our "current" pc isn't the start of a function, no need + // to decrement and recompute. + decr_pc_and_recompute_addr_range = false; + } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) { + // Signal dispatch may set the return address of the handler it calls to + // point to the first byte of a return trampoline (like __kernel_rt_sigreturn), + // so do not decrement and recompute if the symbol we already found is a trap + // handler. + decr_pc_and_recompute_addr_range = false; + } else { + // Decrement to find the function containing the call. decr_pc_and_recompute_addr_range = true; } @@ -502,18 +483,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { Address temporary_pc; temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); m_sym_ctx.Clear(false); - m_sym_ctx_valid = false; - SymbolContextItem resolve_scope = - eSymbolContextFunction | eSymbolContextSymbol; - - ModuleSP temporary_module_sp = temporary_pc.GetModule(); - if (temporary_module_sp && - temporary_module_sp->ResolveSymbolContextForAddress( - temporary_pc, resolve_scope, m_sym_ctx) & - resolve_scope) { - if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) - m_sym_ctx_valid = true; - } + m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + UnwindLogMsg("Symbol is now %s", GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); } @@ -563,6 +534,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind(); + PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp); if (active_row.get() && log) { StreamString active_row_strm; active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, @@ -575,6 +547,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) { active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset); row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); if (active_row.get() && log) { StreamString active_row_strm; active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), @@ -812,6 +785,16 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { unwind_plan_sp.reset(); } + CallFrameInfo *object_file_unwind = + pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo(); + if (object_file_unwind) { + unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) + return unwind_plan_sp; + else + unwind_plan_sp.reset(); + } + return arch_default_unwind_plan_sp; } @@ -824,6 +807,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { m_fast_unwind_plan_sp.reset(); unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); + if (!unwind_plan_sp) + unwind_plan_sp = + func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) { return unwind_plan_sp; @@ -846,6 +832,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { // intend) or compact unwind (this won't work) unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); + if (!unwind_plan_sp) + unwind_plan_sp = + func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the " "DynamicLoader suggested we prefer it", @@ -1512,8 +1501,7 @@ RegisterContextLLDB::SavedLocationForRegister( process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; - DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0, - unwindplan_regloc.GetDWARFExpressionLength()); + DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); dwarfexpr.SetRegisterKind(unwindplan_registerkind); Value cfa_val = Scalar(m_cfa); cfa_val.SetValueType(Value::eValueTypeLoadAddress); @@ -1698,6 +1686,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { // We've copied the fallback unwind plan into the full - now clear the // fallback. m_fallback_unwind_plan_sp.reset(); + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); } return true; @@ -1741,6 +1730,8 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { m_cfa = new_cfa; + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); + UnwindLogMsg("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString()); return true; @@ -1748,6 +1739,53 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { return false; } +void RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan( + lldb::UnwindPlanSP unwind_plan) { + if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) { + // Unwind plan does not indicate trap handler. Do nothing. We may + // already be flagged as trap handler flag due to the symbol being + // in the trap handler symbol list, and that should take precedence. + return; + } else if (m_frame_type != eNormalFrame) { + // If this is already a trap handler frame, nothing to do. + // If this is a skip or debug or invalid frame, don't override that. + return; + } + + m_frame_type = eTrapHandlerFrame; + + if (m_current_offset_backed_up_one != m_current_offset) { + // We backed up the pc by 1 to compute the symbol context, but + // now need to undo that because the pc of the trap handler + // frame may in fact be the first instruction of a signal return + // trampoline, rather than the instruction after a call. This + // happens on systems where the signal handler dispatch code, rather + // than calling the handler and being returned to, jumps to the + // handler after pushing the address of a return trampoline on the + // stack -- on these systems, when the handler returns, control will + // be transferred to the return trampoline, so that's the best + // symbol we can present in the callstack. + UnwindLogMsg("Resetting current offset and re-doing symbol lookup; " + "old symbol was %s", + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + m_current_offset_backed_up_one = m_current_offset; + + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + + UnwindLogMsg("Symbol is now %s", + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + Target *target = &process->GetTarget(); + + m_start_pc = addr_range.GetBaseAddress(); + m_current_offset = + m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target); + } +} + bool RegisterContextLLDB::ReadFrameAddress( lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, addr_t &address) { @@ -1816,8 +1854,7 @@ bool RegisterContextLLDB::ReadFrameAddress( process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; - DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0, - fa.GetDWARFExpressionLength()); + DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); dwarfexpr.SetRegisterKind(row_register_kind); Value result; Status error; @@ -1833,12 +1870,66 @@ bool RegisterContextLLDB::ReadFrameAddress( error.AsCString()); break; } + case UnwindPlan::Row::FAValue::isRaSearch: { + Process &process = *m_thread.GetProcess(); + lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset()); + if (return_address_hint == LLDB_INVALID_ADDRESS) + return false; + const unsigned max_iterations = 256; + for (unsigned i = 0; i < max_iterations; ++i) { + Status st; + lldb::addr_t candidate_addr = + return_address_hint + i * process.GetAddressByteSize(); + lldb::addr_t candidate = + process.ReadPointerFromMemory(candidate_addr, st); + if (st.Fail()) { + UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr, + st.AsCString()); + return false; + } + Address addr; + uint32_t permissions; + if (process.GetLoadAddressPermissions(candidate, permissions) && + permissions & lldb::ePermissionsExecutable) { + address = candidate_addr; + UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address); + return true; + } + } + UnwindLogMsg("No suitable CFA found"); + break; + } default: return false; } return false; } +lldb::addr_t RegisterContextLLDB::GetReturnAddressHint(int32_t plan_offset) { + addr_t hint; + if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint)) + return LLDB_INVALID_ADDRESS; + if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) + return LLDB_INVALID_ADDRESS; + + hint += plan_offset; + + if (auto next = GetNextFrame()) { + if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol) + return LLDB_INVALID_ADDRESS; + if (auto expected_size = + next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize( + *next->m_sym_ctx.symbol)) + hint += *expected_size; + else { + UnwindLogMsgVerbose("Could not retrieve parameter size: %s", + llvm::toString(expected_size.takeError()).c_str()); + return LLDB_INVALID_ADDRESS; + } + } + return hint; +} + // Retrieve a general purpose register value for THIS frame, as saved by the // NEXT frame, i.e. the frame that // this frame called. e.g. @@ -2077,8 +2168,9 @@ void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) { } va_end(args); - log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100, - "", m_thread.GetIndexID(), m_frame_number, logmsg); + LLDB_LOGF(log, "%*sth%d/fr%u %s", + m_frame_number < 100 ? m_frame_number : 100, "", + m_thread.GetIndexID(), m_frame_number, logmsg); free(logmsg); } } @@ -2098,8 +2190,9 @@ void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) { } va_end(args); - log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100, - "", m_thread.GetIndexID(), m_frame_number, logmsg); + LLDB_LOGF(log, "%*sth%d/fr%u %s", + m_frame_number < 100 ? m_frame_number : 100, "", + m_thread.GetIndexID(), m_frame_number, logmsg); free(logmsg); } } diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h index 64dd394d233be..114ac35591e7e 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -120,6 +120,10 @@ private: bool IsTrapHandlerSymbol(lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const; + /// Check if the given unwind plan indicates a signal trap handler, and + /// update frame type and symbol context if so. + void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan); + // Provide a location for where THIS function saved the CALLER's register // value // Or a frame "below" this one saved it, i.e. a function called by this one, @@ -197,6 +201,8 @@ private: bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset); + lldb::addr_t GetReturnAddressHint(int32_t plan_offset); + lldb_private::Thread &m_thread; /// diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 99b897d441b59..db1aa1b8b0931 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -109,6 +109,7 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( switch (register_info->m_target_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: m_reg_info.num_registers = k_num_registers_arm64; m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; @@ -184,6 +185,7 @@ RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) { if (IsRegisterSetAvailable(set)) { switch (m_register_info_up->m_target_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: return &g_reg_sets_arm64[set]; default: assert(false && "Unhandled target architecture."); diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp new file mode 100644 index 0000000000000..916d3233cde5b --- /dev/null +++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -0,0 +1,89 @@ +//===-- RegisterContextWindows_i386.cpp -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextWindows_i386.h" +#include "RegisterContext_x86.h" +#include "lldb-x86-register-enums.h" + +using namespace lldb_private; +using namespace lldb; + +namespace { +// Declare our g_register_infos structure. +typedef struct _GPR { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t fs; + uint32_t gs; + uint32_t ss; + uint32_t ds; + uint32_t es; +} GPR; + +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +#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##_i386 }, nullptr, nullptr, \ + nullptr, 0 \ + } + +// clang-format off +static RegisterInfo g_register_infos_i386[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), +}; +// clang-format on +} // namespace + +RegisterContextWindows_i386::RegisterContextWindows_i386( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch) { + assert(target_arch.GetMachine() == llvm::Triple::x86); +} + +const RegisterInfo *RegisterContextWindows_i386::GetRegisterInfo() const { + return g_register_infos_i386; +} + +uint32_t RegisterContextWindows_i386::GetRegisterCount() const { + return llvm::array_lengthof(g_register_infos_i386); +} + +uint32_t RegisterContextWindows_i386::GetUserRegisterCount() const { + return llvm::array_lengthof(g_register_infos_i386); +} + +size_t RegisterContextWindows_i386::GetGPRSize() const { return sizeof(GPR); } diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h new file mode 100644 index 0000000000000..7779cc3575260 --- /dev/null +++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h @@ -0,0 +1,27 @@ +//===-- RegisterContextWindows_i386.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextWindows_i386_H_ +#define liblldb_RegisterContextWindows_i386_H_ + +#include "RegisterInfoInterface.h" + +class RegisterContextWindows_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextWindows_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; + + uint32_t GetUserRegisterCount() const override; +}; + +#endif diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp new file mode 100644 index 0000000000000..e90584de1a444 --- /dev/null +++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -0,0 +1,152 @@ +//===-- RegisterContextWindows_x86_64.cpp -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextWindows_x86_64.h" +#include "RegisterContext_x86.h" +#include "lldb-x86-register-enums.h" + +#include <vector> + +using namespace lldb_private; +using namespace lldb; + +namespace { +typedef struct _GPR { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + 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 rip; + uint64_t rflags; + uint16_t cs; + uint16_t fs; + uint16_t gs; + uint16_t ss; + uint16_t ds; + uint16_t es; +} GPR; + +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) +#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 \ + } + +typedef struct _FPReg { + XMMReg xmm0; + XMMReg xmm1; + XMMReg xmm2; + XMMReg xmm3; + XMMReg xmm4; + XMMReg xmm5; + XMMReg xmm6; + XMMReg xmm7; + XMMReg xmm8; + XMMReg xmm9; + XMMReg xmm10; + XMMReg xmm11; + XMMReg xmm12; + XMMReg xmm13; + XMMReg xmm14; + XMMReg xmm15; +} FPReg; + +#define FPR_OFFSET(regname) \ + (sizeof(GPR) + LLVM_EXTENSION offsetof(FPReg, regname)) + +#define DEFINE_XMM(reg) \ + { \ +#reg, NULL, sizeof(((FPReg *)nullptr)->reg), FPR_OFFSET(reg), \ + eEncodingUint, eFormatVectorOfUInt64, \ + {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ + nullptr, nullptr, nullptr, 0 \ + } + +// clang-format off +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_XMM(xmm0), + DEFINE_XMM(xmm1), + DEFINE_XMM(xmm2), + DEFINE_XMM(xmm3), + DEFINE_XMM(xmm4), + DEFINE_XMM(xmm5), + DEFINE_XMM(xmm6), + DEFINE_XMM(xmm7), + DEFINE_XMM(xmm8), + DEFINE_XMM(xmm9), + DEFINE_XMM(xmm10), + DEFINE_XMM(xmm11), + DEFINE_XMM(xmm12), + DEFINE_XMM(xmm13), + DEFINE_XMM(xmm14), + DEFINE_XMM(xmm15) +}; +// clang-format on +} // namespace + +RegisterContextWindows_x86_64::RegisterContextWindows_x86_64( + const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch) { + assert(target_arch.GetMachine() == llvm::Triple::x86_64); +} + +const RegisterInfo *RegisterContextWindows_x86_64::GetRegisterInfo() const { + return g_register_infos_x86_64; +} + +uint32_t RegisterContextWindows_x86_64::GetRegisterCount() const { + return llvm::array_lengthof(g_register_infos_x86_64); +} + +uint32_t RegisterContextWindows_x86_64::GetUserRegisterCount() const { + return llvm::array_lengthof(g_register_infos_x86_64); +} + +size_t RegisterContextWindows_x86_64::GetGPRSize() const { return sizeof(GPR); } diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h new file mode 100644 index 0000000000000..18198b5b25b30 --- /dev/null +++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h @@ -0,0 +1,28 @@ +//===-- RegisterContextWindows_x86_64.h --- ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextWindows_x86_64_H_ +#define liblldb_RegisterContextWindows_x86_64_H_ + +#include "RegisterInfoInterface.h" + +class RegisterContextWindows_x86_64 + : public lldb_private::RegisterInfoInterface { +public: + RegisterContextWindows_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; + + uint32_t GetUserRegisterCount() const override; +}; + +#endif diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index f7471526d0548..8b367bdc64489 100644 --- a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -57,6 +57,7 @@ static const lldb_private::RegisterInfo * GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: return g_register_infos_arm64_le; default: assert(false && "Unhandled target architecture."); @@ -68,6 +69,7 @@ static uint32_t GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) / sizeof(g_register_infos_arm64_le[0])); default: diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h index 4ee0b528f2290..68c12aa6e5295 100644 --- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -456,188 +456,265 @@ static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM}; static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM}; static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; +// Generates register kinds array for 64-bit general purpose registers +#define GPR64_KIND(reg, generic_kind) \ + { \ + arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \ + gpr_##reg \ + } + +// Generates register kinds array for registers with lldb kind +#define MISC_KIND(lldb_kind) \ + { \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_kind \ + } + +// Generates register kinds array for vector registers +#define VREG_KIND(reg) \ + { \ + LLDB_INVALID_REGNUM, arm64_dwarf::reg, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##reg \ + } + +// Generates register kinds array for cpsr +#define CPSR_KIND(lldb_kind) \ + { \ + arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, \ + LLDB_INVALID_REGNUM, lldb_kind \ + } + +#define MISC_GPR_KIND(lldb_kind) CPSR_KIND(lldb_kind) +#define MISC_FPU_KIND(lldb_kind) MISC_KIND(lldb_kind) +#define MISC_EXC_KIND(lldb_kind) MISC_KIND(lldb_kind) + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64(reg, generic_kind) \ + { \ + #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ + lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, 0 \ + } + +// Defines a 64-bit general purpose register +#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ + lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, 0 \ + } + +// Defines a 32-bit general purpose pseudo register +#define DEFINE_GPR32(wreg, xreg) \ + { \ + #wreg, nullptr, 4, \ + GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ + lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \ + g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \ + } + +// Defines a vector register with 16-byte size +#define DEFINE_VREG(reg) \ + { \ + #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \ + lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \ + 0 \ + } + +// Defines S and D pseudo registers mapping over correspondig vector register +#define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \ + { \ + #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ + lldb::eEncodingIEEE754, lldb::eFormatFloat, MISC_KIND(fpu_##reg), \ + g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \ + } + +// Defines miscellaneous status and control registers like cpsr, fpsr etc +#define DEFINE_MISC_REGS(reg, size, TYPE, lldb_kind) \ + { \ + #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \ + lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \ + nullptr, 0 \ + } + static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { - // clang-format off - // General purpose registers - // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ - // ===== ======= == ============= =================== ================ ================= =============== ======================== =================== ====== ============== ======= ======= == - {"x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0}, nullptr, nullptr, nullptr, 0}, - {"x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1}, nullptr, nullptr, nullptr, 0}, - {"x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2}, nullptr, nullptr, nullptr, 0}, - {"x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3}, nullptr, nullptr, nullptr, 0}, - {"x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4}, nullptr, nullptr, nullptr, 0}, - {"x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5}, nullptr, nullptr, nullptr, 0}, - {"x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6}, nullptr, nullptr, nullptr, 0}, - {"x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7}, nullptr, nullptr, nullptr, 0}, - {"x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8}, nullptr, nullptr, nullptr, 0}, - {"x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9}, nullptr, nullptr, nullptr, 0}, - {"x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10}, nullptr, nullptr, nullptr, 0}, - {"x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11}, nullptr, nullptr, nullptr, 0}, - {"x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12}, nullptr, nullptr, nullptr, 0}, - {"x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13}, nullptr, nullptr, nullptr, 0}, - {"x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14}, nullptr, nullptr, nullptr, 0}, - {"x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15}, nullptr, nullptr, nullptr, 0}, - {"x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16}, nullptr, nullptr, nullptr, 0}, - {"x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17}, nullptr, nullptr, nullptr, 0}, - {"x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18}, nullptr, nullptr, nullptr, 0}, - {"x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19}, nullptr, nullptr, nullptr, 0}, - {"x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20}, nullptr, nullptr, nullptr, 0}, - {"x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21}, nullptr, nullptr, nullptr, 0}, - {"x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22}, nullptr, nullptr, nullptr, 0}, - {"x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23}, nullptr, nullptr, nullptr, 0}, - {"x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24}, nullptr, nullptr, nullptr, 0}, - {"x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25}, nullptr, nullptr, nullptr, 0}, - {"x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26}, nullptr, nullptr, nullptr, 0}, - {"x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27}, nullptr, nullptr, nullptr, 0}, - {"x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28}, nullptr, nullptr, nullptr, 0}, - {"fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp}, nullptr, nullptr, nullptr, 0}, - {"lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr}, nullptr, nullptr, nullptr, 0}, - {"sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp}, nullptr, nullptr, nullptr, 0}, - {"pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc}, nullptr, nullptr, nullptr, 0}, - - {"cpsr",nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, nullptr, 0}, - - // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE INVALIDATES DYNEXPR SZ - // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= == - {"w0", nullptr, 4, GPR_OFFSET(0) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w0}, g_contained_x0, g_w0_invalidates, nullptr, 0}, - {"w1", nullptr, 4, GPR_OFFSET(1) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w1}, g_contained_x1, g_w1_invalidates, nullptr, 0}, - {"w2", nullptr, 4, GPR_OFFSET(2) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w2}, g_contained_x2, g_w2_invalidates, nullptr, 0}, - {"w3", nullptr, 4, GPR_OFFSET(3) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w3}, g_contained_x3, g_w3_invalidates, nullptr, 0}, - {"w4", nullptr, 4, GPR_OFFSET(4) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w4}, g_contained_x4, g_w4_invalidates, nullptr, 0}, - {"w5", nullptr, 4, GPR_OFFSET(5) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w5}, g_contained_x5, g_w5_invalidates, nullptr, 0}, - {"w6", nullptr, 4, GPR_OFFSET(6) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w6}, g_contained_x6, g_w6_invalidates, nullptr, 0}, - {"w7", nullptr, 4, GPR_OFFSET(7) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w7}, g_contained_x7, g_w7_invalidates, nullptr, 0}, - {"w8", nullptr, 4, GPR_OFFSET(8) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w8}, g_contained_x8, g_w8_invalidates, nullptr, 0}, - {"w9", nullptr, 4, GPR_OFFSET(9) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w9}, g_contained_x9, g_w9_invalidates, nullptr, 0}, - {"w10", nullptr, 4, GPR_OFFSET(10) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w10}, g_contained_x10, g_w10_invalidates, nullptr, 0}, - {"w11", nullptr, 4, GPR_OFFSET(11) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w11}, g_contained_x11, g_w11_invalidates, nullptr, 0}, - {"w12", nullptr, 4, GPR_OFFSET(12) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w12}, g_contained_x12, g_w12_invalidates, nullptr, 0}, - {"w13", nullptr, 4, GPR_OFFSET(13) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w13}, g_contained_x13, g_w13_invalidates, nullptr, 0}, - {"w14", nullptr, 4, GPR_OFFSET(14) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w14}, g_contained_x14, g_w14_invalidates, nullptr, 0}, - {"w15", nullptr, 4, GPR_OFFSET(15) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w15}, g_contained_x15, g_w15_invalidates, nullptr, 0}, - {"w16", nullptr, 4, GPR_OFFSET(16) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w16}, g_contained_x16, g_w16_invalidates, nullptr, 0}, - {"w17", nullptr, 4, GPR_OFFSET(17) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w17}, g_contained_x17, g_w17_invalidates, nullptr, 0}, - {"w18", nullptr, 4, GPR_OFFSET(18) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w18}, g_contained_x18, g_w18_invalidates, nullptr, 0}, - {"w19", nullptr, 4, GPR_OFFSET(19) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w19}, g_contained_x19, g_w19_invalidates, nullptr, 0}, - {"w20", nullptr, 4, GPR_OFFSET(20) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w20}, g_contained_x20, g_w20_invalidates, nullptr, 0}, - {"w21", nullptr, 4, GPR_OFFSET(21) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w21}, g_contained_x21, g_w21_invalidates, nullptr, 0}, - {"w22", nullptr, 4, GPR_OFFSET(22) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w22}, g_contained_x22, g_w22_invalidates, nullptr, 0}, - {"w23", nullptr, 4, GPR_OFFSET(23) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w23}, g_contained_x23, g_w23_invalidates, nullptr, 0}, - {"w24", nullptr, 4, GPR_OFFSET(24) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w24}, g_contained_x24, g_w24_invalidates, nullptr, 0}, - {"w25", nullptr, 4, GPR_OFFSET(25) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w25}, g_contained_x25, g_w25_invalidates, nullptr, 0}, - {"w26", nullptr, 4, GPR_OFFSET(26) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w26}, g_contained_x26, g_w26_invalidates, nullptr, 0}, - {"w27", nullptr, 4, GPR_OFFSET(27) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w27}, g_contained_x27, g_w27_invalidates, nullptr, 0}, - {"w28", nullptr, 4, GPR_OFFSET(28) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w28}, g_contained_x28, g_w28_invalidates, nullptr, 0}, - - // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ - // ===== ======= == ============= =================== ================ ================= =============== =================== =================== ====== ============== ======= ======= == - {"v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0}, nullptr, nullptr, nullptr, 0}, - {"v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1}, nullptr, nullptr, nullptr, 0}, - {"v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2}, nullptr, nullptr, nullptr, 0}, - {"v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3}, nullptr, nullptr, nullptr, 0}, - {"v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4}, nullptr, nullptr, nullptr, 0}, - {"v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5}, nullptr, nullptr, nullptr, 0}, - {"v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6}, nullptr, nullptr, nullptr, 0}, - {"v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7}, nullptr, nullptr, nullptr, 0}, - {"v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8}, nullptr, nullptr, nullptr, 0}, - {"v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9}, nullptr, nullptr, nullptr, 0}, - {"v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10}, nullptr, nullptr, nullptr, 0}, - {"v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11}, nullptr, nullptr, nullptr, 0}, - {"v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12}, nullptr, nullptr, nullptr, 0}, - {"v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13}, nullptr, nullptr, nullptr, 0}, - {"v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14}, nullptr, nullptr, nullptr, 0}, - {"v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15}, nullptr, nullptr, nullptr, 0}, - {"v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16}, nullptr, nullptr, nullptr, 0}, - {"v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17}, nullptr, nullptr, nullptr, 0}, - {"v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18}, nullptr, nullptr, nullptr, 0}, - {"v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19}, nullptr, nullptr, nullptr, 0}, - {"v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20}, nullptr, nullptr, nullptr, 0}, - {"v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21}, nullptr, nullptr, nullptr, 0}, - {"v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22}, nullptr, nullptr, nullptr, 0}, - {"v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23}, nullptr, nullptr, nullptr, 0}, - {"v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24}, nullptr, nullptr, nullptr, 0}, - {"v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25}, nullptr, nullptr, nullptr, 0}, - {"v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26}, nullptr, nullptr, nullptr, 0}, - {"v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27}, nullptr, nullptr, nullptr, 0}, - {"v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28}, nullptr, nullptr, nullptr, 0}, - {"v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29}, nullptr, nullptr, nullptr, 0}, - {"v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30}, nullptr, nullptr, nullptr, 0}, - {"v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31}, nullptr, nullptr, nullptr, 0}, - - // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATES DYNEXPR SZ - // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= == - {"s0", nullptr, 4, FPU_OFFSET(0) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0}, g_contained_v0, g_s0_invalidates, nullptr, 0}, - {"s1", nullptr, 4, FPU_OFFSET(1) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1}, g_contained_v1, g_s1_invalidates, nullptr, 0}, - {"s2", nullptr, 4, FPU_OFFSET(2) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2}, g_contained_v2, g_s2_invalidates, nullptr, 0}, - {"s3", nullptr, 4, FPU_OFFSET(3) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3}, g_contained_v3, g_s3_invalidates, nullptr, 0}, - {"s4", nullptr, 4, FPU_OFFSET(4) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4}, g_contained_v4, g_s4_invalidates, nullptr, 0}, - {"s5", nullptr, 4, FPU_OFFSET(5) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5}, g_contained_v5, g_s5_invalidates, nullptr, 0}, - {"s6", nullptr, 4, FPU_OFFSET(6) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6}, g_contained_v6, g_s6_invalidates, nullptr, 0}, - {"s7", nullptr, 4, FPU_OFFSET(7) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7}, g_contained_v7, g_s7_invalidates, nullptr, 0}, - {"s8", nullptr, 4, FPU_OFFSET(8) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8}, g_contained_v8, g_s8_invalidates, nullptr, 0}, - {"s9", nullptr, 4, FPU_OFFSET(9) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9}, g_contained_v9, g_s9_invalidates, nullptr, 0}, - {"s10", nullptr, 4, FPU_OFFSET(10) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10}, g_contained_v10, g_s10_invalidates, nullptr, 0}, - {"s11", nullptr, 4, FPU_OFFSET(11) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11}, g_contained_v11, g_s11_invalidates, nullptr, 0}, - {"s12", nullptr, 4, FPU_OFFSET(12) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12}, g_contained_v12, g_s12_invalidates, nullptr, 0}, - {"s13", nullptr, 4, FPU_OFFSET(13) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13}, g_contained_v13, g_s13_invalidates, nullptr, 0}, - {"s14", nullptr, 4, FPU_OFFSET(14) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14}, g_contained_v14, g_s14_invalidates, nullptr, 0}, - {"s15", nullptr, 4, FPU_OFFSET(15) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15}, g_contained_v15, g_s15_invalidates, nullptr, 0}, - {"s16", nullptr, 4, FPU_OFFSET(16) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16}, g_contained_v16, g_s16_invalidates, nullptr, 0}, - {"s17", nullptr, 4, FPU_OFFSET(17) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17}, g_contained_v17, g_s17_invalidates, nullptr, 0}, - {"s18", nullptr, 4, FPU_OFFSET(18) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18}, g_contained_v18, g_s18_invalidates, nullptr, 0}, - {"s19", nullptr, 4, FPU_OFFSET(19) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19}, g_contained_v19, g_s19_invalidates, nullptr, 0}, - {"s20", nullptr, 4, FPU_OFFSET(20) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20}, g_contained_v20, g_s20_invalidates, nullptr, 0}, - {"s21", nullptr, 4, FPU_OFFSET(21) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21}, g_contained_v21, g_s21_invalidates, nullptr, 0}, - {"s22", nullptr, 4, FPU_OFFSET(22) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22}, g_contained_v22, g_s22_invalidates, nullptr, 0}, - {"s23", nullptr, 4, FPU_OFFSET(23) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23}, g_contained_v23, g_s23_invalidates, nullptr, 0}, - {"s24", nullptr, 4, FPU_OFFSET(24) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24}, g_contained_v24, g_s24_invalidates, nullptr, 0}, - {"s25", nullptr, 4, FPU_OFFSET(25) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25}, g_contained_v25, g_s25_invalidates, nullptr, 0}, - {"s26", nullptr, 4, FPU_OFFSET(26) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26}, g_contained_v26, g_s26_invalidates, nullptr, 0}, - {"s27", nullptr, 4, FPU_OFFSET(27) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27}, g_contained_v27, g_s27_invalidates, nullptr, 0}, - {"s28", nullptr, 4, FPU_OFFSET(28) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28}, g_contained_v28, g_s28_invalidates, nullptr, 0}, - {"s29", nullptr, 4, FPU_OFFSET(29) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29}, g_contained_v29, g_s29_invalidates, nullptr, 0}, - {"s30", nullptr, 4, FPU_OFFSET(30) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30}, g_contained_v30, g_s30_invalidates, nullptr, 0}, - {"s31", nullptr, 4, FPU_OFFSET(31) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31}, g_contained_v31, g_s31_invalidates, nullptr, 0}, - - {"d0", nullptr, 8, FPU_OFFSET(0) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0}, g_contained_v0, g_d0_invalidates, nullptr, 0}, - {"d1", nullptr, 8, FPU_OFFSET(1) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1}, g_contained_v1, g_d1_invalidates, nullptr, 0}, - {"d2", nullptr, 8, FPU_OFFSET(2) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2}, g_contained_v2, g_d2_invalidates, nullptr, 0}, - {"d3", nullptr, 8, FPU_OFFSET(3) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3}, g_contained_v3, g_d3_invalidates, nullptr, 0}, - {"d4", nullptr, 8, FPU_OFFSET(4) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4}, g_contained_v4, g_d4_invalidates, nullptr, 0}, - {"d5", nullptr, 8, FPU_OFFSET(5) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5}, g_contained_v5, g_d5_invalidates, nullptr, 0}, - {"d6", nullptr, 8, FPU_OFFSET(6) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6}, g_contained_v6, g_d6_invalidates, nullptr, 0}, - {"d7", nullptr, 8, FPU_OFFSET(7) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7}, g_contained_v7, g_d7_invalidates, nullptr, 0}, - {"d8", nullptr, 8, FPU_OFFSET(8) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8}, g_contained_v8, g_d8_invalidates, nullptr, 0}, - {"d9", nullptr, 8, FPU_OFFSET(9) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9}, g_contained_v9, g_d9_invalidates, nullptr, 0}, - {"d10", nullptr, 8, FPU_OFFSET(10) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10}, g_contained_v10, g_d10_invalidates, nullptr, 0}, - {"d11", nullptr, 8, FPU_OFFSET(11) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11}, g_contained_v11, g_d11_invalidates, nullptr, 0}, - {"d12", nullptr, 8, FPU_OFFSET(12) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12}, g_contained_v12, g_d12_invalidates, nullptr, 0}, - {"d13", nullptr, 8, FPU_OFFSET(13) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13}, g_contained_v13, g_d13_invalidates, nullptr, 0}, - {"d14", nullptr, 8, FPU_OFFSET(14) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14}, g_contained_v14, g_d14_invalidates, nullptr, 0}, - {"d15", nullptr, 8, FPU_OFFSET(15) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15}, g_contained_v15, g_d15_invalidates, nullptr, 0}, - {"d16", nullptr, 8, FPU_OFFSET(16) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16}, g_contained_v16, g_d16_invalidates, nullptr, 0}, - {"d17", nullptr, 8, FPU_OFFSET(17) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17}, g_contained_v17, g_d17_invalidates, nullptr, 0}, - {"d18", nullptr, 8, FPU_OFFSET(18) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18}, g_contained_v18, g_d18_invalidates, nullptr, 0}, - {"d19", nullptr, 8, FPU_OFFSET(19) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19}, g_contained_v19, g_d19_invalidates, nullptr, 0}, - {"d20", nullptr, 8, FPU_OFFSET(20) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20}, g_contained_v20, g_d20_invalidates, nullptr, 0}, - {"d21", nullptr, 8, FPU_OFFSET(21) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21}, g_contained_v21, g_d21_invalidates, nullptr, 0}, - {"d22", nullptr, 8, FPU_OFFSET(22) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22}, g_contained_v22, g_d22_invalidates, nullptr, 0}, - {"d23", nullptr, 8, FPU_OFFSET(23) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23}, g_contained_v23, g_d23_invalidates, nullptr, 0}, - {"d24", nullptr, 8, FPU_OFFSET(24) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24}, g_contained_v24, g_d24_invalidates, nullptr, 0}, - {"d25", nullptr, 8, FPU_OFFSET(25) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25}, g_contained_v25, g_d25_invalidates, nullptr, 0}, - {"d26", nullptr, 8, FPU_OFFSET(26) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26}, g_contained_v26, g_d26_invalidates, nullptr, 0}, - {"d27", nullptr, 8, FPU_OFFSET(27) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27}, g_contained_v27, g_d27_invalidates, nullptr, 0}, - {"d28", nullptr, 8, FPU_OFFSET(28) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28}, g_contained_v28, g_d28_invalidates, nullptr, 0}, - {"d29", nullptr, 8, FPU_OFFSET(29) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29}, g_contained_v29, g_d29_invalidates, nullptr, 0}, - {"d30", nullptr, 8, FPU_OFFSET(30) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30}, g_contained_v30, g_d30_invalidates, nullptr, 0}, - {"d31", nullptr, 8, FPU_OFFSET(31) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31}, g_contained_v31, g_d31_invalidates, nullptr, 0}, - - {"fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr}, nullptr, nullptr, nullptr, 0}, - {"fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr}, nullptr, nullptr, nullptr, 0}, - - {"far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, nullptr, 0}, - {"esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr}, nullptr, nullptr, nullptr, 0}, - {"exception", nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, nullptr, 0}, + // DEFINE_GPR64(name, GENERIC KIND) + DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR64(x1, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR64(x2, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR64(x3, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR64(x4, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR64(x5, LLDB_REGNUM_GENERIC_ARG6), + DEFINE_GPR64(x6, LLDB_REGNUM_GENERIC_ARG7), + DEFINE_GPR64(x7, LLDB_REGNUM_GENERIC_ARG8), + DEFINE_GPR64(x8, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x9, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x10, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x11, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x12, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x13, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x14, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x15, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x16, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x17, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x18, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x19, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x20, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x21, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x22, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x23, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x24, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x25, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x26, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x27, LLDB_INVALID_REGNUM), + DEFINE_GPR64(x28, LLDB_INVALID_REGNUM), + // DEFINE_GPR64(name, GENERIC KIND) + DEFINE_GPR64_ALT(fp, x29, LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR64_ALT(lr, x30, LLDB_REGNUM_GENERIC_RA), + DEFINE_GPR64_ALT(sp, x31, LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC), + + // DEFINE_MISC_REGS(name, size, TYPE, lldb kind) + DEFINE_MISC_REGS(cpsr, 4, GPR, gpr_cpsr), + + // DEFINE_GPR32(name, parent name) + DEFINE_GPR32(w0, x0), + DEFINE_GPR32(w1, x1), + DEFINE_GPR32(w2, x2), + DEFINE_GPR32(w3, x3), + DEFINE_GPR32(w4, x4), + DEFINE_GPR32(w5, x5), + DEFINE_GPR32(w6, x6), + DEFINE_GPR32(w7, x7), + DEFINE_GPR32(w8, x8), + DEFINE_GPR32(w9, x9), + DEFINE_GPR32(w10, x10), + DEFINE_GPR32(w11, x11), + DEFINE_GPR32(w12, x12), + DEFINE_GPR32(w13, x13), + DEFINE_GPR32(w14, x14), + DEFINE_GPR32(w15, x15), + DEFINE_GPR32(w16, x16), + DEFINE_GPR32(w17, x17), + DEFINE_GPR32(w18, x18), + DEFINE_GPR32(w19, x19), + DEFINE_GPR32(w20, x20), + DEFINE_GPR32(w21, x21), + DEFINE_GPR32(w22, x22), + DEFINE_GPR32(w23, x23), + DEFINE_GPR32(w24, x24), + DEFINE_GPR32(w25, x25), + DEFINE_GPR32(w26, x26), + DEFINE_GPR32(w27, x27), + DEFINE_GPR32(w28, x28), + + // DEFINE_VREG(name) + DEFINE_VREG(v0), + DEFINE_VREG(v1), + DEFINE_VREG(v2), + DEFINE_VREG(v3), + DEFINE_VREG(v4), + DEFINE_VREG(v5), + DEFINE_VREG(v6), + DEFINE_VREG(v7), + DEFINE_VREG(v8), + DEFINE_VREG(v9), + DEFINE_VREG(v10), + DEFINE_VREG(v11), + DEFINE_VREG(v12), + DEFINE_VREG(v13), + DEFINE_VREG(v14), + DEFINE_VREG(v15), + DEFINE_VREG(v16), + DEFINE_VREG(v17), + DEFINE_VREG(v18), + DEFINE_VREG(v19), + DEFINE_VREG(v20), + DEFINE_VREG(v21), + DEFINE_VREG(v22), + DEFINE_VREG(v23), + DEFINE_VREG(v24), + DEFINE_VREG(v25), + DEFINE_VREG(v26), + DEFINE_VREG(v27), + DEFINE_VREG(v28), + DEFINE_VREG(v29), + DEFINE_VREG(v30), + DEFINE_VREG(v31), + + // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register) + DEFINE_FPU_PSEUDO(s0, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v0), + DEFINE_FPU_PSEUDO(s1, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v1), + DEFINE_FPU_PSEUDO(s2, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v2), + DEFINE_FPU_PSEUDO(s3, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v3), + DEFINE_FPU_PSEUDO(s4, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v4), + DEFINE_FPU_PSEUDO(s5, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v5), + DEFINE_FPU_PSEUDO(s6, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v6), + DEFINE_FPU_PSEUDO(s7, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v7), + DEFINE_FPU_PSEUDO(s8, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v8), + DEFINE_FPU_PSEUDO(s9, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v9), + DEFINE_FPU_PSEUDO(s10, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v10), + DEFINE_FPU_PSEUDO(s11, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v11), + DEFINE_FPU_PSEUDO(s12, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v12), + DEFINE_FPU_PSEUDO(s13, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v13), + DEFINE_FPU_PSEUDO(s14, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v14), + DEFINE_FPU_PSEUDO(s15, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v15), + DEFINE_FPU_PSEUDO(s16, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v16), + DEFINE_FPU_PSEUDO(s17, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v17), + DEFINE_FPU_PSEUDO(s18, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v18), + DEFINE_FPU_PSEUDO(s19, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v19), + DEFINE_FPU_PSEUDO(s20, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v20), + DEFINE_FPU_PSEUDO(s21, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v21), + DEFINE_FPU_PSEUDO(s22, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v22), + DEFINE_FPU_PSEUDO(s23, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v23), + DEFINE_FPU_PSEUDO(s24, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v24), + DEFINE_FPU_PSEUDO(s25, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v25), + DEFINE_FPU_PSEUDO(s26, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v26), + DEFINE_FPU_PSEUDO(s27, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v27), + DEFINE_FPU_PSEUDO(s28, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v28), + DEFINE_FPU_PSEUDO(s29, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v29), + DEFINE_FPU_PSEUDO(s30, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v30), + DEFINE_FPU_PSEUDO(s31, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v31), + + DEFINE_FPU_PSEUDO(d0, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v0), + DEFINE_FPU_PSEUDO(d1, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v1), + DEFINE_FPU_PSEUDO(d2, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v2), + DEFINE_FPU_PSEUDO(d3, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v3), + DEFINE_FPU_PSEUDO(d4, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v4), + DEFINE_FPU_PSEUDO(d5, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v5), + DEFINE_FPU_PSEUDO(d6, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v6), + DEFINE_FPU_PSEUDO(d7, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v7), + DEFINE_FPU_PSEUDO(d8, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v8), + DEFINE_FPU_PSEUDO(d9, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v9), + DEFINE_FPU_PSEUDO(d10, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v10), + DEFINE_FPU_PSEUDO(d11, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v11), + DEFINE_FPU_PSEUDO(d12, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v12), + DEFINE_FPU_PSEUDO(d13, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v13), + DEFINE_FPU_PSEUDO(d14, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v14), + DEFINE_FPU_PSEUDO(d15, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v15), + DEFINE_FPU_PSEUDO(d16, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v16), + DEFINE_FPU_PSEUDO(d17, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v17), + DEFINE_FPU_PSEUDO(d18, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v18), + DEFINE_FPU_PSEUDO(d19, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v19), + DEFINE_FPU_PSEUDO(d20, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v20), + DEFINE_FPU_PSEUDO(d21, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v21), + DEFINE_FPU_PSEUDO(d22, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v22), + DEFINE_FPU_PSEUDO(d23, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v23), + DEFINE_FPU_PSEUDO(d24, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v24), + DEFINE_FPU_PSEUDO(d25, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v25), + DEFINE_FPU_PSEUDO(d26, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v26), + DEFINE_FPU_PSEUDO(d27, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v27), + DEFINE_FPU_PSEUDO(d28, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v28), + DEFINE_FPU_PSEUDO(d29, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v29), + DEFINE_FPU_PSEUDO(d30, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v30), + DEFINE_FPU_PSEUDO(d31, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v31), + + // DEFINE_MISC_REGS(name, size, TYPE, lldb kind) + DEFINE_MISC_REGS(fpsr, 4, FPU, fpu_fpsr), + DEFINE_MISC_REGS(fpcr, 4, FPU, fpu_fpcr), + DEFINE_MISC_REGS(far, 8, EXC, exc_far), + DEFINE_MISC_REGS(esr, 4, EXC, exc_esr), + DEFINE_MISC_REGS(exception, 4, EXC, exc_exception), {DEFINE_DBG(bvr, 0)}, {DEFINE_DBG(bvr, 1)}, diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp index 588015a51ef16..6d03bd534f37f 100644 --- a/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -30,331 +30,266 @@ using namespace lldb; using namespace lldb_private; const char *StopInfoMachException::GetDescription() { - if (m_description.empty() && m_value != 0) { - ExecutionContext exe_ctx(m_thread_wp.lock()); - Target *target = exe_ctx.GetTargetPtr(); - const llvm::Triple::ArchType cpu = - target ? target->GetArchitecture().GetMachine() - : llvm::Triple::UnknownArch; - - const char *exc_desc = nullptr; - const char *code_label = "code"; - const char *code_desc = nullptr; - const char *subcode_label = "subcode"; - const char *subcode_desc = nullptr; + if (!m_description.empty()) + return m_description.c_str(); + if (GetValue() == eStopReasonInvalid) + return "invalid stop reason!"; + + ExecutionContext exe_ctx(m_thread_wp.lock()); + Target *target = exe_ctx.GetTargetPtr(); + const llvm::Triple::ArchType cpu = + target ? target->GetArchitecture().GetMachine() + : llvm::Triple::UnknownArch; + + const char *exc_desc = nullptr; + const char *code_label = "code"; + const char *code_desc = nullptr; + const char *subcode_label = "subcode"; + const char *subcode_desc = nullptr; #if defined(__APPLE__) - char code_desc_buf[32]; - char subcode_desc_buf[32]; + char code_desc_buf[32]; + char subcode_desc_buf[32]; #endif - switch (m_value) { - case 1: // EXC_BAD_ACCESS - exc_desc = "EXC_BAD_ACCESS"; - subcode_label = "address"; - switch (cpu) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - switch (m_exc_code) { - case 0xd: - code_desc = "EXC_I386_GPFLT"; - m_exc_data_count = 1; - break; - } - break; - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (m_exc_code) { - case 0x101: - code_desc = "EXC_ARM_DA_ALIGN"; - break; - case 0x102: - code_desc = "EXC_ARM_DA_DEBUG"; - break; - } + switch (m_value) { + case 1: // EXC_BAD_ACCESS + exc_desc = "EXC_BAD_ACCESS"; + subcode_label = "address"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 0xd: + code_desc = "EXC_I386_GPFLT"; + m_exc_data_count = 1; break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) { - case 0x101: - code_desc = "EXC_PPC_VM_PROT_READ"; - break; - case 0x102: - code_desc = "EXC_PPC_BADSPACE"; - break; - case 0x103: - code_desc = "EXC_PPC_UNALIGNED"; - break; - } + } + break; + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (m_exc_code) { + case 0x101: + code_desc = "EXC_ARM_DA_ALIGN"; break; - - default: + case 0x102: + code_desc = "EXC_ARM_DA_DEBUG"; break; } break; - case 2: // EXC_BAD_INSTRUCTION - exc_desc = "EXC_BAD_INSTRUCTION"; - switch (cpu) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (m_exc_code == 1) - code_desc = "EXC_I386_INVOP"; - break; + default: + break; + } + break; + + case 2: // EXC_BAD_INSTRUCTION + exc_desc = "EXC_BAD_INSTRUCTION"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + if (m_exc_code == 1) + code_desc = "EXC_I386_INVOP"; + break; - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) { - case 1: - code_desc = "EXC_PPC_INVALID_SYSCALL"; - break; - case 2: - code_desc = "EXC_PPC_UNIPL_INST"; - break; - case 3: - code_desc = "EXC_PPC_PRIVINST"; - break; - case 4: - code_desc = "EXC_PPC_PRIVREG"; - break; - case 5: - code_desc = "EXC_PPC_TRACE"; - break; - case 6: - code_desc = "EXC_PPC_PERFMON"; - break; - } - break; + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (m_exc_code == 1) + code_desc = "EXC_ARM_UNDEFINED"; + break; - case llvm::Triple::arm: - case llvm::Triple::thumb: - if (m_exc_code == 1) - code_desc = "EXC_ARM_UNDEFINED"; + default: + break; + } + break; + + case 3: // EXC_ARITHMETIC + exc_desc = "EXC_ARITHMETIC"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 1: + code_desc = "EXC_I386_DIV"; break; - - default: + case 2: + code_desc = "EXC_I386_INTO"; break; - } - break; - - case 3: // EXC_ARITHMETIC - exc_desc = "EXC_ARITHMETIC"; - switch (cpu) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - switch (m_exc_code) { - case 1: - code_desc = "EXC_I386_DIV"; - break; - case 2: - code_desc = "EXC_I386_INTO"; - break; - case 3: - code_desc = "EXC_I386_NOEXT"; - break; - case 4: - code_desc = "EXC_I386_EXTOVR"; - break; - case 5: - code_desc = "EXC_I386_EXTERR"; - break; - case 6: - code_desc = "EXC_I386_EMERR"; - break; - case 7: - code_desc = "EXC_I386_BOUND"; - break; - case 8: - code_desc = "EXC_I386_SSEEXTERR"; - break; - } + case 3: + code_desc = "EXC_I386_NOEXT"; break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) { - case 1: - code_desc = "EXC_PPC_OVERFLOW"; - break; - case 2: - code_desc = "EXC_PPC_ZERO_DIVIDE"; - break; - case 3: - code_desc = "EXC_PPC_FLT_INEXACT"; - break; - case 4: - code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; - break; - case 5: - code_desc = "EXC_PPC_FLT_UNDERFLOW"; - break; - case 6: - code_desc = "EXC_PPC_FLT_OVERFLOW"; - break; - case 7: - code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; - break; - } + case 4: + code_desc = "EXC_I386_EXTOVR"; break; - - default: + case 5: + code_desc = "EXC_I386_EXTERR"; + break; + case 6: + code_desc = "EXC_I386_EMERR"; + break; + case 7: + code_desc = "EXC_I386_BOUND"; + break; + case 8: + code_desc = "EXC_I386_SSEEXTERR"; break; } break; - case 4: // EXC_EMULATION - exc_desc = "EXC_EMULATION"; + default: break; + } + break; - case 5: // EXC_SOFTWARE - exc_desc = "EXC_SOFTWARE"; - if (m_exc_code == 0x10003) { - subcode_desc = "EXC_SOFT_SIGNAL"; - subcode_label = "signo"; + case 4: // EXC_EMULATION + exc_desc = "EXC_EMULATION"; + break; + + case 5: // EXC_SOFTWARE + exc_desc = "EXC_SOFTWARE"; + if (m_exc_code == 0x10003) { + subcode_desc = "EXC_SOFT_SIGNAL"; + subcode_label = "signo"; + } + break; + + case 6: // EXC_BREAKPOINT + { + exc_desc = "EXC_BREAKPOINT"; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (m_exc_code) { + case 1: + code_desc = "EXC_I386_SGL"; + break; + case 2: + code_desc = "EXC_I386_BPT"; + break; } break; - case 6: // EXC_BREAKPOINT - { - exc_desc = "EXC_BREAKPOINT"; - switch (cpu) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - switch (m_exc_code) { - case 1: - code_desc = "EXC_I386_SGL"; - break; - case 2: - code_desc = "EXC_I386_BPT"; - break; - } + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (m_exc_code) { + case 0x101: + code_desc = "EXC_ARM_DA_ALIGN"; break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) { - case 1: - code_desc = "EXC_PPC_BREAKPOINT"; - break; - } + case 0x102: + code_desc = "EXC_ARM_DA_DEBUG"; break; - - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (m_exc_code) { - case 0x101: - code_desc = "EXC_ARM_DA_ALIGN"; - break; - case 0x102: - code_desc = "EXC_ARM_DA_DEBUG"; - break; - case 1: - code_desc = "EXC_ARM_BREAKPOINT"; - break; - // FIXME temporary workaround, exc_code 0 does not really mean - // EXC_ARM_BREAKPOINT - case 0: - code_desc = "EXC_ARM_BREAKPOINT"; - break; - } + case 1: + code_desc = "EXC_ARM_BREAKPOINT"; break; - - default: + // FIXME temporary workaround, exc_code 0 does not really mean + // EXC_ARM_BREAKPOINT + case 0: + code_desc = "EXC_ARM_BREAKPOINT"; break; } - } break; - - case 7: - exc_desc = "EXC_SYSCALL"; break; - case 8: - exc_desc = "EXC_MACH_SYSCALL"; + default: break; + } + } break; - case 9: - exc_desc = "EXC_RPC_ALERT"; - break; + case 7: + exc_desc = "EXC_SYSCALL"; + break; - case 10: - exc_desc = "EXC_CRASH"; - break; - case 11: - exc_desc = "EXC_RESOURCE"; + case 8: + exc_desc = "EXC_MACH_SYSCALL"; + break; + + case 9: + exc_desc = "EXC_RPC_ALERT"; + break; + + case 10: + exc_desc = "EXC_CRASH"; + break; + case 11: + exc_desc = "EXC_RESOURCE"; #if defined(__APPLE__) - { - int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code); - - code_label = "limit"; - code_desc = code_desc_buf; - subcode_label = "observed"; - subcode_desc = subcode_desc_buf; - - switch (resource_type) { - case RESOURCE_TYPE_CPU: - exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU"; - snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%", - (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code)); - snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%", - (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode)); - break; - case RESOURCE_TYPE_WAKEUPS: - exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS"; - snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s", + { + int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code); + + code_label = "limit"; + code_desc = code_desc_buf; + subcode_label = "observed"; + subcode_desc = subcode_desc_buf; + + switch (resource_type) { + case RESOURCE_TYPE_CPU: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED( + m_exc_subcode)); + break; + case RESOURCE_TYPE_WAKEUPS: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS"; + snprintf( + code_desc_buf, sizeof(code_desc_buf), "%d w/s", (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code)); - snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s", - (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode)); - break; - case RESOURCE_TYPE_MEMORY: - exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY"; - snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", - (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code)); - subcode_desc = nullptr; - subcode_label = "unused"; - break; - case RESOURCE_TYPE_IO: - exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO"; - snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", - (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code)); - snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB", - (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));; - break; - } - } + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED( + m_exc_subcode)); + break; + case RESOURCE_TYPE_MEMORY: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code)); + subcode_desc = nullptr; + subcode_label = "unused"; + break; +#if defined(RESOURCE_TYPE_IO) + // RESOURCE_TYPE_IO is introduced in macOS SDK 10.12. + case RESOURCE_TYPE_IO: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode)); + ; + break; #endif - break; - case 12: - exc_desc = "EXC_GUARD"; - break; + } } +#endif + break; + case 12: + exc_desc = "EXC_GUARD"; + break; + } - StreamString strm; + StreamString strm; - if (exc_desc) - strm.PutCString(exc_desc); - else - strm.Printf("EXC_??? (%" PRIu64 ")", m_value); + if (exc_desc) + strm.PutCString(exc_desc); + else + strm.Printf("EXC_??? (%" PRIu64 ")", m_value); - if (m_exc_data_count >= 1) { - if (code_desc) - strm.Printf(" (%s=%s", code_label, code_desc); - else - strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code); - } + if (m_exc_data_count >= 1) { + if (code_desc) + strm.Printf(" (%s=%s", code_label, code_desc); + else + strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code); + } - if (m_exc_data_count >= 2) { - if (subcode_desc) - strm.Printf(", %s=%s", subcode_label, subcode_desc); - else - strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode); - } + if (m_exc_data_count >= 2) { + if (subcode_desc) + strm.Printf(", %s=%s", subcode_label, subcode_desc); + else + strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode); + } - if (m_exc_data_count > 0) - strm.PutChar(')'); + if (m_exc_data_count > 0) + strm.PutChar(')'); - m_description = strm.GetString(); - } + m_description = strm.GetString(); return m_description.c_str(); } @@ -362,141 +297,62 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted, bool adjust_pc_if_needed) { - if (exc_type != 0) { - uint32_t pc_decrement = 0; - ExecutionContext exe_ctx(thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - const llvm::Triple::ArchType cpu = - target ? target->GetArchitecture().GetMachine() - : llvm::Triple::UnknownArch; - - switch (exc_type) { - case 1: // EXC_BAD_ACCESS - break; - - case 2: // EXC_BAD_INSTRUCTION - switch (cpu) { - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (exc_code) { - case 1: // EXC_PPC_INVALID_SYSCALL - case 2: // EXC_PPC_UNIPL_INST - case 3: // EXC_PPC_PRIVINST - case 4: // EXC_PPC_PRIVREG - break; - case 5: // EXC_PPC_TRACE - return StopInfo::CreateStopReasonToTrace(thread); - case 6: // EXC_PPC_PERFMON - break; - } - break; - - default: - break; - } - break; - - case 3: // EXC_ARITHMETIC - case 4: // EXC_EMULATION - break; - - case 5: // EXC_SOFTWARE - if (exc_code == 0x10003) // EXC_SOFT_SIGNAL - { - if (exc_sub_code == 5) { - // On MacOSX, a SIGTRAP can signify that a process has called exec, - // so we should check with our dynamic loader to verify. - ProcessSP process_sp(thread.GetProcess()); - if (process_sp) { - DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader(); - if (dynamic_loader && dynamic_loader->ProcessDidExec()) { - // The program was re-exec'ed - return StopInfo::CreateStopReasonWithExec(thread); - } - // if (!process_did_exec) - // { - // // We have a SIGTRAP, make sure we - // didn't exec by checking - // // for the PC being at - // "_dyld_start"... - // lldb::StackFrameSP frame_sp - // (thread.GetStackFrameAtIndex(0)); - // if (frame_sp) - // { - // const Symbol *symbol = - // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol; - // if (symbol) - // { - // if (symbol->GetName() == - // ConstString("_dyld_start")) - // process_did_exec = true; - // } - // } - // } + if (exc_type == 0) + return StopInfoSP(); + + uint32_t pc_decrement = 0; + ExecutionContext exe_ctx(thread.shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + const llvm::Triple::ArchType cpu = + target ? target->GetArchitecture().GetMachine() + : llvm::Triple::UnknownArch; + + switch (exc_type) { + case 1: // EXC_BAD_ACCESS + case 2: // EXC_BAD_INSTRUCTION + case 3: // EXC_ARITHMETIC + case 4: // EXC_EMULATION + break; + + case 5: // EXC_SOFTWARE + if (exc_code == 0x10003) // EXC_SOFT_SIGNAL + { + if (exc_sub_code == 5) { + // On MacOSX, a SIGTRAP can signify that a process has called exec, + // so we should check with our dynamic loader to verify. + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader(); + if (dynamic_loader && dynamic_loader->ProcessDidExec()) { + // The program was re-exec'ed + return StopInfo::CreateStopReasonWithExec(thread); } } - return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code); } - break; - - case 6: // EXC_BREAKPOINT - { - bool is_actual_breakpoint = false; - bool is_trace_if_actual_breakpoint_missing = false; - switch (cpu) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (exc_code == 1) // EXC_I386_SGL - { - if (!exc_sub_code) { - // This looks like a plain trap. - // Have to check if there is a breakpoint here as well. When you - // single-step onto a trap, the single step stops you not to trap. - // Since we also do that check below, let's just use that logic. - is_actual_breakpoint = true; - is_trace_if_actual_breakpoint_missing = true; - } else { - - // It's a watchpoint, then. - // The exc_sub_code indicates the data break address. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress( - (lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) { - // Debugserver may piggyback the hardware index of the fired - // watchpoint in the exception data. Set the hardware index if - // that's the case. - if (exc_data_count >= 3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, - wp_sp->GetID()); - } - } - } else if (exc_code == 2 || // EXC_I386_BPT - exc_code == 3) // EXC_I386_BPTFLT - { - // KDP returns EXC_I386_BPTFLT for trace breakpoints - if (exc_code == 3) - is_trace_if_actual_breakpoint_missing = true; - + return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code); + } + break; + + case 6: // EXC_BREAKPOINT + { + bool is_actual_breakpoint = false; + bool is_trace_if_actual_breakpoint_missing = false; + switch (cpu) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + if (exc_code == 1) // EXC_I386_SGL + { + if (!exc_sub_code) { + // This looks like a plain trap. + // Have to check if there is a breakpoint here as well. When you + // single-step onto a trap, the single step stops you not to trap. + // Since we also do that check below, let's just use that logic. is_actual_breakpoint = true; - if (!pc_already_adjusted) - pc_decrement = 1; - } - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT - break; + is_trace_if_actual_breakpoint_missing = true; + } else { - case llvm::Triple::arm: - case llvm::Triple::thumb: - if (exc_code == 0x102) // EXC_ARM_DA_DEBUG - { - // It's a watchpoint, then, if the exc_sub_code indicates a - // known/enabled data break address from our watchpoint list. + // It's a watchpoint, then. + // The exc_sub_code indicates the data break address. lldb::WatchpointSP wp_sp; if (target) wp_sp = target->GetWatchpointList().FindByAddress( @@ -509,116 +365,148 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); - } else { - is_actual_breakpoint = true; - is_trace_if_actual_breakpoint_missing = true; } - } else if (exc_code == 1) // EXC_ARM_BREAKPOINT - { - is_actual_breakpoint = true; - is_trace_if_actual_breakpoint_missing = true; - } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel - // is currently returning this so accept it - // as indicating a breakpoint until the - // kernel is fixed - { - is_actual_breakpoint = true; - is_trace_if_actual_breakpoint_missing = true; } - break; + } else if (exc_code == 2 || // EXC_I386_BPT + exc_code == 3) // EXC_I386_BPTFLT + { + // KDP returns EXC_I386_BPTFLT for trace breakpoints + if (exc_code == 3) + is_trace_if_actual_breakpoint_missing = true; - case llvm::Triple::aarch64: { - if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT - { - // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 - // is set - is_actual_breakpoint = false; + is_actual_breakpoint = true; + if (!pc_already_adjusted) + pc_decrement = 1; + } + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (exc_code == 0x102) // EXC_ARM_DA_DEBUG + { + // It's a watchpoint, then, if the exc_sub_code indicates a + // known/enabled data break address from our watchpoint list. + lldb::WatchpointSP wp_sp; + if (target) + wp_sp = target->GetWatchpointList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired + // watchpoint in the exception data. Set the hardware index if + // that's the case. + if (exc_data_count >= 3) + wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithWatchpointID(thread, + wp_sp->GetID()); + } else { + is_actual_breakpoint = true; is_trace_if_actual_breakpoint_missing = true; } - if (exc_code == 0x102) // EXC_ARM_DA_DEBUG - { - // It's a watchpoint, then, if the exc_sub_code indicates a - // known/enabled data break address from our watchpoint list. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress( - (lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) { - // Debugserver may piggyback the hardware index of the fired - // watchpoint in the exception data. Set the hardware index if - // that's the case. - if (exc_data_count >= 3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, - wp_sp->GetID()); - } - // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as - // EXC_BAD_ACCESS - if (thread.GetTemporaryResumeState() == eStateStepping) - return StopInfo::CreateStopReasonToTrace(thread); - } - // It looks like exc_sub_code has the 4 bytes of the instruction that - // triggered the exception, i.e. our breakpoint opcode - is_actual_breakpoint = exc_code == 1; - break; + } else if (exc_code == 1) // EXC_ARM_BREAKPOINT + { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel + // is currently returning this so accept it + // as indicating a breakpoint until the + // kernel is fixed + { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; } + break; - default: - break; + case llvm::Triple::aarch64_32: + case llvm::Triple::aarch64: { + if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT + { + // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 + // is set + is_actual_breakpoint = false; + is_trace_if_actual_breakpoint_missing = true; } - - if (is_actual_breakpoint) { - RegisterContextSP reg_ctx_sp(thread.GetRegisterContext()); - addr_t pc = reg_ctx_sp->GetPC() - pc_decrement; - - ProcessSP process_sp(thread.CalculateProcess()); - - lldb::BreakpointSiteSP bp_site_sp; - if (process_sp) - bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc); - if (bp_site_sp && bp_site_sp->IsEnabled()) { - // Update the PC if we were asked to do so, but only do so if we find - // a breakpoint that we know about cause this could be a trap - // instruction in the code - if (pc_decrement > 0 && adjust_pc_if_needed) - reg_ctx_sp->SetPC(pc); - - // If the breakpoint is for this thread, then we'll report the hit, - // but if it is for another thread, we can just report no reason. We - // don't need to worry about stepping over the breakpoint here, that - // will be taken care of when the thread resumes and notices that - // there's a breakpoint under the pc. If we have an operating system - // plug-in, we might have set a thread specific breakpoint using the - // operating system thread ID, so we can't make any assumptions about - // the thread ID so we must always report the breakpoint regardless - // of the thread. - if (bp_site_sp->ValidForThisThread(&thread) || - thread.GetProcess()->GetOperatingSystem() != nullptr) - return StopInfo::CreateStopReasonWithBreakpointSiteID( - thread, bp_site_sp->GetID()); - else if (is_trace_if_actual_breakpoint_missing) - return StopInfo::CreateStopReasonToTrace(thread); - else - return StopInfoSP(); + if (exc_code == 0x102) // EXC_ARM_DA_DEBUG + { + // It's a watchpoint, then, if the exc_sub_code indicates a + // known/enabled data break address from our watchpoint list. + lldb::WatchpointSP wp_sp; + if (target) + wp_sp = target->GetWatchpointList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired + // watchpoint in the exception data. Set the hardware index if + // that's the case. + if (exc_data_count >= 3) + wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithWatchpointID(thread, + wp_sp->GetID()); } - - // Don't call this a trace if we weren't single stepping this thread. - if (is_trace_if_actual_breakpoint_missing && - thread.GetTemporaryResumeState() == eStateStepping) { + // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as + // EXC_BAD_ACCESS + if (thread.GetTemporaryResumeState() == eStateStepping) return StopInfo::CreateStopReasonToTrace(thread); - } } - } break; + // It looks like exc_sub_code has the 4 bytes of the instruction that + // triggered the exception, i.e. our breakpoint opcode + is_actual_breakpoint = exc_code == 1; + break; + } - case 7: // EXC_SYSCALL - case 8: // EXC_MACH_SYSCALL - case 9: // EXC_RPC_ALERT - case 10: // EXC_CRASH + default: break; } - return StopInfoSP(new StopInfoMachException( - thread, exc_type, exc_data_count, exc_code, exc_sub_code)); + if (is_actual_breakpoint) { + RegisterContextSP reg_ctx_sp(thread.GetRegisterContext()); + addr_t pc = reg_ctx_sp->GetPC() - pc_decrement; + + ProcessSP process_sp(thread.CalculateProcess()); + + lldb::BreakpointSiteSP bp_site_sp; + if (process_sp) + bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc); + if (bp_site_sp && bp_site_sp->IsEnabled()) { + // Update the PC if we were asked to do so, but only do so if we find + // a breakpoint that we know about cause this could be a trap + // instruction in the code + if (pc_decrement > 0 && adjust_pc_if_needed) + reg_ctx_sp->SetPC(pc); + + // If the breakpoint is for this thread, then we'll report the hit, + // but if it is for another thread, we can just report no reason. We + // don't need to worry about stepping over the breakpoint here, that + // will be taken care of when the thread resumes and notices that + // there's a breakpoint under the pc. If we have an operating system + // plug-in, we might have set a thread specific breakpoint using the + // operating system thread ID, so we can't make any assumptions about + // the thread ID so we must always report the breakpoint regardless + // of the thread. + if (bp_site_sp->ValidForThisThread(&thread) || + thread.GetProcess()->GetOperatingSystem() != nullptr) + return StopInfo::CreateStopReasonWithBreakpointSiteID( + thread, bp_site_sp->GetID()); + else if (is_trace_if_actual_breakpoint_missing) + return StopInfo::CreateStopReasonToTrace(thread); + else + return StopInfoSP(); + } + + // Don't call this a trace if we weren't single stepping this thread. + if (is_trace_if_actual_breakpoint_missing && + thread.GetTemporaryResumeState() == eStateStepping) { + return StopInfo::CreateStopReasonToTrace(thread); + } + } + } break; + + case 7: // EXC_SYSCALL + case 8: // EXC_MACH_SYSCALL + case 9: // EXC_RPC_ALERT + case 10: // EXC_CRASH + break; } - return StopInfoSP(); + + return StopInfoSP(new StopInfoMachException(thread, exc_type, exc_data_count, + exc_code, exc_sub_code)); } diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 38209fb249483..74fc90e885472 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -104,8 +104,8 @@ bool UnwindLLDB::AddFirstFrame() { unwind_done: Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); if (log) { - log->Printf("th%d Unwind of this thread is complete.", - m_thread.GetIndexID()); + LLDB_LOGF(log, "th%d Unwind of this thread is complete.", + m_thread.GetIndexID()); } m_unwind_complete = true; return false; @@ -140,10 +140,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // is going to blow out the stack space. If we're still unwinding at that // point, we're probably never going to finish. if (cur_idx >= max_stack_depth) { - if (log) - log->Printf("%*sFrame %d unwound too many frames, assuming unwind has " - "gone astray, stopping.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d unwound too many frames, assuming unwind has " + "gone astray, stopping.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } @@ -161,9 +161,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf("%*sFrame %d did not get a RegisterContext, stopping.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } @@ -181,10 +180,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf("%*sFrame %d invalid RegisterContext for this frame, " - "stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d invalid RegisterContext for this frame, " + "stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { @@ -201,10 +200,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf( - "%*sFrame %d did not get CFA for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d did not get CFA for this frame, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { @@ -230,17 +228,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf("%*sFrame %d did not get a valid CFA for this frame, " - "stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d did not get a valid CFA for this frame, " + "stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } else { - if (log) - log->Printf("%*sFrame %d had a bad CFA value but we switched the " - "UnwindPlan being used and got one that looks more " - "realistic.", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d had a bad CFA value but we switched the " + "UnwindPlan being used and got one that looks more " + "realistic.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); } } } @@ -258,10 +256,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf( - "%*sFrame %d did not get PC for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, + "%*sFrame %d did not get PC for this frame, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { @@ -278,18 +275,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { return GetOneMoreFrame(abi); } - if (log) - log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } // Infinite loop where the current cursor is the same as the previous one... if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa) { - if (log) - log->Printf("th%d pc of this frame is the same as the previous frame and " - "CFAs for both frames are identical -- stopping unwind", - m_thread.GetIndexID()); + LLDB_LOGF(log, + "th%d pc of this frame is the same as the previous frame and " + "CFAs for both frames are identical -- stopping unwind", + m_thread.GetIndexID()); return nullptr; } @@ -337,9 +333,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { new_frame = GetOneMoreFrame(abi); if (new_frame == nullptr) { - if (log) - log->Printf("th%d Unwind of this thread is complete.", - m_thread.GetIndexID()); + LLDB_LOGF(log, "th%d Unwind of this thread is complete.", + m_thread.GetIndexID()); m_unwind_complete = true; return false; } @@ -395,7 +390,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { return true; } -bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) { +bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, + bool &behaves_like_zeroth_frame) { if (m_frames.size() == 0) { if (!AddFirstFrame()) return false; @@ -410,6 +406,24 @@ bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) { if (idx < m_frames.size()) { cfa = m_frames[idx]->cfa; pc = m_frames[idx]->start_pc; + if (idx == 0) { + // Frame zero always behaves like it. + behaves_like_zeroth_frame = true; + } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { + // This could be an asynchronous signal, thus the + // pc might point to the interrupted instruction rather + // than a post-call instruction + behaves_like_zeroth_frame = true; + } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { + // This frame may result from signal processing installing + // a pointer to the first byte of a signal-return trampoline + // in the return address slot of the frame below, so this + // too behaves like the zeroth frame (i.e. the pc might not + // be pointing just past a call in it) + behaves_like_zeroth_frame = true; + } else { + behaves_like_zeroth_frame = false; + } return true; } return false; diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h index c512929c185b4..ff5db39730b51 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/source/Plugins/Process/Utility/UnwindLLDB.h @@ -73,7 +73,8 @@ protected: uint32_t DoGetFrameCount() override; bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &start_pc) override; + lldb::addr_t &start_pc, + bool &behaves_like_zeroth_frame) override; lldb::RegisterContextSP DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp index 7dc5a5f5fdd1b..558edeec1a37f 100644 --- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp @@ -43,9 +43,8 @@ uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() { return m_cursors.size(); } -bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx, - addr_t &cfa, - addr_t &pc) { +bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex( + uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) { const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) { if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS) @@ -55,6 +54,7 @@ bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx, pc = m_cursors[idx].pc; cfa = m_cursors[idx].fp; + behaves_like_zeroth_frame = (idx == 0); return true; } diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h index 2208bcc2f2e4f..f0bde90a53be7 100644 --- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h +++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h @@ -26,7 +26,8 @@ protected: uint32_t DoGetFrameCount() override; bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc) override; + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) override; lldb::RegisterContextSP DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 980169e16c51d..ab23589ae9a99 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -33,6 +33,7 @@ #include "ThreadElfCore.h" using namespace lldb_private; +namespace ELF = llvm::ELF; ConstString ProcessElfCore::GetPluginNameStatic() { static ConstString g_name("elf-core"); @@ -117,16 +118,20 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( FileRange file_range(header.p_offset, header.p_filesz); VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range); - VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); - if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && - last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() && - last_entry->GetByteSize() == last_entry->data.GetByteSize()) { - last_entry->SetRangeEnd(range_entry.GetRangeEnd()); - last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd()); - } else { - m_core_aranges.Append(range_entry); + // Only add to m_core_aranges if the file size is non zero. Some core files + // have PT_LOAD segments for all address ranges, but set f_filesz to zero for + // the .text sections since they can be retrieved from the object files. + if (header.p_filesz > 0) { + VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); + if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && + last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() && + last_entry->GetByteSize() == last_entry->data.GetByteSize()) { + last_entry->SetRangeEnd(range_entry.GetRangeEnd()); + last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd()); + } else { + m_core_aranges.Append(range_entry); + } } - // Keep a separate map of permissions that that isn't coalesced so all ranges // are maintained. const uint32_t permissions = @@ -417,7 +422,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); if (log) { if (pr_version > 1) - log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version); + LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version); } // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate @@ -521,8 +526,8 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { if (note.info.n_name != "FreeBSD") continue; - if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) || - (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) { + if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) || + (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) { assert(thread_data.gpregset.GetByteSize() > 0); // Add the new thread to thread list m_thread_data.push_back(thread_data); @@ -532,19 +537,19 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { } switch (note.info.n_type) { - case FREEBSD::NT_PRSTATUS: + case ELF::NT_PRSTATUS: have_prstatus = true; ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture()); break; - case FREEBSD::NT_PRPSINFO: + case ELF::NT_PRPSINFO: have_prpsinfo = true; break; - case FREEBSD::NT_THRMISC: { + case ELF::NT_FREEBSD_THRMISC: { lldb::offset_t offset = 0; thread_data.name = note.data.GetCStr(&offset, 20); break; } - case FREEBSD::NT_PROCSTAT_AUXV: + case ELF::NT_FREEBSD_PROCSTAT_AUXV: // FIXME: FreeBSD sticks an int at the beginning of the note m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4); break; @@ -771,8 +776,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { if (note.info.n_name != "CORE" && note.info.n_name != "LINUX") continue; - if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) || - (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) { + if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) || + (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) { assert(thread_data.gpregset.GetByteSize() > 0); // Add the new thread to thread list m_thread_data.push_back(thread_data); @@ -782,7 +787,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { } switch (note.info.n_type) { - case LINUX::NT_PRSTATUS: { + case ELF::NT_PRSTATUS: { have_prstatus = true; ELFLinuxPrStatus prstatus; Status status = prstatus.Parse(note.data, arch); @@ -795,7 +800,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { thread_data.gpregset = DataExtractor(note.data, header_size, len); break; } - case LINUX::NT_PRPSINFO: { + case ELF::NT_PRPSINFO: { have_prpsinfo = true; ELFLinuxPrPsInfo prpsinfo; Status status = prpsinfo.Parse(note.data, arch); @@ -805,7 +810,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { SetID(prpsinfo.pr_pid); break; } - case LINUX::NT_SIGINFO: { + case ELF::NT_SIGINFO: { ELFLinuxSigInfo siginfo; Status status = siginfo.Parse(note.data, arch); if (status.Fail()) @@ -813,7 +818,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { thread_data.signo = siginfo.si_signo; break; } - case LINUX::NT_FILE: { + case ELF::NT_FILE: { m_nt_file_entries.clear(); lldb::offset_t offset = 0; const uint64_t count = note.data.GetAddress(&offset); @@ -832,7 +837,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { } break; } - case LINUX::NT_AUXV: + case ELF::NT_AUXV: m_auxv = note.data; break; default: diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.h b/source/Plugins/Process/elf-core/RegisterUtilities.h index d3b3373150f8f..49ad425db4453 100644 --- a/source/Plugins/Process/elf-core/RegisterUtilities.h +++ b/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -11,21 +11,11 @@ #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "lldb/Utility/DataExtractor.h" +#include "llvm/BinaryFormat/ELF.h" namespace lldb_private { /// Core files PT_NOTE segment descriptor types -namespace FREEBSD { -enum { - NT_PRSTATUS = 1, - NT_FPREGSET, - NT_PRPSINFO, - NT_THRMISC = 7, - NT_PROCSTAT_AUXV = 16, - NT_PPC_VMX = 0x100 -}; -} - namespace NETBSD { enum { NT_PROCINFO = 1, NT_AUXV = 2 }; @@ -76,22 +66,6 @@ enum { }; } -namespace LINUX { -enum { - NT_PRSTATUS = 1, - NT_FPREGSET, - NT_PRPSINFO, - NT_TASKSTRUCT, - NT_PLATFORM, - NT_AUXV, - NT_FILE = 0x46494c45, - NT_SIGINFO = 0x53494749, - NT_PPC_VMX = 0x100, - NT_PPC_VSX = 0x102, - NT_PRXFPREG = 0x46e62b7f, -}; -} - struct CoreNote { ELFNote info; DataExtractor data; @@ -122,24 +96,24 @@ DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes, llvm::ArrayRef<RegsetDesc> RegsetDescs); constexpr RegsetDesc FPR_Desc[] = { - {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET}, + {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET}, // In a i386 core file NT_FPREGSET is present, but it's not the result // of the FXSAVE instruction like in 64 bit files. // The result from FXSAVE is in NT_PRXFPREG for i386 core files - {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG}, - {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET}, + {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG}, + {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET}, {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS}, {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS}, {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS}, }; constexpr RegsetDesc PPC_VMX_Desc[] = { - {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX}, - {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX}, + {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, + {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX}, }; constexpr RegsetDesc PPC_VSX_Desc[] = { - {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX}, + {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VSX}, }; } // namespace lldb_private diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp index a5d1fc4a7bfff..508c8a3108a68 100644 --- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -181,9 +181,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { } if (!reg_interface) { - if (log) - log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported", - __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); + LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported", + __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); assert(false && "Architecture or OS not supported"); } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index fe7ef6b3aceab..064bbde8442e7 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -63,18 +63,16 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( case PacketResult::Success: break; default: - if (log) - log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false", - __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteClientBase::%s () ReadPacket(...) => false", + __FUNCTION__); return eStateInvalid; } if (response.Empty()) return eStateInvalid; const char stop_type = response.GetChar(); - if (log) - log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__, - response.GetStringRef().c_str()); + LLDB_LOGF(log, "GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__, + response.GetStringRef().data()); switch (stop_type) { case 'W': @@ -84,9 +82,8 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( // ERROR return eStateInvalid; default: - if (log) - log->Printf("GDBRemoteClientBase::%s () unrecognized async packet", - __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteClientBase::%s () unrecognized async packet", + __FUNCTION__); return eStateInvalid; case 'O': { std::string inferior_stdout; @@ -162,10 +159,10 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse( if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)) - log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending " - "packet '%.*s' (send_async=%d)", - __FUNCTION__, int(payload.size()), payload.data(), - send_async); + LLDB_LOGF(log, + "GDBRemoteClientBase::%s failed to get mutex, not sending " + "packet '%.*s' (send_async=%d)", + __FUNCTION__, int(payload.size()), payload.data(), send_async); return PacketResult::ErrorSendFailed; } @@ -181,10 +178,10 @@ GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport( if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)) - log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending " - "packet '%.*s' (send_async=%d)", - __FUNCTION__, int(payload.size()), payload.data(), - send_async); + LLDB_LOGF(log, + "GDBRemoteClientBase::%s failed to get mutex, not sending " + "packet '%.*s' (send_async=%d)", + __FUNCTION__, int(payload.size()), payload.data(), send_async); return PacketResult::ErrorSendFailed; } @@ -214,13 +211,13 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock( return packet_result; // Response says it wasn't valid Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS); - if (log) - log->Printf( - "error: packet with payload \"%.*s\" got invalid response \"%s\": %s", - int(payload.size()), payload.data(), response.GetStringRef().c_str(), - (i == (max_response_retries - 1)) - ? "using invalid response and giving up" - : "ignoring response and waiting for another"); + LLDB_LOGF( + log, + "error: packet with payload \"%.*s\" got invalid response \"%s\": %s", + int(payload.size()), payload.data(), response.GetStringRef().data(), + (i == (max_response_retries - 1)) + ? "using invalid response and giving up" + : "ignoring response and waiting for another"); } return packet_result; } @@ -228,16 +225,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock( bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload, StringExtractorGDBRemote &response) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__); // we want to lock down packet sending while we continue Lock lock(*this, true); - if (log) - log->Printf( - "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", - __FUNCTION__, int(payload.size()), payload.data()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", + __FUNCTION__, int(payload.size()), payload.data()); if (SendPacketNoLock(payload) != PacketResult::Success) return false; @@ -315,18 +310,16 @@ void GDBRemoteClientBase::ContinueLock::unlock() { GDBRemoteClientBase::ContinueLock::LockResult GDBRemoteClientBase::ContinueLock::lock() { Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS); - if (log) - log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s", - __FUNCTION__, m_comm.m_continue_packet.c_str()); + LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() resuming with %s", + __FUNCTION__, m_comm.m_continue_packet.c_str()); lldbassert(!m_acquired); std::unique_lock<std::mutex> lock(m_comm.m_mutex); m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; }); if (m_comm.m_should_stop) { m_comm.m_should_stop = false; - if (log) - log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled", - __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() cancelled", + __FUNCTION__); return LockResult::Cancelled; } if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) != @@ -368,9 +361,8 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) { size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, nullptr); if (bytes_written == 0) { --m_comm.m_async_count; - if (log) - log->Printf("GDBRemoteClientBase::Lock::Lock failed to send " - "interrupt packet"); + LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send " + "interrupt packet"); return; } if (log) diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h index 54f69e8caac68..ea294ffcef261 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -24,12 +24,10 @@ public: virtual void HandleAsyncMisc(llvm::StringRef data) = 0; virtual void HandleStopReply() = 0; - // ========================================================================= /// Process asynchronously-received structured data. /// /// \param[in] data /// The complete data packet, expected to start with JSON-async. - // ========================================================================= virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0; }; @@ -83,42 +81,48 @@ protected: virtual void OnRunPacketSent(bool first); private: - // Variables handling synchronization between the Continue thread and any - // other threads - // wishing to send packets over the connection. Either the continue thread has - // control over - // the connection (m_is_running == true) or the connection is free for an - // arbitrary number of - // other senders to take which indicate their interest by incrementing - // m_async_count. - // Semantics of individual states: - // - m_continue_packet == false, m_async_count == 0: connection is free - // - m_continue_packet == true, m_async_count == 0: only continue thread is - // present - // - m_continue_packet == true, m_async_count > 0: continue thread has - // control, async threads - // should interrupt it and wait for it to set m_continue_packet to false - // - m_continue_packet == false, m_async_count > 0: async threads have - // control, continue - // thread needs to wait for them to finish (m_async_count goes down to 0). + /// Variables handling synchronization between the Continue thread and any + /// other threads wishing to send packets over the connection. Either the + /// continue thread has control over the connection (m_is_running == true) or + /// the connection is free for an arbitrary number of other senders to take + /// which indicate their interest by incrementing m_async_count. + /// + /// Semantics of individual states: + /// + /// - m_continue_packet == false, m_async_count == 0: + /// connection is free + /// - m_continue_packet == true, m_async_count == 0: + /// only continue thread is present + /// - m_continue_packet == true, m_async_count > 0: + /// continue thread has control, async threads should interrupt it and wait + /// for it to set m_continue_packet to false + /// - m_continue_packet == false, m_async_count > 0: + /// async threads have control, continue thread needs to wait for them to + /// finish (m_async_count goes down to 0). + /// @{ std::mutex m_mutex; std::condition_variable m_cv; - // Packet with which to resume after an async interrupt. Can be changed by an - // async thread - // e.g. to inject a signal. + + /// Packet with which to resume after an async interrupt. Can be changed by + /// an async thread e.g. to inject a signal. std::string m_continue_packet; - // When was the interrupt packet sent. Used to make sure we time out if the - // stub does not - // respond to interrupt requests. + + /// When was the interrupt packet sent. Used to make sure we time out if the + /// stub does not respond to interrupt requests. std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time; + + /// Number of threads interested in sending. uint32_t m_async_count; + + /// Whether the continue thread has control. bool m_is_running; - bool m_should_stop; // Whether we should resume after a stop. - // end of continue thread synchronization block - // This handles the synchronization between individual async threads. For now - // they just use a - // simple mutex. + /// Whether we should resume after a stop. + bool m_should_stop; + /// @} + + /// This handles the synchronization between individual async threads. For + /// now they just use a simple mutex. std::recursive_mutex m_async_mutex; bool ShouldStop(const UnixSignals &signals, diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 11052eff948f9..144ae103faa4b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -14,6 +14,7 @@ #include <sys/stat.h> #include "lldb/Core/StreamFile.h" +#include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" @@ -38,6 +39,8 @@ #if defined(__APPLE__) #define DEBUGSERVER_BASENAME "debugserver" +#elif defined(_WIN32) +#define DEBUGSERVER_BASENAME "lldb-server.exe" #else #define DEBUGSERVER_BASENAME "lldb-server" #endif @@ -99,10 +102,8 @@ size_t GDBRemoteCommunication::SendAck() { ConnectionStatus status = eConnectionStatusSuccess; char ch = '+'; const size_t bytes_written = Write(&ch, 1, status, nullptr); - if (log) - log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, - bytes_written); + LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); + m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written); return bytes_written; } @@ -111,10 +112,8 @@ size_t GDBRemoteCommunication::SendNack() { ConnectionStatus status = eConnectionStatusSuccess; char ch = '-'; const size_t bytes_written = Write(&ch, 1, status, nullptr); - if (log) - log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, - bytes_written); + LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); + m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written); return bytes_written; } @@ -172,13 +171,12 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, strm.Printf("%*s", (int)3, p); log->PutString(strm.GetString()); } else - log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, - (int)packet_length, packet_data); + LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %.*s", + (uint64_t)bytes_written, (int)packet_length, packet_data); } m_history.AddPacket(packet.str(), packet_length, - GDBRemoteCommunicationHistory::ePacketTypeSend, - bytes_written); + GDBRemotePacket::ePacketTypeSend, bytes_written); if (bytes_written == packet_length) { if (!skip_ack && GetSendAcks()) @@ -186,9 +184,8 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, else return PacketResult::Success; } else { - if (log) - log->Printf("error: failed to send packet: %.*s", (int)packet_length, - packet_data); + LLDB_LOGF(log, "error: failed to send packet: %.*s", (int)packet_length, + packet_data); } } return PacketResult::ErrorSendFailed; @@ -332,11 +329,12 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, std::string regex_str = "^"; regex_str += echo_packet; regex_str += "$"; - response_regex.Compile(regex_str); + response_regex = RegularExpression(regex_str); } else { echo_packet_len = ::snprintf(echo_packet, sizeof(echo_packet), "qC"); - response_regex.Compile(llvm::StringRef("^QC[0-9A-Fa-f]+$")); + response_regex = + RegularExpression(llvm::StringRef("^QC[0-9A-Fa-f]+$")); } PacketResult echo_packet_result = @@ -489,11 +487,10 @@ bool GDBRemoteCommunication::DecompressPacket() { llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1)); bool success = packet_checksum == actual_checksum; if (!success) { - if (log) - log->Printf( - "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", - (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum, - (uint8_t)actual_checksum); + LLDB_LOGF(log, + "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", + (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum, + (uint8_t)actual_checksum); } // Send the ack or nack if needed if (!success) { @@ -651,8 +648,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, if (src && src_len > 0) { if (log && log->GetVerbose()) { StreamString s; - log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s", - __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src); + LLDB_LOGF(log, "GDBRemoteCommunication::%s adding %u bytes: %.*s", + __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src); } m_bytes.append((const char *)src, src_len); } @@ -733,9 +730,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, break; } } - if (log) - log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", - __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str()); + LLDB_LOGF(log, "GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", + __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str()); m_bytes.erase(0, idx - 1); } break; } @@ -752,7 +748,6 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, size_t content_end = content_start + content_length; bool success = true; - std::string &packet_str = packet.GetStringRef(); if (log) { // If logging was just enabled and we have history, then dump out what // we have to the log so we get the historical context. The Dump() call @@ -800,25 +795,23 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, log->PutString(strm.GetString()); } else { if (CompressionIsEnabled()) - log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", - (uint64_t)original_packet_size, (uint64_t)total_length, - (int)(total_length), m_bytes.c_str()); + LLDB_LOGF(log, "<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", + (uint64_t)original_packet_size, (uint64_t)total_length, + (int)(total_length), m_bytes.c_str()); else - log->Printf("<%4" PRIu64 "> read packet: %.*s", - (uint64_t)total_length, (int)(total_length), - m_bytes.c_str()); + LLDB_LOGF(log, "<%4" PRIu64 "> read packet: %.*s", + (uint64_t)total_length, (int)(total_length), + m_bytes.c_str()); } } m_history.AddPacket(m_bytes, total_length, - GDBRemoteCommunicationHistory::ePacketTypeRecv, - total_length); + GDBRemotePacket::ePacketTypeRecv, total_length); - // Clear packet_str in case there is some existing data in it. - packet_str.clear(); // Copy the packet from m_bytes to packet_str expanding the run-length // encoding in the process. Reserve enough byte for the most common case // (no RLE used) + std ::string packet_str; packet_str.reserve(m_bytes.length()); for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c) { @@ -841,6 +834,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, packet_str.push_back(*c); } } + packet = StringExtractorGDBRemote(packet_str); if (m_bytes[0] == '$' || m_bytes[0] == '%') { assert(checksum_idx < m_bytes.size()); @@ -853,11 +847,11 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, llvm::StringRef(m_bytes).slice(content_start, content_end)); success = packet_checksum == actual_checksum; if (!success) { - if (log) - log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, " - "got 0x%2.2x", - (int)(total_length), m_bytes.c_str(), - (uint8_t)packet_checksum, (uint8_t)actual_checksum); + LLDB_LOGF(log, + "error: checksum mismatch: %.*s expected 0x%2.2x, " + "got 0x%2.2x", + (int)(total_length), m_bytes.c_str(), + (uint8_t)packet_checksum, (uint8_t)actual_checksum); } // Send the ack or nack if needed if (!success) @@ -867,9 +861,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, } } else { success = false; - if (log) - log->Printf("error: invalid checksum in packet: '%s'\n", - m_bytes.c_str()); + LLDB_LOGF(log, "error: invalid checksum in packet: '%s'\n", + m_bytes.c_str()); } } @@ -933,10 +926,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess( const char *url, Platform *platform, ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args, int pass_comm_fd) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", - __FUNCTION__, url ? url : "<empty>", - port ? *port : uint16_t(0)); + LLDB_LOGF(log, "GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", + __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0)); Status error; // If we locate debugserver, keep that located version around @@ -953,10 +944,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( if (!env_debugserver_path.empty()) { debugserver_file_spec.SetFile(env_debugserver_path, FileSpec::Style::native); - if (log) - log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set " - "from environment variable: %s", - __FUNCTION__, env_debugserver_path.c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() gdb-remote stub exe path set " + "from environment variable: %s", + __FUNCTION__, env_debugserver_path.c_str()); } else debugserver_file_spec = g_debugserver_file_spec; bool debugserver_exists = @@ -968,10 +959,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess( debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME); debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec); if (debugserver_exists) { - if (log) - log->Printf( - "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", - __FUNCTION__, debugserver_file_spec.GetPath().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", + __FUNCTION__, debugserver_file_spec.GetPath().c_str()); g_debugserver_file_spec = debugserver_file_spec; } else { @@ -985,10 +975,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( // exist debugserver_exists = true; } else { - if (log) - log->Printf("GDBRemoteCommunication::%s() could not find " - "gdb-remote stub exe '%s'", - __FUNCTION__, debugserver_file_spec.GetPath().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() could not find " + "gdb-remote stub exe '%s'", + __FUNCTION__, debugserver_file_spec.GetPath().c_str()); } // Don't cache the platform specific GDB server binary as it could // change from platform to platform @@ -1052,10 +1042,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunication::%s() " - "named pipe creation failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() " + "named pipe creation failed: %s", + __FUNCTION__, error.AsCString()); return error; } debugserver_args.AppendArgument(llvm::StringRef("--named-pipe")); @@ -1065,10 +1055,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( // using using an unnamed pipe... error = socket_pipe.CreateNew(true); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunication::%s() " - "unnamed pipe creation failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() " + "unnamed pipe creation failed: %s", + __FUNCTION__, error.AsCString()); return error; } pipe_t write = socket_pipe.GetWritePipe(); @@ -1081,10 +1071,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( // debugserver connect to us.. error = StartListenThread("127.0.0.1", 0); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunication::%s() unable to start listen " - "thread: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() unable to start listen " + "thread: %s", + __FUNCTION__, error.AsCString()); return error; } @@ -1104,9 +1094,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess( *port = port_; } else { error.SetErrorString("failed to bind to port 0 on 127.0.0.1"); - if (log) - log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, - error.AsCString()); + LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s", + __FUNCTION__, error.AsCString()); return error; } } @@ -1148,10 +1137,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( if (has_env_var) { debugserver_args.AppendArgument(llvm::StringRef(extra_arg)); - if (log) - log->Printf("GDBRemoteCommunication::%s adding env var %s contents " - "to stub command line (%s)", - __FUNCTION__, env_var_name, extra_arg.c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s adding env var %s contents " + "to stub command line (%s)", + __FUNCTION__, env_var_name, extra_arg.c_str()); } } while (has_env_var); @@ -1177,8 +1166,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess( StreamString string_stream; Platform *const platform = nullptr; launch_info.Dump(string_stream, platform); - log->Printf("launch info for gdb-remote stub:\n%s", - string_stream.GetData()); + LLDB_LOGF(log, "launch info for gdb-remote stub:\n%s", + string_stream.GetData()); } error = Host::LaunchProcess(launch_info); @@ -1188,11 +1177,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess( if (named_pipe_path.size() > 0) { error = socket_pipe.OpenAsReader(named_pipe_path, false); if (error.Fail()) - if (log) - log->Printf("GDBRemoteCommunication::%s() " - "failed to open named pipe %s for reading: %s", - __FUNCTION__, named_pipe_path.c_str(), - error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() " + "failed to open named pipe %s for reading: %s", + __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); } if (socket_pipe.CanWrite()) @@ -1209,24 +1197,22 @@ Status GDBRemoteCommunication::StartDebugserverProcess( 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); + LLDB_LOGF(log, + "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)); + LLDB_LOGF(log, + "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() " - "failed to read a port value from pipe %s: %s", - __FUNCTION__, named_pipe_path.c_str(), - error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s() " + "failed to read a port value from pipe %s: %s", + __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); } socket_pipe.Close(); } @@ -1234,10 +1220,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess( if (named_pipe_path.size() > 0) { const auto err = socket_pipe.Delete(named_pipe_path); if (err.Fail()) { - if (log) - log->Printf( - "GDBRemoteCommunication::%s failed to delete pipe %s: %s", - __FUNCTION__, named_pipe_path.c_str(), err.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunication::%s failed to delete pipe %s: %s", + __FUNCTION__, named_pipe_path.c_str(), err.AsCString()); } } @@ -1249,9 +1234,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess( } if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, - error.AsCString()); + LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, + error.AsCString()); } return error; @@ -1351,7 +1335,7 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes, if (type == PacketType::Notify) { // put this packet into an event - const char *pdata = packet.GetStringRef().c_str(); + const char *pdata = packet.GetStringRef().data(); // as the communication class, we are a broadcaster and the async thread // is tuned to listen to us diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 9797184026e06..feb9f0589ceed 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -23,7 +23,6 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -35,17 +34,15 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/JSON.h" -#if defined(__APPLE__) -#ifndef HAVE_LIBCOMPRESSION -#define HAVE_LIBCOMPRESSION -#endif +#if defined(HAVE_LIBCOMPRESSION) #include <compression.h> #endif using namespace lldb; -using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +using namespace lldb_private; using namespace std::chrono; // GDBRemoteCommunicationClient constructor @@ -342,7 +339,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { // not, we assume no limit // build the qSupported packet - std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"}; + std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"}; StreamString packet; packet.PutCString("qSupported"); for (uint32_t i = 0; i < features.size(); ++i) { @@ -354,7 +351,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { if (SendPacketAndWaitForResponse(packet.GetString(), response, /*send_async=*/false) == PacketResult::Success) { - const char *response_cstr = response.GetStringRef().c_str(); + const char *response_cstr = response.GetStringRef().data(); // Hang on to the qSupported packet, so that platforms can do custom // configuration of the transport before attaching/launching the process. @@ -439,8 +436,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_max_packet_size = UINT64_MAX; // Must have been a garbled response Log *log( ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("Garbled PacketSize spec in qSupported response"); + LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response"); } } } @@ -469,7 +465,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) { m_supports_vCont_S = eLazyBoolNo; if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success) { - const char *response_cstr = response.GetStringRef().c_str(); + const char *response_cstr = response.GetStringRef().data(); if (::strstr(response_cstr, ";c")) m_supports_vCont_c = eLazyBoolYes; @@ -525,9 +521,10 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse( if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) - log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex " - "for %s packet.", - __FUNCTION__, payload.GetData()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex " + "for %s packet.", + __FUNCTION__, payload.GetData()); return PacketResult::ErrorNoSequenceLock; } @@ -660,10 +657,10 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( if (!lock) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending " - "packets with prefix '%s'", - payload_prefix); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "packets with prefix '%s'", + payload_prefix); return PacketResult::ErrorNoSequenceLock; } @@ -934,6 +931,11 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() { return m_os_version; } +llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() { + GetHostInfo(); + return m_maccatalyst_version; +} + bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) { if (GetHostInfo()) { if (!m_os_build.empty()) { @@ -1136,6 +1138,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { uint32_t sub = 0; std::string arch_name; std::string os_name; + std::string environment; std::string vendor_name; std::string triple; std::string distribution_id; @@ -1175,7 +1178,11 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { extractor.GetHexByteString(m_os_kernel); ++num_keys_decoded; } else if (name.equals("ostype")) { - os_name = value; + if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else + os_name = value; ++num_keys_decoded; } else if (name.equals("vendor")) { vendor_name = value; @@ -1199,6 +1206,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { { if (!m_os_version.tryParse(value)) ++num_keys_decoded; + } else if (name.equals("maccatalyst_version")) { + if (!m_maccatalyst_version.tryParse(value)) + ++num_keys_decoded; } else if (name.equals("watchpoint_exceptions_received")) { m_watchpoints_trigger_after_instruction = llvm::StringSwitch<LazyBool>(value) @@ -1236,6 +1246,8 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { llvm::StringRef(vendor_name)); if (!os_name.empty()) m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + if (!environment.empty()) + m_host_arch.GetTriple().setEnvironmentName(environment); } } else { std::string triple; @@ -1259,6 +1271,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { host_triple.getOS() == llvm::Triple::Darwin) { switch (m_host_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: case llvm::Triple::arm: case llvm::Triple::thumb: host_triple.setOS(llvm::Triple::IOS); @@ -1284,14 +1297,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { assert(byte_order == m_host_arch.GetByteOrder()); } - if (log) - log->Printf("GDBRemoteCommunicationClient::%s parsed host " - "architecture as %s, triple as %s from triple text %s", - __FUNCTION__, m_host_arch.GetArchitectureName() - ? m_host_arch.GetArchitectureName() - : "<null-arch-name>", - m_host_arch.GetTriple().getTriple().c_str(), - triple.c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s parsed host " + "architecture as %s, triple as %s from triple text %s", + __FUNCTION__, + m_host_arch.GetArchitectureName() + ? m_host_arch.GetArchitectureName() + : "<null-arch-name>", + m_host_arch.GetTriple().getTriple().c_str(), + triple.c_str()); } if (!distribution_id.empty()) m_host_arch.SetDistributionId(distribution_id.c_str()); @@ -1893,7 +1907,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( } else if (name.equals("euid")) { uint32_t uid = UINT32_MAX; value.getAsInteger(0, uid); - process_info.SetEffectiveGroupID(uid); + process_info.SetEffectiveUserID(uid); } else if (name.equals("gid")) { uint32_t gid = UINT32_MAX; value.getAsInteger(0, gid); @@ -1914,6 +1928,26 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( std::string name; extractor.GetHexByteString(name); process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native); + } else if (name.equals("args")) { + llvm::StringRef encoded_args(value), hex_arg; + + bool is_arg0 = true; + while (!encoded_args.empty()) { + std::tie(hex_arg, encoded_args) = encoded_args.split('-'); + std::string arg; + StringExtractor extractor(hex_arg); + if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) { + // In case of wrong encoding, we discard all the arguments + process_info.GetArguments().Clear(); + process_info.SetArg0(""); + break; + } + if (is_arg0) + process_info.SetArg0(arg); + else + process_info.GetArguments().AppendArgument(arg); + is_arg0 = false; + } } else if (name.equals("cputype")) { value.getAsInteger(0, cpu); } else if (name.equals("cpusubtype")) { @@ -1987,6 +2021,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { uint32_t sub = 0; std::string arch_name; std::string os_name; + std::string environment; std::string vendor_name; std::string triple; std::string elf_abi; @@ -2007,7 +2042,11 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { extractor.GetHexByteString(triple); ++num_keys_decoded; } else if (name.equals("ostype")) { - os_name = value; + if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else + os_name = value; ++num_keys_decoded; } else if (name.equals("vendor")) { vendor_name = value; @@ -2048,6 +2087,8 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty()) { llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name); + if (!environment.empty()) + triple.setEnvironmentName(environment); assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat); assert(triple.getObjectFormat() != llvm::Triple::Wasm); @@ -2064,12 +2105,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { break; case llvm::Triple::Wasm: case llvm::Triple::XCOFF: - if (log) - log->Printf("error: not supported target architecture"); + LLDB_LOGF(log, "error: not supported target architecture"); return false; case llvm::Triple::UnknownObjectFormat: - if (log) - log->Printf("error: failed to determine target architecture"); + LLDB_LOGF(log, "error: failed to determine target architecture"); return false; } @@ -2081,8 +2120,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { } m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); } return true; } @@ -2156,8 +2197,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) packet.Printf("egid:%u;", match_info.GetProcessInfo().GetEffectiveGroupID()); - if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) - packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); + packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); if (match_info.GetProcessInfo().GetArchitecture().IsValid()) { const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture(); @@ -2178,8 +2218,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( if (!DecodeProcessInfoResponse(response, process_info)) break; process_infos.Append(process_info); - response.GetStringRef().clear(); - response.SetFilePos(0); + response = StringExtractorGDBRemote(); } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) == PacketResult::Success); } else { @@ -2641,9 +2680,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo( uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( GDBStoppointType type, bool insert, addr_t addr, uint32_t length) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, - __FUNCTION__, insert ? "add" : "remove", addr); + LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, + __FUNCTION__, insert ? "add" : "remove", addr); // Check if the stub is known not to support this breakpoint type if (!SupportsGDBStoppointPacket(type)) @@ -2745,9 +2783,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( #if !defined(LLDB_CONFIGURATION_DEBUG) Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending " - "packet 'qfThreadInfo'"); + LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " + "packet 'qfThreadInfo'"); #endif sequence_mutex_unavailable = true; } @@ -2879,7 +2916,7 @@ static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, } lldb::user_id_t GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec, - uint32_t flags, mode_t mode, + File::OpenOptions flags, mode_t mode, Status &error) { std::string path(file_spec.GetPath(false)); lldb_private::StreamString stream; @@ -3146,7 +3183,8 @@ bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) { if (arch.IsValid() && arch.GetTriple().getVendor() == llvm::Triple::Apple && arch.GetTriple().getOS() == llvm::Triple::IOS && - arch.GetTriple().getArch() == llvm::Triple::aarch64) { + (arch.GetTriple().getArch() == llvm::Triple::aarch64 || + arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) { m_avoid_g_packets = eLazyBoolYes; uint32_t gdb_server_version = GetGDBServerProgramVersion(); if (gdb_server_version != 0) { @@ -3592,21 +3630,21 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { llvm::Optional<std::vector<ModuleSpec>> GDBRemoteCommunicationClient::GetModulesInfo( llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) { + namespace json = llvm::json; + if (!m_supports_jModulesInfo) return llvm::None; - JSONArray::SP module_array_sp = std::make_shared<JSONArray>(); + json::Array module_array; for (const FileSpec &module_file_spec : module_file_specs) { - JSONObject::SP module_sp = std::make_shared<JSONObject>(); - module_array_sp->AppendObject(module_sp); - module_sp->SetObject( - "file", std::make_shared<JSONString>(module_file_spec.GetPath(false))); - module_sp->SetObject("triple", - std::make_shared<JSONString>(triple.getTriple())); + module_array.push_back( + json::Object{{"file", module_file_spec.GetPath(false)}, + {"triple", triple.getTriple()}}); } StreamString unescaped_payload; unescaped_payload.PutCString("jModulesInfo:"); - module_array_sp->Write(unescaped_payload); + unescaped_payload.AsRawOstream() << std::move(module_array); + StreamGDBRemote payload; payload.PutEscapedBytes(unescaped_payload.GetString().data(), unescaped_payload.GetSize()); @@ -3796,8 +3834,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; lldb_private::SymbolContextList sc_list; - if (process->GetTarget().GetImages().FindSymbolsWithNameAndType( - ConstString(symbol_name), eSymbolTypeAny, sc_list)) { + process->GetTarget().GetImages().FindSymbolsWithNameAndType( + ConstString(symbol_name), eSymbolTypeAny, sc_list); + if (!sc_list.IsEmpty()) { const size_t num_scs = sc_list.GetSize(); for (size_t sc_idx = 0; sc_idx < num_scs && @@ -3873,9 +3912,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) { - log->Printf( - "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", + __FUNCTION__); } } } @@ -3899,26 +3938,27 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { !m_supported_async_json_packets_sp->GetAsArray()) { // We were returned something other than a JSON array. This is // invalid. Clear it out. - if (log) - log->Printf("GDBRemoteCommunicationClient::%s(): " - "QSupportedAsyncJSONPackets returned invalid " - "result: %s", - __FUNCTION__, response.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): " + "QSupportedAsyncJSONPackets returned invalid " + "result: %s", + __FUNCTION__, response.GetStringRef().data()); m_supported_async_json_packets_sp.reset(); } } else { - if (log) - log->Printf("GDBRemoteCommunicationClient::%s(): " - "QSupportedAsyncJSONPackets unsupported", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): " + "QSupportedAsyncJSONPackets unsupported", + __FUNCTION__); } if (log && m_supported_async_json_packets_sp) { StreamString stream; m_supported_async_json_packets_sp->Dump(stream); - log->Printf("GDBRemoteCommunicationClient::%s(): supported async " - "JSON packets: %s", - __FUNCTION__, stream.GetData()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): supported async " + "JSON packets: %s", + __FUNCTION__, stream.GetData()); } } @@ -3980,14 +4020,14 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( SendPacketAndWaitForResponse(stream.GetString(), response, send_async); if (result == PacketResult::Success) { // We failed if the config result comes back other than OK. - if (strcmp(response.GetStringRef().c_str(), "OK") == 0) { + if (strcmp(response.GetStringRef().data(), "OK") == 0) { // Okay! error.Clear(); } else { error.SetErrorStringWithFormat("configuring StructuredData feature " "%s failed with error %s", type_name.AsCString(), - response.GetStringRef().c_str()); + response.GetStringRef().data()); } } else { // Can we get more data here on the failure? diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index de85c9f8b67b3..574cd0fd70c57 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -17,8 +17,9 @@ #include <string> #include <vector> +#include "lldb/Host/File.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/StructuredData.h" #if defined(_WIN32) #include "lldb/Host/windows/PosixApi.h" @@ -248,6 +249,8 @@ public: llvm::VersionTuple GetOSVersion(); + llvm::VersionTuple GetMacCatalystVersion(); + bool GetOSBuildString(std::string &s); bool GetOSKernelDescription(std::string &s); @@ -348,7 +351,7 @@ public: size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable); - lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, + lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, mode_t mode, Status &error); bool CloseFile(lldb::user_id_t fd, Status &error); @@ -548,6 +551,7 @@ protected: ArchSpec m_host_arch; ArchSpec m_process_arch; llvm::VersionTuple m_os_version; + llvm::VersionTuple m_maccatalyst_version; std::string m_os_build; std::string m_os_kernel; std::string m_hostname; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp index bcddb4faf8634..d2cc32f63f20a 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -18,12 +18,6 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; -void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const { - yaml::Output yout(strm); - yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this); - strm.flush(); -} - GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) : m_packets(), m_curr_idx(0), m_total_packet_count(0), m_dumped_to_log(false) { @@ -33,7 +27,8 @@ GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {} -void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type, +void GDBRemoteCommunicationHistory::AddPacket(char packet_char, + GDBRemotePacket::Type type, uint32_t bytes_transmitted) { const size_t size = m_packets.size(); if (size == 0) @@ -50,7 +45,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type, } void GDBRemoteCommunicationHistory::AddPacket(const std::string &src, - uint32_t src_len, PacketType type, + uint32_t src_len, + GDBRemotePacket::Type type, uint32_t bytes_transmitted) { const size_t size = m_packets.size(); if (size == 0) @@ -72,13 +68,12 @@ void GDBRemoteCommunicationHistory::Dump(Stream &strm) const { const uint32_t stop_idx = m_curr_idx + size; for (uint32_t i = first_idx; i < stop_idx; ++i) { const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + const GDBRemotePacket &entry = m_packets[idx]; + if (entry.type == GDBRemotePacket::ePacketTypeInvalid || + entry.packet.data.empty()) break; - strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.data.c_str()); + strm.Printf("history[%u] ", entry.packet_idx); + entry.Dump(strm); } } @@ -92,51 +87,15 @@ void GDBRemoteCommunicationHistory::Dump(Log *log) const { const uint32_t stop_idx = m_curr_idx + size; for (uint32_t i = first_idx; i < stop_idx; ++i) { const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + const GDBRemotePacket &entry = m_packets[idx]; + if (entry.type == GDBRemotePacket::ePacketTypeInvalid || + entry.packet.data.empty()) break; - log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.data.c_str()); + LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", + entry.packet_idx, entry.tid, entry.bytes_transmitted, + (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send" + : "read", + entry.packet.data.c_str()); } } -void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>:: - enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) { - io.enumCase(value, "Invalid", - GDBRemoteCommunicationHistory::ePacketTypeInvalid); - io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend); - io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv); -} - -void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>:: - output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *, - raw_ostream &Out) { - Out << toHex(Val.data); -} - -StringRef -yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input( - StringRef Scalar, void *, - GDBRemoteCommunicationHistory::Entry::BinaryData &Val) { - Val.data = fromHex(Scalar); - return {}; -} - -void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping( - IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { - io.mapRequired("packet", Entry.packet); - io.mapRequired("type", Entry.type); - io.mapRequired("bytes", Entry.bytes_transmitted); - io.mapRequired("index", Entry.packet_idx); - io.mapRequired("tid", Entry.tid); -} - -StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate( - IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { - if (Entry.bytes_transmitted != Entry.packet.data.size()) - return "BinaryData size doesn't match bytes transmitted"; - - return {}; -} diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h index 85f112b506236..c006fbd34a4b9 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "lldb/Utility/GDBRemote.h" #include "lldb/lldb-public.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" @@ -25,46 +26,17 @@ class GDBRemoteCommunicationHistory { public: friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>; - enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; - - /// Entry in the ring buffer containing the packet data, its type, size and - /// index. Entries can be serialized to file. - struct Entry { - Entry() - : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), - packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {} - - void Clear() { - packet.data.clear(); - type = ePacketTypeInvalid; - bytes_transmitted = 0; - packet_idx = 0; - tid = LLDB_INVALID_THREAD_ID; - } - - struct BinaryData { - std::string data; - }; - - void Serialize(llvm::raw_ostream &strm) const; - - BinaryData packet; - PacketType type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; - }; - GDBRemoteCommunicationHistory(uint32_t size = 0); ~GDBRemoteCommunicationHistory(); // For single char packets for ack, nack and /x03 - void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted); - - void AddPacket(const std::string &src, uint32_t src_len, PacketType type, + void AddPacket(char packet_char, GDBRemotePacket::Type type, uint32_t bytes_transmitted); + void AddPacket(const std::string &src, uint32_t src_len, + GDBRemotePacket::Type type, uint32_t bytes_transmitted); + void Dump(Stream &strm) const; void Dump(Log *log) const; bool DidDumpToLog() const { return m_dumped_to_log; } @@ -97,7 +69,7 @@ private: return m_packets.empty() ? 0 : i % m_packets.size(); } - std::vector<Entry> m_packets; + std::vector<GDBRemotePacket> m_packets; uint32_t m_curr_idx; uint32_t m_total_packet_count; mutable bool m_dumped_to_log; @@ -107,49 +79,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry) - -namespace llvm { -namespace yaml { - -template <> -struct ScalarEnumerationTraits<lldb_private::process_gdb_remote:: - GDBRemoteCommunicationHistory::PacketType> { - static void enumeration(IO &io, - lldb_private::process_gdb_remote:: - GDBRemoteCommunicationHistory::PacketType &value); -}; - -template <> -struct ScalarTraits<lldb_private::process_gdb_remote:: - GDBRemoteCommunicationHistory::Entry::BinaryData> { - static void output(const lldb_private::process_gdb_remote:: - GDBRemoteCommunicationHistory::Entry::BinaryData &, - void *, raw_ostream &); - - static StringRef - input(StringRef, void *, - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry:: - BinaryData &); - - static QuotingType mustQuote(StringRef S) { return QuotingType::None; } -}; - -template <> -struct MappingTraits< - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> { - static void - mapping(IO &io, - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry - &Entry); - - static StringRef validate( - IO &io, - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &); -}; - -} // namespace yaml -} // namespace llvm - #endif // liblldb_GDBRemoteCommunicationHistory_h_ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp index 417f5737a30ff..2d26c550dc76a 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -9,6 +9,7 @@ #include <errno.h> #include "lldb/Host/Config.h" +#include "llvm/ADT/ScopeExit.h" #include "GDBRemoteCommunicationReplayServer.h" #include "ProcessGDBRemoteLog.h" @@ -127,7 +128,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); while (!m_packet_history.empty()) { // Pop last packet from the history. - GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back(); + GDBRemotePacket entry = m_packet_history.back(); m_packet_history.pop_back(); // We've handled the handshake implicitly before. Skip the packet and move @@ -135,7 +136,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( if (entry.packet.data == "+") continue; - if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeSend) { + if (entry.type == GDBRemotePacket::ePacketTypeSend) { if (unexpected(entry.packet.data, packet.GetStringRef())) { LLDB_LOG(log, "GDBRemoteCommunicationReplayServer expected packet: '{0}'", @@ -149,14 +150,14 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( // Ignore QEnvironment packets as they're handled earlier. if (entry.packet.data.find("QEnvironment") == 1) { assert(m_packet_history.back().type == - GDBRemoteCommunicationHistory::ePacketTypeRecv); + GDBRemotePacket::ePacketTypeRecv); m_packet_history.pop_back(); } continue; } - if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeInvalid) { + if (entry.type == GDBRemotePacket::ePacketTypeInvalid) { LLDB_LOG( log, "GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'", @@ -175,10 +176,6 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( return packet_result; } -LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( - std::vector< - lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>) - llvm::Error GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) { auto error_or_file = MemoryBuffer::getFile(path.GetPath()); @@ -256,11 +253,10 @@ void GDBRemoteCommunicationReplayServer::ReceivePacket( thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { GDBRemoteCommunicationReplayServer *server = (GDBRemoteCommunicationReplayServer *)arg; - + auto D = make_scope_exit([&]() { server->Disconnect(); }); EventSP event_sp; bool done = false; - - while (true) { + while (!done) { if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { const uint32_t event_type = event_sp->GetType(); if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h index 26d65e265463b..0b5e910f7c6a6 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -62,7 +62,7 @@ protected: static lldb::thread_result_t AsyncThread(void *arg); /// Replay history with the oldest packet at the end. - std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history; + std::vector<GDBRemotePacket> m_packet_history; /// Server thread. Broadcaster m_async_broadcaster; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 49cbeb023fd55..ac6ecffcf854f 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -59,14 +59,13 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse( break; case StringExtractorGDBRemote::eServerPacketType_unimplemented: - packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str()); + packet_result = SendUnimplementedResponse(packet.GetStringRef().data()); break; default: auto handler_it = m_packet_handlers.find(packet_type); if (handler_it == m_packet_handlers.end()) - packet_result = - SendUnimplementedResponse(packet.GetStringRef().c_str()); + packet_result = SendUnimplementedResponse(packet.GetStringRef().data()); else packet_result = handler_it->second(packet, error, interrupt, quit); break; @@ -139,10 +138,9 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServer::SendIllFormedResponse( const StringExtractorGDBRemote &failed_packet, const char *message) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); - if (log) - log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", - __FUNCTION__, failed_packet.GetStringRef().c_str(), - message ? message : ""); + LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", + __FUNCTION__, failed_packet.GetStringRef().data(), + message ? message : ""); return SendErrorResponse(0x03); } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index d095c7a057ad4..37980d914dc2b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -29,12 +29,13 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Platform.h" #include "lldb/Utility/Endian.h" -#include "lldb/Utility/JSON.h" +#include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/JSON.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" @@ -43,11 +44,10 @@ #include "lldb/Host/android/HostInfoAndroid.h" #endif -#include "llvm/ADT/StringSwitch.h" using namespace lldb; -using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +using namespace lldb_private; #ifdef __ANDROID__ const static uint32_t g_default_packet_timeout_sec = 20; // seconds @@ -231,6 +231,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( #else if (host_arch.GetMachine() == llvm::Triple::aarch64 || + host_arch.GetMachine() == llvm::Triple::aarch64_32 || host_arch.GetMachine() == llvm::Triple::aarch64_be || host_arch.GetMachine() == llvm::Triple::arm || host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS()) @@ -260,6 +261,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( response.PutChar(';'); } +#if defined(__APPLE__) + llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion(); + if (!maccatalyst_version.empty()) { + response.Format("maccatalyst_version:{0}", + maccatalyst_version.getAsString()); + response.PutChar(';'); + } +#endif + std::string s; if (HostInfo::GetOSBuildString(s)) { response.PutCString("os_build:"); @@ -421,8 +431,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName( StringExtractorGDBRemote &packet) { #if !defined(LLDB_DISABLE_POSIX) Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); // Packet format: "qUserName:%i" where %i is the uid packet.SetFilePos(::strlen("qUserName:")); @@ -435,8 +444,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName( return SendPacketNoLock(response.GetString()); } } - if (log) - log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); #endif return SendErrorResponse(5); } @@ -500,19 +508,32 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( packet.GetHexByteStringTerminatedBy(path, ','); if (!path.empty()) { if (packet.GetChar() == ',') { - uint32_t flags = packet.GetHexMaxU32(false, 0); + // FIXME + // The flag values for OpenOptions do not match the values used by GDB + // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags + // * rdar://problem/46788934 + auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); FileSpec path_spec(path); FileSystem::Instance().Resolve(path_spec); - File file; // Do not close fd. - Status error = - FileSystem::Instance().Open(file, path_spec, flags, mode, false); - const int save_errno = error.GetError(); + auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); + + int save_errno = 0; + int descriptor = File::kInvalidDescriptor; + if (file) { + descriptor = file.get()->GetDescriptor(); + } else { + std::error_code code = errorToErrorCode(file.takeError()); + if (code.category() == std::system_category()) { + save_errno = code.value(); + } + } + StreamString response; response.PutChar('F'); - response.Printf("%i", file.GetDescriptor()); + response.Printf("%i", descriptor); if (save_errno) response.Printf(",%i", save_errno); return SendPacketNoLock(response.GetString()); @@ -530,7 +551,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close( int err = -1; int save_errno = 0; if (fd >= 0) { - File file(fd, true); + NativeFile file(fd, File::OpenOptions(0), true); Status error = file.Close(); err = 0; save_errno = error.GetError(); @@ -552,16 +573,16 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( packet.SetFilePos(::strlen("vFile:pread:")); int fd = packet.GetS32(-1); if (packet.GetChar() == ',') { - size_t count = packet.GetU64(UINT64_MAX); + size_t count = packet.GetU64(SIZE_MAX); if (packet.GetChar() == ',') { off_t offset = packet.GetU64(UINT32_MAX); - if (count == UINT64_MAX) { + if (count == SIZE_MAX) { response.Printf("F-1:%i", EINVAL); return SendPacketNoLock(response.GetString()); } std::string buffer(count, 0); - File file(fd, false); + NativeFile file(fd, File::eOpenOptionRead, false); Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset); const ssize_t bytes_read = error.Success() ? count : -1; const int save_errno = error.GetError(); @@ -593,7 +614,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( if (packet.GetChar() == ',') { std::string buffer; if (packet.GetEscapedBinaryData(buffer)) { - File file(fd, false); + NativeFile file(fd, File::eOpenOptionWrite, false); size_t count = buffer.size(); Status error = file.Write(static_cast<const void *>(&buffer[0]), count, offset); @@ -825,6 +846,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported( #if defined(__linux__) || defined(__NetBSD__) response.PutCString(";QPassSignals+"); response.PutCString(";qXfer:auxv:read+"); + response.PutCString(";qXfer:libraries-svr4:read+"); #endif return SendPacketNoLock(response.GetString()); @@ -1016,9 +1038,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { m_process_launch_info.GetExecutableFile().SetFile( arg, FileSpec::Style::native); m_process_launch_info.GetArguments().AppendArgument(arg); - if (log) - log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"", - __FUNCTION__, actual_arg_index, arg.c_str()); + LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"", + __FUNCTION__, actual_arg_index, arg.c_str()); ++actual_arg_index; } } @@ -1104,6 +1125,8 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( StringExtractorGDBRemote &packet) { + namespace json = llvm::json; + packet.SetFilePos(::strlen("jModulesInfo:")); StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek()); @@ -1114,7 +1137,7 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( if (!packet_array) return SendErrorResponse(2); - JSONArray::SP response_array_sp = std::make_shared<JSONArray>(); + json::Array response_array; for (size_t i = 0; i < packet_array->GetSize(); ++i) { StructuredData::Dictionary *query = packet_array->GetItemAtIndex(i)->GetAsDictionary(); @@ -1132,27 +1155,22 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo( const auto file_offset = matched_module_spec.GetObjectOffset(); const auto file_size = matched_module_spec.GetObjectSize(); const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); - if (uuid_str.empty()) continue; - - JSONObject::SP response = std::make_shared<JSONObject>(); - response_array_sp->AppendObject(response); - response->SetObject("uuid", std::make_shared<JSONString>(uuid_str)); - response->SetObject( - "triple", - std::make_shared<JSONString>( - matched_module_spec.GetArchitecture().GetTriple().getTriple())); - response->SetObject("file_path", - std::make_shared<JSONString>( - matched_module_spec.GetFileSpec().GetPath())); - response->SetObject("file_offset", - std::make_shared<JSONNumber>(file_offset)); - response->SetObject("file_size", std::make_shared<JSONNumber>(file_size)); + const auto triple_str = + matched_module_spec.GetArchitecture().GetTriple().getTriple(); + const auto file_path = matched_module_spec.GetFileSpec().GetPath(); + + json::Object response{{"uuid", uuid_str}, + {"triple", triple_str}, + {"file_path", file_path}, + {"file_offset", static_cast<int64_t>(file_offset)}, + {"file_size", static_cast<int64_t>(file_size)}}; + response_array.push_back(std::move(response)); } StreamString response; - response_array_sp->Write(response); + response.AsRawOstream() << std::move(response_array); StreamGDBRemote escaped_response; escaped_response.PutEscapedBytes(response.GetString().data(), response.GetSize()); @@ -1168,6 +1186,15 @@ void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); response.PutCString("name:"); response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); + + response.PutChar(';'); + response.PutCString("args:"); + response.PutStringAsRawHex8(proc_info.GetArg0()); + for (auto &arg : proc_info.GetArguments()) { + response.PutChar('-'); + response.PutStringAsRawHex8(arg.ref()); + } + response.PutChar(';'); const ArchSpec &proc_arch = proc_info.GetArchitecture(); if (proc_arch.IsValid()) { @@ -1217,6 +1244,7 @@ void GDBRemoteCommunicationServerCommon:: case llvm::Triple::arm: case llvm::Triple::thumb: case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: ostype = "ios"; break; default: diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 196607665bbaf..ad1a39b579699 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -11,7 +11,7 @@ #include "lldb/Host/Config.h" #include "GDBRemoteCommunicationServerLLGS.h" -#include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/GDBRemote.h" #include <chrono> #include <cstring> @@ -32,7 +32,6 @@ #include "lldb/Utility/Args.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/RegisterValue.h" @@ -40,6 +39,7 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" #include "ProcessGDBRemote.h" @@ -217,8 +217,13 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); if (should_forward_stdio) { + // Temporarily relax the following for Windows until we can take advantage + // of the recently added pty support. This doesn't really affect the use of + // lldb-server on Windows. +#if !defined(_WIN32) if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) return Status(std::move(Err)); +#endif } { @@ -249,18 +254,18 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { // Setup stdout/stderr mapping from inferior to $O auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor(); if (terminal_fd >= 0) { - if (log) - log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting " - "inferior STDIO fd to %d", - __FUNCTION__, terminal_fd); + LLDB_LOGF(log, + "ProcessGDBRemoteCommunicationServerLLGS::%s setting " + "inferior STDIO fd to %d", + __FUNCTION__, terminal_fd); Status status = SetSTDIOFileDescriptor(terminal_fd); if (status.Fail()) return status; } else { - if (log) - log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " - "inferior STDIO since terminal fd reported as %d", - __FUNCTION__, terminal_fd); + LLDB_LOGF(log, + "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " + "inferior STDIO since terminal fd reported as %d", + __FUNCTION__, terminal_fd); } } else { LLDB_LOG(log, @@ -278,9 +283,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, - __FUNCTION__, pid); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, + __FUNCTION__, pid); // Before we try to attach, make sure we aren't already monitoring something // else. @@ -304,18 +308,18 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { // Setup stdout/stderr mapping from inferior. auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor(); if (terminal_fd >= 0) { - if (log) - log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting " - "inferior STDIO fd to %d", - __FUNCTION__, terminal_fd); + LLDB_LOGF(log, + "ProcessGDBRemoteCommunicationServerLLGS::%s setting " + "inferior STDIO fd to %d", + __FUNCTION__, terminal_fd); Status status = SetSTDIOFileDescriptor(terminal_fd); if (status.Fail()) return status; } else { - if (log) - log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " - "inferior STDIO since terminal fd reported as %d", - __FUNCTION__, terminal_fd); + LLDB_LOGF(log, + "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " + "inferior STDIO since terminal fd reported as %d", + __FUNCTION__, terminal_fd); } printf("Attached to process %" PRIu64 "...\n", pid); @@ -327,10 +331,11 @@ void GDBRemoteCommunicationServerLLGS::InitializeDelegate( assert(process && "process cannot be NULL"); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); if (log) { - log->Printf("GDBRemoteCommunicationServerLLGS::%s called with " - "NativeProcessProtocol pid %" PRIu64 ", current state: %s", - __FUNCTION__, process->GetID(), - StateAsCString(process->GetState())); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s called with " + "NativeProcessProtocol pid %" PRIu64 ", current state: %s", + __FUNCTION__, process->GetID(), + StateAsCString(process->GetState())); } } @@ -397,19 +402,21 @@ static void WriteRegisterValueInHexFixedWidth( } } -static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { +static llvm::Expected<json::Object> +GetRegistersAsJSON(NativeThreadProtocol &thread) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); - JSONObject::SP register_object_sp = std::make_shared<JSONObject>(); + json::Object register_object; #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET // Expedite all registers in the first register set (i.e. should be GPRs) // that are not contained in other registers. const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0); if (!reg_set_p) - return nullptr; + return llvm::make_error<llvm::StringError>("failed to get registers", + llvm::inconvertibleErrorCode()); for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { uint32_t reg_num = *reg_num_p; @@ -431,10 +438,9 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { const RegisterInfo *const reg_info_p = reg_ctx.GetRegisterInfoAtIndex(reg_num); if (reg_info_p == nullptr) { - if (log) - log->Printf( - "%s failed to get register info for register index %" PRIu32, - __FUNCTION__, reg_num); + LLDB_LOGF(log, + "%s failed to get register info for register index %" PRIu32, + __FUNCTION__, reg_num); continue; } @@ -445,11 +451,10 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { RegisterValue reg_value; Status error = reg_ctx.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_num, error.AsCString()); + LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", + __FUNCTION__, + reg_info_p->name ? reg_info_p->name : "<unnamed-register>", + reg_num, error.AsCString()); continue; } @@ -457,12 +462,11 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p, ®_value, lldb::eByteOrderBig); - register_object_sp->SetObject( - llvm::to_string(reg_num), - std::make_shared<JSONString>(stream.GetString())); + register_object.try_emplace(llvm::to_string(reg_num), + stream.GetString().str()); } - return register_object_sp; + return register_object; } static const char *GetStopReasonString(StopReason stop_reason) { @@ -489,11 +493,11 @@ static const char *GetStopReasonString(StopReason stop_reason) { return nullptr; } -static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, - bool abridged) { +static llvm::Expected<json::Array> +GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); - JSONArray::SP threads_array_sp = std::make_shared<JSONArray>(); + json::Array threads_array; // Ensure we can get info on the given thread. uint32_t thread_idx = 0; @@ -507,61 +511,62 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, struct ThreadStopInfo tid_stop_info; std::string description; if (!thread->GetStopReason(tid_stop_info, description)) - return nullptr; + return llvm::make_error<llvm::StringError>( + "failed to get stop reason", llvm::inconvertibleErrorCode()); const int signum = tid_stop_info.details.signal.signo; if (log) { - log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 - " tid %" PRIu64 - " got signal signo = %d, reason = %d, exc_type = %" PRIu64, - __FUNCTION__, process.GetID(), tid, signum, - tid_stop_info.reason, tid_stop_info.details.exception.type); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 + " tid %" PRIu64 + " got signal signo = %d, reason = %d, exc_type = %" PRIu64, + __FUNCTION__, process.GetID(), tid, signum, + tid_stop_info.reason, tid_stop_info.details.exception.type); } - JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>(); - threads_array_sp->AppendObject(thread_obj_sp); + json::Object thread_obj; if (!abridged) { - if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread)) - thread_obj_sp->SetObject("registers", registers_sp); + if (llvm::Expected<json::Object> registers = + GetRegistersAsJSON(*thread)) { + thread_obj.try_emplace("registers", std::move(*registers)); + } else { + return registers.takeError(); + } } - thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid)); + thread_obj.try_emplace("tid", static_cast<int64_t>(tid)); + if (signum != 0) - thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum)); + thread_obj.try_emplace("signal", signum); const std::string thread_name = thread->GetName(); if (!thread_name.empty()) - thread_obj_sp->SetObject("name", - std::make_shared<JSONString>(thread_name)); + thread_obj.try_emplace("name", thread_name); - if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason)) - thread_obj_sp->SetObject("reason", - std::make_shared<JSONString>(stop_reason_str)); + const char *stop_reason = GetStopReasonString(tid_stop_info.reason); + if (stop_reason) + thread_obj.try_emplace("reason", stop_reason); if (!description.empty()) - thread_obj_sp->SetObject("description", - std::make_shared<JSONString>(description)); + thread_obj.try_emplace("description", description); if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type) { - thread_obj_sp->SetObject( - "metype", - std::make_shared<JSONNumber>(tid_stop_info.details.exception.type)); + thread_obj.try_emplace( + "metype", static_cast<int64_t>(tid_stop_info.details.exception.type)); - JSONArray::SP medata_array_sp = std::make_shared<JSONArray>(); + json::Array medata_array; for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) { - medata_array_sp->AppendObject(std::make_shared<JSONNumber>( - tid_stop_info.details.exception.data[i])); + medata_array.push_back( + static_cast<int64_t>(tid_stop_info.details.exception.data[i])); } - thread_obj_sp->SetObject("medata", medata_array_sp); + thread_obj.try_emplace("medata", std::move(medata_array)); } - - // TODO: Expedite interesting regions of inferior memory + threads_array.push_back(std::move(thread_obj)); } - - return threads_array_sp; + return threads_array; } GDBRemoteCommunication::PacketResult @@ -653,19 +658,21 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( // is hex ascii JSON that contains the thread IDs thread stop info only for // threads that have stop reasons. Only send this if we have more than one // thread otherwise this packet has all the info it needs. - if (thread_index > 0) { + if (thread_index > 1) { const bool threads_with_valid_stop_info_only = true; - JSONArray::SP threads_info_sp = GetJSONThreadsInfo( + llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( *m_debugged_process_up, threads_with_valid_stop_info_only); - if (threads_info_sp) { + if (threads_info) { response.PutCString("jstopinfo:"); StreamString unescaped_response; - threads_info_sp->Write(unescaped_response); + unescaped_response.AsRawOstream() << std::move(*threads_info); response.PutStringAsRawHex8(unescaped_response.GetData()); response.PutChar(';'); - } else - LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}", - m_debugged_process_up->GetID()); + } else { + LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}:", + m_debugged_process_up->GetID(), + llvm::toString(threads_info.takeError())); + } } uint32_t i = 0; @@ -684,12 +691,10 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( RegisterValue reg_value; Status error = reg_ctx.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()); + LLDB_LOGF(log, "%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; } @@ -713,25 +718,24 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( const RegisterSet *reg_set_p; if (reg_ctx.GetRegisterSetCount() > 0 && ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers " - "from set '%s' (registers set count: %zu)", - __FUNCTION__, - reg_set_p->name ? reg_set_p->name : "<unnamed-set>", - reg_set_p->num_registers); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s expediting registers " + "from set '%s' (registers set count: %zu)", + __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", + reg_set_p->num_registers); for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { const RegisterInfo *const reg_info_p = reg_ctx.GetRegisterInfoAtIndex(*reg_num_p); if (reg_info_p == nullptr) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get " - "register info for register set '%s', register index " - "%" PRIu32, - __FUNCTION__, - reg_set_p->name ? reg_set_p->name : "<unnamed-set>", - *reg_num_p); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to get " + "register info for register set '%s', register index " + "%" PRIu32, + __FUNCTION__, + reg_set_p->name ? reg_set_p->name : "<unnamed-set>", + *reg_num_p); } else if (reg_info_p->value_regs == nullptr) { // Only expediate registers that are not contained in other registers. RegisterValue reg_value; @@ -742,13 +746,12 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( ®_value, lldb::eByteOrderBig); response.PutChar(';'); } else { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read " - "register '%s' index %" PRIu32 ": %s", - __FUNCTION__, - reg_info_p->name ? reg_info_p->name - : "<unnamed-register>", - *reg_num_p, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to read " + "register '%s' index %" PRIu32 ": %s", + __FUNCTION__, + reg_info_p->name ? reg_info_p->name : "<unnamed-register>", + *reg_num_p, error.AsCString()); } } } @@ -787,15 +790,14 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( assert(process && "process cannot be NULL"); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); PacketResult result = SendStopReasonForState(StateType::eStateExited); if (result != PacketResult::Success) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop " - "notification for PID %" PRIu64 ", state: eStateExited", - __FUNCTION__, process->GetID()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to send stop " + "notification for PID %" PRIu64 ", state: eStateExited", + __FUNCTION__, process->GetID()); } // Close the pipe to the inferior terminal i/o if we launched it and set one @@ -812,8 +814,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( assert(process && "process cannot be NULL"); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); // Send the stop reason unless this is the stop after the launch or attach. switch (m_inferior_prev_state) { @@ -825,10 +826,10 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( // In all other cases, send the stop reason. PacketResult result = SendStopReasonForState(StateType::eStateStopped); if (result != PacketResult::Success) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop " - "notification for PID %" PRIu64 ", state: eStateExited", - __FUNCTION__, process->GetID()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to send stop " + "notification for PID %" PRIu64 ", state: eStateExited", + __FUNCTION__, process->GetID()); } break; } @@ -839,9 +840,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( assert(process && "process cannot be NULL"); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); if (log) { - log->Printf("GDBRemoteCommunicationServerLLGS::%s called with " - "NativeProcessProtocol pid %" PRIu64 ", state: %s", - __FUNCTION__, process->GetID(), StateAsCString(state)); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s called with " + "NativeProcessProtocol pid %" PRIu64 ", state: %s", + __FUNCTION__, process->GetID(), StateAsCString(state)); } switch (state) { @@ -868,9 +870,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( default: if (log) { - log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state " - "change for pid %" PRIu64 ", new state: %s", - __FUNCTION__, process->GetID(), StateAsCString(state)); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s didn't handle state " + "change for pid %" PRIu64 ", new state: %s", + __FUNCTION__, process->GetID(), StateAsCString(state)); } break; } @@ -888,10 +891,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { if (!m_handshake_completed) { if (!HandshakeWithClient()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with " - "client failed, exiting", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s handshake with " + "client failed, exiting", + __FUNCTION__); m_mainloop.RequestTermination(); return; } @@ -908,10 +911,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { break; // No more packets in the queue if ((result != PacketResult::Success)) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet " - "failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s processing a packet " + "failed: %s", + __FUNCTION__, error.AsCString()); m_mainloop.RequestTermination(); break; } @@ -982,9 +985,10 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { // Not much we can do about the failure. Log it and continue without // forwarding. if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) - log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio " - "forwarding: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio " + "forwarding: %s", + __FUNCTION__, error.AsCString()); } } @@ -1008,10 +1012,11 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { case eConnectionStatusError: case eConnectionStatusNoConnection: if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) - log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio " - "forwarding as communication returned status %d (error: " - "%s)", - __FUNCTION__, status, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s Stopping stdio " + "forwarding as communication returned status %d (error: " + "%s)", + __FUNCTION__, status, error.AsCString()); m_stdio_handle_up.reset(); return; @@ -1349,15 +1354,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); // Ensure we have a native process. if (!m_debugged_process_up) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process " - "shared pointer", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s no debugged process " + "shared pointer", + __FUNCTION__); return SendErrorResponse(0x36); } @@ -1376,13 +1380,14 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { if (packet.GetBytesLeft() > 0) { // FIXME add continue at address support for $C{signo}[;{continue-address}]. if (*packet.Peek() == ';') - return SendUnimplementedResponse(packet.GetStringRef().c_str()); + return SendUnimplementedResponse(packet.GetStringRef().data()); else return SendIllFormedResponse( packet, "unexpected content after $C{signal-number}"); } - ResumeActionList resume_actions(StateType::eStateRunning, 0); + ResumeActionList resume_actions(StateType::eStateRunning, + LLDB_INVALID_SIGNAL_NUMBER); Status error; // We have two branches: what to do if a continue thread is specified (in @@ -1430,8 +1435,7 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); packet.SetFilePos(packet.GetFilePos() + ::strlen("c")); @@ -1440,20 +1444,21 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { if (has_continue_address) { LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]", packet.Peek()); - return SendUnimplementedResponse(packet.GetStringRef().c_str()); + return SendUnimplementedResponse(packet.GetStringRef().data()); } // Ensure we have a native process. if (!m_debugged_process_up) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process " - "shared pointer", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s no debugged process " + "shared pointer", + __FUNCTION__); return SendErrorResponse(0x36); } // Build the ResumeActionList - ResumeActionList actions(StateType::eStateRunning, 0); + ResumeActionList actions(StateType::eStateRunning, + LLDB_INVALID_SIGNAL_NUMBER); Status error = m_debugged_process_up->Resume(actions); if (error.Fail()) { @@ -1480,17 +1485,16 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_vCont( StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", - __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet", + __FUNCTION__); packet.SetFilePos(::strlen("vCont")); if (packet.GetBytesLeft() == 0) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from " - "vCont package", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s missing action from " + "vCont package", + __FUNCTION__); return SendIllFormedResponse(packet, "Missing action from vCont package"); } @@ -1521,7 +1525,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont( ResumeAction thread_action; thread_action.tid = LLDB_INVALID_THREAD_ID; thread_action.state = eStateInvalid; - thread_action.signal = 0; + thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER; const char action = packet.GetChar(); switch (action) { @@ -1958,10 +1962,10 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { const uint32_t reg_index = packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); if (reg_index == std::numeric_limits<uint32_t>::max()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " - "parse register number from request \"%s\"", - __FUNCTION__, packet.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, could not " + "parse register number from request \"%s\"", + __FUNCTION__, packet.GetStringRef().data()); return SendErrorResponse(0x15); } @@ -1978,20 +1982,19 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { // Return the end of registers response if we've iterated one past the end of // the register set. if (reg_index >= reg_context.GetUserRegisterCount()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " - "register %" PRIu32 " beyond register count %" PRIu32, - __FUNCTION__, reg_index, - reg_context.GetUserRegisterCount()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, requested " + "register %" PRIu32 " beyond register count %" PRIu32, + __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); return SendErrorResponse(0x15); } const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); if (!reg_info) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " - "register %" PRIu32 " returned NULL", - __FUNCTION__, reg_index); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, requested " + "register %" PRIu32 " returned NULL", + __FUNCTION__, reg_index); return SendErrorResponse(0x15); } @@ -2002,20 +2005,20 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { RegisterValue reg_value; Status error = reg_context.ReadRegister(reg_info, reg_value); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of " - "requested register %" PRIu32 " (%s) failed: %s", - __FUNCTION__, reg_index, reg_info->name, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, read of " + "requested register %" PRIu32 " (%s) failed: %s", + __FUNCTION__, reg_index, reg_info->name, error.AsCString()); return SendErrorResponse(0x15); } const uint8_t *const data = reinterpret_cast<const uint8_t *>(reg_value.GetBytes()); if (!data) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data " - "bytes from requested register %" PRIu32, - __FUNCTION__, reg_index); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to get data " + "bytes from requested register %" PRIu32, + __FUNCTION__, reg_index); return SendErrorResponse(0x15); } @@ -2039,10 +2042,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { const uint32_t reg_index = packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); if (reg_index == std::numeric_limits<uint32_t>::max()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " - "parse register number from request \"%s\"", - __FUNCTION__, packet.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, could not " + "parse register number from request \"%s\"", + __FUNCTION__, packet.GetStringRef().data()); return SendErrorResponse(0x29); } @@ -2058,10 +2061,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { // Get the thread to use. NativeThreadProtocol *thread = GetThreadFromSuffix(packet); if (!thread) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread " - "available (thread index 0)", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, no thread " + "available (thread index 0)", + __FUNCTION__); return SendErrorResponse(0x28); } @@ -2069,20 +2072,20 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { NativeRegisterContext ®_context = thread->GetRegisterContext(); const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); if (!reg_info) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " - "register %" PRIu32 " returned NULL", - __FUNCTION__, reg_index); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, requested " + "register %" PRIu32 " returned NULL", + __FUNCTION__, reg_index); return SendErrorResponse(0x48); } // Return the end of registers response if we've iterated one past the end of // the register set. if (reg_index >= reg_context.GetUserRegisterCount()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " - "register %" PRIu32 " beyond register count %" PRIu32, - __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, requested " + "register %" PRIu32 " beyond register count %" PRIu32, + __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); return SendErrorResponse(0x47); } @@ -2101,10 +2104,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { m_debugged_process_up->GetArchitecture().GetByteOrder()); Status error = reg_context.WriteRegister(reg_info, reg_value); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of " - "requested register %" PRIu32 " (%s) failed: %s", - __FUNCTION__, reg_index, reg_info->name, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, write of " + "requested register %" PRIu32 " (%s) failed: %s", + __FUNCTION__, reg_index, reg_info->name, error.AsCString()); return SendErrorResponse(0x32); } @@ -2118,20 +2121,20 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } // Parse out which variant of $H is requested. packet.SetFilePos(strlen("H")); if (packet.GetBytesLeft() < 1) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command " - "missing {g,c} variant", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, H command " + "missing {g,c} variant", + __FUNCTION__); return SendIllFormedResponse(packet, "H command missing {g,c} variant"); } @@ -2144,10 +2147,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { break; default: - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", - __FUNCTION__, h_variant); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", + __FUNCTION__, h_variant); return SendIllFormedResponse(packet, "H variant unsupported, should be c or g"); } @@ -2162,10 +2165,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); if (!thread) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 - " not found", - __FUNCTION__, tid); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 + " not found", + __FUNCTION__, tid); return SendErrorResponse(0x15); } } @@ -2196,10 +2199,10 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -2257,10 +2260,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -2284,10 +2287,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( const uint64_t byte_count = packet.GetHexMaxU64(false, 0); if (byte_count == 0) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: " - "zero-length packet", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s nothing to read: " + "zero-length packet", + __FUNCTION__); return SendOKResponse(); } @@ -2301,20 +2304,20 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read( Status error = m_debugged_process_up->ReadMemoryWithoutTrap( read_addr, &buf[0], byte_count, bytes_read); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 - " mem 0x%" PRIx64 ": failed to read. Error: %s", - __FUNCTION__, m_debugged_process_up->GetID(), read_addr, - error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 + " mem 0x%" PRIx64 ": failed to read. Error: %s", + __FUNCTION__, m_debugged_process_up->GetID(), read_addr, + error.AsCString()); return SendErrorResponse(0x08); } if (bytes_read == 0) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 - " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", - __FUNCTION__, m_debugged_process_up->GetID(), read_addr, - byte_count); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 + " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", + __FUNCTION__, m_debugged_process_up->GetID(), read_addr, + byte_count); return SendErrorResponse(0x08); } @@ -2338,10 +2341,10 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -2426,10 +2429,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( // since we won't have a NativeProcessProtocol. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -2454,10 +2457,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( // Ensure we have a process. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -2703,10 +2706,10 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { // Ensure we have a process. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x32); } @@ -2725,7 +2728,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { return SendErrorResponse(0x33); // Create the step action for the given thread. - ResumeAction action = {tid, eStateStepping, 0}; + ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER}; // Setup the actions list. ResumeActionList actions; @@ -2735,11 +2738,11 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); Status error = m_debugged_process_up->Resume(actions); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 - " tid %" PRIu64 " Resume() failed with error: %s", - __FUNCTION__, m_debugged_process_up->GetID(), tid, - error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 + " tid %" PRIu64 " Resume() failed with error: %s", + __FUNCTION__, m_debugged_process_up->GetID(), tid, + error.AsCString()); return SendErrorResponse(0x49); } @@ -2765,6 +2768,24 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, return std::move(*buffer_or_error); } + if (object == "libraries-svr4") { + auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries(); + if (!library_list) + return library_list.takeError(); + + StreamString response; + response.Printf("<library-list-svr4 version=\"1.0\">"); + for (auto const &library : *library_list) { + response.Printf("<library name=\"%s\" ", + XMLEncodeAttributeValue(library.name.c_str()).c_str()); + response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map); + response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr); + response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr); + } + response.Printf("</library-list-svr4>"); + return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__); + } + return llvm::make_error<PacketUnimplementedError>( "Xfer object not supported"); } @@ -2968,18 +2989,18 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach( "vAttach failed to parse the process id"); // Attempt to attach. - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to " - "pid %" PRIu64, - __FUNCTION__, pid); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s attempting to attach to " + "pid %" PRIu64, + __FUNCTION__, pid); Status error = AttachToProcess(pid); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to " - "pid %" PRIu64 ": %s\n", - __FUNCTION__, pid, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to attach to " + "pid %" PRIu64 ": %s\n", + __FUNCTION__, pid, error.AsCString()); return SendErrorResponse(error); } @@ -2996,10 +3017,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { // Fail if we don't have a current process. if (!m_debugged_process_up || (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - if (log) - log->Printf( - "GDBRemoteCommunicationServerLLGS::%s failed, no process available", - __FUNCTION__); + LLDB_LOGF( + log, + "GDBRemoteCommunicationServerLLGS::%s failed, no process available", + __FUNCTION__); return SendErrorResponse(0x15); } @@ -3023,11 +3044,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { const Status error = m_debugged_process_up->Detach(); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from " - "pid %" PRIu64 ": %s\n", - __FUNCTION__, m_debugged_process_up->GetID(), - error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed to detach from " + "pid %" PRIu64 ": %s\n", + __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString()); return SendErrorResponse(0x01); } @@ -3042,10 +3062,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( packet.SetFilePos(strlen("qThreadStopInfo")); const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); if (tid == LLDB_INVALID_THREAD_ID) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " - "parse thread id from request \"%s\"", - __FUNCTION__, packet.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s failed, could not " + "parse thread id from request \"%s\"", + __FUNCTION__, packet.GetStringRef().data()); return SendErrorResponse(0x15); } return SendStopReplyPacketForThread(tid); @@ -3064,15 +3084,16 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( StreamString response; const bool threads_with_valid_stop_info_only = false; - JSONArray::SP threads_array_sp = GetJSONThreadsInfo( + llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo( *m_debugged_process_up, threads_with_valid_stop_info_only); - if (!threads_array_sp) { - LLDB_LOG(log, "failed to prepare a packet for pid {0}", - m_debugged_process_up->GetID()); + if (!threads_info) { + LLDB_LOG(log, "failed to prepare a packet for pid {0}: {1}", + m_debugged_process_up->GetID(), + llvm::toString(threads_info.takeError())); return SendErrorResponse(52); } - threads_array_sp->Write(response); + response.AsRawOstream() << *threads_info; StreamGDBRemote escaped_response; escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); return SendPacketNoLock(escaped_response.GetString()); @@ -3177,15 +3198,15 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { connection->Disconnect(&error); if (error.Success()) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process " - "terminal stdio - SUCCESS", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s disconnect process " + "terminal stdio - SUCCESS", + __FUNCTION__); } else { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process " - "terminal stdio - FAIL: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s disconnect process " + "terminal stdio - FAIL: %s", + __FUNCTION__, error.AsCString()); } } } @@ -3215,11 +3236,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( // Parse out the ';'. if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " - "error: expected ';' prior to start of thread suffix: packet " - "contents = '%s'", - __FUNCTION__, packet.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " + "error: expected ';' prior to start of thread suffix: packet " + "contents = '%s'", + __FUNCTION__, packet.GetStringRef().data()); return nullptr; } @@ -3228,11 +3249,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( // Parse out thread: portion. if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " - "error: expected 'thread:' but not found, packet contents = " - "'%s'", - __FUNCTION__, packet.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " + "error: expected 'thread:' but not found, packet contents = " + "'%s'", + __FUNCTION__, packet.GetStringRef().data()); return nullptr; } packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); @@ -3283,3 +3304,28 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch); } + +std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue( + llvm::StringRef value) { + std::string result; + for (const char &c : value) { + switch (c) { + case '\'': + result += "'"; + break; + case '"': + result += """; + break; + case '<': + result += "<"; + break; + case '>': + result += ">"; + break; + default: + result += c; + break; + } + } + return result; +} diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 068ea52caaaf0..088ba92ad11ac 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -196,6 +196,8 @@ protected: llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> ReadXferObject(llvm::StringRef object, llvm::StringRef annex); + static std::string XMLEncodeAttributeValue(llvm::StringRef value); + private: void HandleInferiorState_Exited(NativeProcessProtocol *process); diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 6deb75f2f0211..25cebbba8f7b3 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -15,8 +15,10 @@ #include <cstring> #include <mutex> #include <sstream> +#include <thread> #include "llvm/Support/FileSystem.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/Threading.h" #include "lldb/Host/Config.h" @@ -26,9 +28,8 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Target/Platform.h" #include "lldb/Target/UnixSignals.h" -#include "lldb/Utility/JSON.h" +#include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UriParser.h" @@ -36,8 +37,8 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" using namespace lldb; -using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +using namespace lldb_private; // GDBRemoteCommunicationServerPlatform constructor GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform( @@ -104,8 +105,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( hostname = "127.0.0.1"; Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) - log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port); + LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(), + port); // Do not run in a new session so that it can not linger after the platform // closes. @@ -161,9 +162,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( // process... Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) - log->Printf("GDBRemoteCommunicationServerPlatform::%s() called", - __FUNCTION__); + LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called", + __FUNCTION__); ConnectionFileDescriptor file_conn; std::string hostname; @@ -183,17 +183,17 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( Status error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name); if (error.Fail()) { - if (log) - log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver " - "launch failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerPlatform::%s() debugserver " + "launch failed: %s", + __FUNCTION__, error.AsCString()); return SendErrorResponse(9); } - if (log) - log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver " - "launched successfully as pid %" PRIu64, - __FUNCTION__, debugserver_pid); + LLDB_LOGF(log, + "GDBRemoteCommunicationServerPlatform::%s() debugserver " + "launched successfully as pid %" PRIu64, + __FUNCTION__, debugserver_pid); StreamGDBRemote response; response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, @@ -215,22 +215,21 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer( StringExtractorGDBRemote &packet) { + namespace json = llvm::json; + if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID) return SendErrorResponse(4); - JSONObject::SP server_sp = std::make_shared<JSONObject>(); - server_sp->SetObject("port", - std::make_shared<JSONNumber>(m_pending_gdb_server.port)); + json::Object server{{"port", m_pending_gdb_server.port}}; + if (!m_pending_gdb_server.socket_name.empty()) - server_sp->SetObject( - "socket_name", - std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str())); + server.try_emplace("socket_name", m_pending_gdb_server.socket_name); - JSONArray server_list; - server_list.AppendObject(server_sp); + json::Array server_list; + server_list.push_back(std::move(server)); StreamGDBRemote response; - server_list.Write(response); + response.AsRawOstream() << std::move(server_list); StreamGDBRemote escaped_response; escaped_response.PutEscapedBytes(response.GetString().data(), @@ -281,10 +280,9 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) { return true; } } - usleep(10000); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - // check one more time after the final usleep { std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); if (m_spawned_pids.find(pid) == m_spawned_pids.end()) @@ -303,10 +301,10 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) { return true; } } - usleep(10000); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - // check one more time after the final usleep Scope for locker + // check one more time after the final sleep { std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); if (m_spawned_pids.find(pid) == m_spawned_pids.end()) diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index a77e659a55fa2..c06c9527708ed 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -206,11 +206,14 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, } else { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - log->Printf ("error: GDBRemoteRegisterContext::ReadRegisterBytes tried to read the " - "entire register context at once, expected at least %" PRId64 " bytes " - "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(), - buffer_sp->GetByteSize()); + LLDB_LOGF( + log, + "error: GDBRemoteRegisterContext::ReadRegisterBytes tried " + "to read the " + "entire register context at once, expected at least %" PRId64 + " bytes " + "but only got %" PRId64 " bytes.", + m_reg_data.GetByteSize(), buffer_sp->GetByteSize()); } } return false; @@ -390,13 +393,15 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, if (log->GetVerbose()) { StreamString strm; gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending " - "write register for \"%s\":\n%s", - reg_info->name, strm.GetData()); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "write register for \"%s\":\n%s", + reg_info->name, strm.GetData()); } else - log->Printf("error: failed to get packet sequence mutex, not sending " - "write register for \"%s\"", - reg_info->name); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "write register for \"%s\"", + reg_info->name); } } } @@ -494,12 +499,14 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( if (log->GetVerbose()) { StreamString strm; gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending " - "read all registers:\n%s", - strm.GetData()); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "read all registers:\n%s", + strm.GetData()); } else - log->Printf("error: failed to get packet sequence mutex, not sending " - "read all registers"); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "read all registers"); } } @@ -630,7 +637,9 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( if (m_thread.GetProcess().get()) { const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); - if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 && + if (arch.IsValid() && + (arch.GetMachine() == llvm::Triple::aarch64 || + arch.GetMachine() == llvm::Triple::aarch64_32) && arch.GetTriple().getVendor() == llvm::Triple::Apple && arch.GetTriple().getOS() == llvm::Triple::IOS) { arm64_debugserver = true; @@ -667,12 +676,14 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( if (log->GetVerbose()) { StreamString strm; gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending " - "write all registers:\n%s", - strm.GetData()); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "write all registers:\n%s", + strm.GetData()); } else - log->Printf("error: failed to get packet sequence mutex, not sending " - "write all registers"); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "write all registers"); } } return false; diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a6fdd8dd07070..f1762abc55f82 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -63,7 +63,6 @@ #include "lldb/Target/TargetList.h" #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/Args.h" -#include "lldb/Utility/CleanUp.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/State.h" @@ -81,12 +80,12 @@ #include "lldb/Host/Host.h" #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" #define DEBUGSERVER_BASENAME "debugserver" -using namespace llvm; using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; @@ -99,51 +98,25 @@ namespace lldb { // namespace. This allows you to attach with a debugger and call this function // and get the packet history dumped to a file. void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { - StreamFile strm; - Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path), - File::eOpenOptionWrite | - File::eOpenOptionCanCreate); - if (error.Success()) - ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm); + auto file = FileSystem::Instance().Open( + FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate); + if (!file) { + llvm::consumeError(file.takeError()); + return; + } + StreamFile stream(std::move(file.get())); + ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream); } } // namespace lldb namespace { -static constexpr PropertyDefinition g_properties[] = { - {"packet-timeout", - OptionValue::eTypeUInt64, - true, - 5 -#if defined(__has_feature) -#if __has_feature(address_sanitizer) - * 2 -#endif -#endif - , - nullptr, - {}, - "Specify the default packet timeout in seconds."}, - {"target-definition-file", - OptionValue::eTypeFileSpec, - true, - 0, - nullptr, - {}, - "The file that provides the description for remote target registers."}, - {"use-libraries-svr4", - OptionValue::eTypeBoolean, - true, - false, - nullptr, - {}, - "If true, the libraries-svr4 feature will be used to get a hold of the " - "process's loaded modules."}}; +#define LLDB_PROPERTIES_processgdbremote +#include "ProcessGDBRemoteProperties.inc" enum { - ePropertyPacketTimeout, - ePropertyTargetDefinitionFile, - ePropertyUseSVR4 +#define LLDB_PROPERTIES_processgdbremote +#include "ProcessGDBRemotePropertiesEnum.inc" }; class PluginProperties : public Properties { @@ -154,7 +127,7 @@ public: PluginProperties() : Properties() { m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); - m_collection_sp->Initialize(g_properties); + m_collection_sp->Initialize(g_processgdbremote_properties); } ~PluginProperties() override {} @@ -162,7 +135,7 @@ public: uint64_t GetPacketTimeout() { const uint32_t idx = ePropertyPacketTimeout; return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_properties[idx].default_uint_value); + nullptr, idx, g_processgdbremote_properties[idx].default_uint_value); } bool SetPacketTimeout(uint64_t timeout) { @@ -178,7 +151,8 @@ public: bool GetUseSVR4() const { const uint32_t idx = ePropertyUseSVR4; return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_properties[idx].default_uint_value != 0); + nullptr, idx, + g_processgdbremote_properties[idx].default_uint_value != 0); } }; @@ -191,45 +165,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { return g_settings_sp; } -class ProcessGDBRemoteProvider - : public repro::Provider<ProcessGDBRemoteProvider> { -public: - struct Info { - static const char *name; - static const char *file; - }; - - ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) { - } - - raw_ostream *GetHistoryStream() { - FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file); - - std::error_code EC; - m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC, - sys::fs::OpenFlags::F_Text); - return m_stream_up.get(); - } - - void SetCallback(std::function<void()> callback) { - m_callback = std::move(callback); - } - - void Keep() override { m_callback(); } - - void Discard() override { m_callback(); } - - static char ID; - -private: - std::function<void()> m_callback; - std::unique_ptr<raw_fd_ostream> m_stream_up; -}; - -char ProcessGDBRemoteProvider::ID = 0; -const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote"; -const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml"; - } // namespace // TODO Randomly assigning a port is unsafe. We should get an unused @@ -339,8 +274,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, "async thread did exit"); if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { - ProcessGDBRemoteProvider &provider = - g->GetOrCreate<ProcessGDBRemoteProvider>(); + repro::ProcessGDBRemoteProvider &provider = + g->GetOrCreate<repro::ProcessGDBRemoteProvider>(); // Set the history stream to the stream owned by the provider. m_gdb_comm.SetHistoryStream(provider.GetHistoryStream()); // Make sure to clear the stream again when we're finished. @@ -354,10 +289,10 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, if (m_async_listener_sp->StartListeningForEvents( &m_async_broadcaster, async_event_mask) != async_event_mask) { - if (log) - log->Printf("ProcessGDBRemote::%s failed to listen for " - "m_async_broadcaster events", - __FUNCTION__); + LLDB_LOGF(log, + "ProcessGDBRemote::%s failed to listen for " + "m_async_broadcaster events", + __FUNCTION__); } const uint32_t gdb_event_mask = @@ -365,9 +300,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify; if (m_async_listener_sp->StartListeningForEvents( &m_gdb_comm, gdb_event_mask) != gdb_event_mask) { - if (log) - log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", - __FUNCTION__); + LLDB_LOGF(log, + "ProcessGDBRemote::%s failed to listen for m_gdb_comm events", + __FUNCTION__); } const uint64_t timeout_seconds = @@ -785,15 +720,15 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm, pid, remote_url.str().c_str()); } - if (log) - log->Printf("ProcessGDBRemote::%s pid %" PRIu64 - ": normalizing target architecture initial triple: %s " - "(GetTarget().GetArchitecture().IsValid() %s, " - "m_gdb_comm.GetHostArchitecture().IsValid(): %s)", - __FUNCTION__, GetID(), - GetTarget().GetArchitecture().GetTriple().getTriple().c_str(), - GetTarget().GetArchitecture().IsValid() ? "true" : "false", - m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s pid %" PRIu64 + ": normalizing target architecture initial triple: %s " + "(GetTarget().GetArchitecture().IsValid() %s, " + "m_gdb_comm.GetHostArchitecture().IsValid(): %s)", + __FUNCTION__, GetID(), + GetTarget().GetArchitecture().GetTriple().getTriple().c_str(), + GetTarget().GetArchitecture().IsValid() ? "true" : "false", + m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false"); if (error.Success() && !GetTarget().GetArchitecture().IsValid() && m_gdb_comm.GetHostArchitecture().IsValid()) { @@ -805,11 +740,11 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm, GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture()); } - if (log) - log->Printf("ProcessGDBRemote::%s pid %" PRIu64 - ": normalized target architecture triple: %s", - __FUNCTION__, GetID(), - GetTarget().GetArchitecture().GetTriple().getTriple().c_str()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s pid %" PRIu64 + ": normalized target architecture triple: %s", + __FUNCTION__, GetID(), + GetTarget().GetArchitecture().GetTriple().getTriple().c_str()); if (error.Success()) { PlatformSP platform_sp = GetTarget().GetPlatform(); @@ -834,8 +769,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error; - if (log) - log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s() entered", __FUNCTION__); uint32_t launch_flags = launch_info.GetFlags().Get(); FileSpec stdin_file_spec{}; @@ -862,15 +796,17 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, if (log) { if (stdin_file_spec || stdout_file_spec || stderr_file_spec) - log->Printf("ProcessGDBRemote::%s provided with STDIO paths via " - "launch_info: stdin=%s, stdout=%s, stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s provided with STDIO paths via " + "launch_info: stdin=%s, stdout=%s, stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); else - log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info", - __FUNCTION__); + LLDB_LOGF(log, + "ProcessGDBRemote::%s no STDIO paths given via launch_info", + __FUNCTION__); } const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; @@ -925,24 +861,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, if (!stderr_file_spec) stderr_file_spec = slave_name; } - if (log) - log->Printf( - "ProcessGDBRemote::%s adjusted STDIO paths for local platform " - "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); + LLDB_LOGF( + log, + "ProcessGDBRemote::%s adjusted STDIO paths for local platform " + "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); } - if (log) - log->Printf("ProcessGDBRemote::%s final STDIO paths after all " - "adjustments: stdin=%s, stdout=%s, stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s final STDIO paths after all " + "adjustments: stdin=%s, stdout=%s, stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); if (stdin_file_spec) m_gdb_comm.SetSTDIN(stdin_file_spec); @@ -988,9 +923,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, } if (GetID() == LLDB_INVALID_PROCESS_ID) { - if (log) - log->Printf("failed to connect to debugserver: %s", - error.AsCString()); + LLDB_LOGF(log, "failed to connect to debugserver: %s", + error.AsCString()); KillDebugserverProcess(); return error; } @@ -1020,8 +954,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, } } } else { - if (log) - log->Printf("failed to connect to debugserver: %s", error.AsCString()); + LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString()); } } else { // Set our user ID to an invalid process ID. @@ -1040,9 +973,8 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); if (!connect_url.empty()) { - if (log) - log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, - connect_url.str().c_str()); + LLDB_LOGF(log, "ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, + connect_url.str().c_str()); std::unique_ptr<ConnectionFileDescriptor> conn_up( new ConnectionFileDescriptor()); if (conn_up) { @@ -1062,7 +994,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { if (retry_count >= max_retry_count) break; - usleep(100000); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } } @@ -1116,8 +1048,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::%s()", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__); if (GetID() != LLDB_INVALID_PROCESS_ID) { BuildDynamicRegisterInfo(false); @@ -1130,43 +1061,42 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); if (remote_process_arch.IsValid()) { process_arch = remote_process_arch; - if (log) - log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, " - "using %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s gdb-remote had process architecture, " + "using %s %s", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", + process_arch.GetTriple().getTriple().c_str() + ? process_arch.GetTriple().getTriple().c_str() + : "<null>"); } else { process_arch = m_gdb_comm.GetHostArchitecture(); - if (log) - log->Printf("ProcessGDBRemote::%s gdb-remote did not have process " - "architecture, using gdb-remote host architecture %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s gdb-remote did not have process " + "architecture, using gdb-remote host architecture %s %s", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", + process_arch.GetTriple().getTriple().c_str() + ? process_arch.GetTriple().getTriple().c_str() + : "<null>"); } if (process_arch.IsValid()) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); if (target_arch.IsValid()) { - if (log) - log->Printf( - "ProcessGDBRemote::%s analyzing target arch, currently %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s analyzing target arch, currently %s %s", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "<null>", + target_arch.GetTriple().getTriple().c_str() + ? target_arch.GetTriple().getTriple().c_str() + : "<null>"); // If the remote host is ARM and we have apple as the vendor, then // ARM executables and shared libraries can have mixed ARM @@ -1180,16 +1110,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { process_arch.GetMachine() == llvm::Triple::thumb) && process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { GetTarget().SetArchitecture(process_arch); - if (log) - log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, " - "setting target arch to %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s remote process is ARM/Apple, " + "setting target arch to %s %s", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "<null>", + process_arch.GetTriple().getTriple().c_str() + ? process_arch.GetTriple().getTriple().c_str() + : "<null>"); } else { // Fill in what is missing in the triple const llvm::Triple &remote_triple = process_arch.GetTriple(); @@ -1211,16 +1141,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { } } - if (log) - log->Printf("ProcessGDBRemote::%s final target arch after " - "adjustments for remote architecture: %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : "<null>"); + LLDB_LOGF(log, + "ProcessGDBRemote::%s final target arch after " + "adjustments for remote architecture: %s %s", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "<null>", + target_arch.GetTriple().getTriple().c_str() + ? target_arch.GetTriple().getTriple().c_str() + : "<null>"); } else { // The target doesn't have a valid architecture yet, set it from the // architecture we got from the remote GDB server @@ -1247,8 +1177,7 @@ Status ProcessGDBRemote::DoAttachToProcessWithID( Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error; - if (log) - log->Printf("ProcessGDBRemote::%s()", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__); // Clear out and clean up from any current state Clear(); @@ -1359,8 +1288,7 @@ Status ProcessGDBRemote::WillResume() { Status ProcessGDBRemote::DoResume() { Status error; Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::Resume()"); + LLDB_LOGF(log, "ProcessGDBRemote::Resume()"); ListenerSP listener_sp( Listener::MakeListener("gdb-remote.resume-packet-sent")); @@ -1547,9 +1475,8 @@ Status ProcessGDBRemote::DoResume() { EventSP event_sp; if (!m_async_thread.IsJoinable()) { error.SetErrorString("Trying to resume but the async thread is dead."); - if (log) - log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the " - "async thread is dead."); + LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Trying to resume but the " + "async thread is dead."); return error; } @@ -1560,14 +1487,13 @@ Status ProcessGDBRemote::DoResume() { if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) { error.SetErrorString("Resume timed out."); - if (log) - log->Printf("ProcessGDBRemote::DoResume: Resume timed out."); + LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Resume timed out."); } else if (event_sp->BroadcasterIs(&m_async_broadcaster)) { error.SetErrorString("Broadcast continue, but the async thread was " "killed before we got an ack back."); - if (log) - log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the " - "async thread was killed before we got an ack back."); + LLDB_LOGF(log, + "ProcessGDBRemote::DoResume: Broadcast continue, but the " + "async thread was killed before we got an ack back."); return error; } } @@ -1864,8 +1790,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( } for (const auto &pair : expedited_register_map) { - StringExtractor reg_value_extractor; - reg_value_extractor.GetStringRef() = pair.second; + StringExtractor reg_value_extractor(pair.second); DataBufferSP buffer_sp(new DataBufferHeap( reg_value_extractor.GetStringRef().size() / 2, 0)); reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc'); @@ -1979,8 +1904,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( if (watch_id == LLDB_INVALID_WATCH_ID) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet( GDBR_LOG_WATCHPOINTS)); - if (log) - log->Printf("failed to find watchpoint"); + LLDB_LOGF(log, "failed to find watchpoint"); } thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID( *thread_sp, watch_id, wp_hit_addr)); @@ -2400,7 +2324,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); description = ostr.GetString(); } else if (key.compare("library") == 0) { - LoadModules(); + auto error = LoadModules(); + if (error) { + Log *log( + ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG_ERROR(log, std::move(error), "Failed to load modules: {0}"); + } } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) @@ -2474,7 +2403,7 @@ void ProcessGDBRemote::RefreshStateAfterStop() { // Clear the thread stop stack m_stop_packet_stack.clear(); } - + // If we have queried for a default thread id if (m_initial_tid != LLDB_INVALID_THREAD_ID) { m_thread_list.SetSelectedThreadByID(m_initial_tid); @@ -2501,8 +2430,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) { Status ProcessGDBRemote::DoDetach(bool keep_stopped) { Status error; Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped); + LLDB_LOGF(log, "ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped); error = m_gdb_comm.Detach(keep_stopped); if (log) { @@ -2510,8 +2438,9 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) { log->PutCString( "ProcessGDBRemote::DoDetach() detach packet sent successfully"); else - log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s", - error.AsCString() ? error.AsCString() : "<unknown error>"); + LLDB_LOGF(log, + "ProcessGDBRemote::DoDetach() detach packet send failed: %s", + error.AsCString() ? error.AsCString() : "<unknown error>"); } if (!error.Success()) @@ -2530,8 +2459,7 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) { Status ProcessGDBRemote::DoDestroy() { Status error; Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::DoDestroy()"); + LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()"); // There is a bug in older iOS debugservers where they don't shut down the // process they are debugging properly. If the process is sitting at a @@ -2586,11 +2514,11 @@ Status ProcessGDBRemote::DoDestroy() { reason = stop_info_sp->GetStopReason(); if (reason == eStopReasonBreakpoint || reason == eStopReasonException) { - if (log) - log->Printf( - "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 - " stopped with reason: %s.", - thread_sp->GetProtocolID(), stop_info_sp->GetDescription()); + LLDB_LOGF(log, + "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 + " stopped with reason: %s.", + thread_sp->GetProtocolID(), + stop_info_sp->GetDescription()); stop_looks_like_crash = true; break; } @@ -2622,10 +2550,10 @@ Status ProcessGDBRemote::DoDestroy() { reason = stop_info_sp->GetStopReason(); if (reason != eStopReasonBreakpoint && reason != eStopReasonException) { - if (log) - log->Printf("ProcessGDBRemote::DoDestroy() - Suspending " - "thread: 0x%4.4" PRIx64 " before running.", - thread_sp->GetProtocolID()); + LLDB_LOGF(log, + "ProcessGDBRemote::DoDestroy() - Suspending " + "thread: 0x%4.4" PRIx64 " before running.", + thread_sp->GetProtocolID()); thread_sp->SetResumeState(eStateSuspended); } } @@ -2669,30 +2597,28 @@ Status ProcessGDBRemote::DoDestroy() { int status; ::pid_t reap_pid; reap_pid = waitpid(GetID(), &status, WNOHANG); - if (log) - log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status); + LLDB_LOGF(log, "Reaped pid: %d, status: %d.\n", reap_pid, status); } #endif SetLastStopPacket(response); ClearThreadIDList(); exit_status = response.GetHexU8(); } else { - if (log) - log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response " - "to k packet: %s", - response.GetStringRef().c_str()); + LLDB_LOGF(log, + "ProcessGDBRemote::DoDestroy - got unexpected response " + "to k packet: %s", + response.GetStringRef().data()); exit_string.assign("got unexpected response to k packet: "); exit_string.append(response.GetStringRef()); } } else { - if (log) - log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet"); + LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet"); exit_string.assign("failed to send the k packet"); } } else { - if (log) - log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while " - "attaching"); + LLDB_LOGF(log, + "ProcessGDBRemote::DoDestroy - killed or interrupted while " + "attaching"); exit_string.assign("killed or interrupted while attaching."); } } else { @@ -2715,8 +2641,7 @@ void ProcessGDBRemote::SetLastStopPacket( response.GetStringRef().find(";reason:exec;") != std::string::npos; if (did_exec) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec"); + LLDB_LOGF(log, "ProcessGDBRemote::SetLastStopPacket () - detected exec"); m_thread_list_real.Clear(); m_thread_list.Clear(); @@ -2756,9 +2681,13 @@ addr_t ProcessGDBRemote::GetImageInfoAddress() { // the loaded module list can also provides a link map address if (addr == LLDB_INVALID_ADDRESS) { - LoadedModuleInfoList list; - if (GetLoadedModuleList(list).Success()) - addr = list.m_link_map; + llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList(); + if (!list) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}"); + } else { + addr = list->m_link_map; + } } return addr; @@ -2840,7 +2769,7 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, else error.SetErrorStringWithFormat( "unexpected response to GDB server memory read packet '%s': '%s'", - packet, response.GetStringRef().c_str()); + packet, response.GetStringRef().data()); } else { error.SetErrorStringWithFormat("failed to send packet: '%s'", packet); } @@ -2950,7 +2879,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) { else status.SetErrorStringWithFormat( "unexpected response to GDB server flash erase packet '%s': '%s'", - packet.GetData(), response.GetStringRef().c_str()); + packet.GetData(), response.GetStringRef().data()); } } else { status.SetErrorStringWithFormat("failed to send packet: '%s'", @@ -2978,7 +2907,7 @@ Status ProcessGDBRemote::FlashDone() { else status.SetErrorStringWithFormat( "unexpected response to GDB server flash done packet: '%s'", - response.GetStringRef().c_str()); + response.GetStringRef().data()); } } else { status.SetErrorStringWithFormat("failed to send flash done packet"); @@ -3041,7 +2970,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, else error.SetErrorStringWithFormat( "unexpected response to GDB server memory write packet '%s': '%s'", - packet.GetData(), response.GetStringRef().c_str()); + packet.GetData(), response.GetStringRef().data()); } else { error.SetErrorStringWithFormat("failed to send packet: '%s'", packet.GetData()); @@ -3078,11 +3007,11 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size, m_addr_to_mmap_size[allocated_addr] = size; else { allocated_addr = LLDB_INVALID_ADDRESS; - if (log) - log->Printf("ProcessGDBRemote::%s no direct stub support for memory " - "allocation, and InferiorCallMmap also failed - is stub " - "missing register context save/restore capability?", - __FUNCTION__); + LLDB_LOGF(log, + "ProcessGDBRemote::%s no direct stub support for memory " + "allocation, and InferiorCallMmap also failed - is stub " + "missing register context save/restore capability?", + __FUNCTION__); } } @@ -3173,17 +3102,17 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { const addr_t addr = bp_site->GetLoadAddress(); // Log that a breakpoint was requested - if (log) - log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 - ") address = 0x%" PRIx64, - site_id, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 + ") address = 0x%" PRIx64, + site_id, (uint64_t)addr); // Breakpoint already exists and is enabled if (bp_site->IsEnabled()) { - if (log) - log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 - ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", - site_id, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 + ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", + site_id, (uint64_t)addr); return error; } @@ -3231,8 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { // We reach here when software breakpoints have been found to be // unsupported. For future calls to set a breakpoint, we will not attempt // to set a breakpoint with a type that is known not to be supported. - if (log) - log->Printf("Software breakpoints are unsupported"); + LLDB_LOGF(log, "Software breakpoints are unsupported"); // So we will fall through and try a hardware breakpoint } @@ -3270,8 +3198,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { // We will reach here when the stub gives an unsupported response to a // hardware breakpoint - if (log) - log->Printf("Hardware breakpoints are unsupported"); + LLDB_LOGF(log, "Hardware breakpoints are unsupported"); // Finally we will falling through to a #trap style breakpoint } @@ -3293,10 +3220,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) { addr_t addr = bp_site->GetLoadAddress(); user_id_t site_id = bp_site->GetID(); Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS)); - if (log) - log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 - ") addr = 0x%8.8" PRIx64, - site_id, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 + ") addr = 0x%8.8" PRIx64, + site_id, (uint64_t)addr); if (bp_site->IsEnabled()) { const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site); @@ -3328,10 +3255,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) { if (error.Success()) bp_site->SetEnabled(false); } else { - if (log) - log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 - ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", - site_id, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 + ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", + site_id, (uint64_t)addr); return error; } @@ -3363,14 +3290,13 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) { addr_t addr = wp->GetLoadAddress(); Log *log( ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS)); - if (log) - log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", - watchID); + LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", + watchID); if (wp->IsEnabled()) { - if (log) - log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", - watchID, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 + ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", + watchID, (uint64_t)addr); return error; } @@ -3403,16 +3329,16 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) { addr_t addr = wp->GetLoadAddress(); - if (log) - log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64, - watchID, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 + ") addr = 0x%8.8" PRIx64, + watchID, (uint64_t)addr); if (!wp->IsEnabled()) { - if (log) - log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", - watchID, (uint64_t)addr); + LLDB_LOGF(log, + "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 + ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", + watchID, (uint64_t)addr); // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling // attempt might come from the user-supplied actions, we'll route it in // order for the watchpoint object to intelligently process this action. @@ -3447,8 +3373,7 @@ void ProcessGDBRemote::Clear() { Status ProcessGDBRemote::DoSignal(int signo) { Status error; Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo); + LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo); if (!m_gdb_comm.SendAsyncSignal(signo)) error.SetErrorStringWithFormat("failed to send signal %i", signo); @@ -3460,7 +3385,8 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) { return Status("No loader provided."); // Construct replay history path. - FileSpec history_file = loader->GetFile<ProcessGDBRemoteProvider::Info>(); + FileSpec history_file = + loader->GetFile<repro::ProcessGDBRemoteProvider::Info>(); if (!history_file) return Status("No provider for gdb-remote."); @@ -3556,8 +3482,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( int our_socket = sockets[0]; int gdb_socket = sockets[1]; - CleanUp cleanup_our(close, our_socket); - CleanUp cleanup_gdb(close, gdb_socket); + auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); }); + auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); }); // Don't let any child processes inherit our communication socket SetCloexecFlag(our_socket); @@ -3577,7 +3503,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION // Our process spawned correctly, we can now set our connection to use // our end of the socket pair - cleanup_our.disable(); + cleanup_our.release(); m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true)); #endif StartAsyncThread(); @@ -3586,9 +3512,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( if (error.Fail()) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("failed to start debugserver process: %s", - error.AsCString()); + LLDB_LOGF(log, "failed to start debugserver process: %s", + error.AsCString()); return error; } @@ -3614,22 +3539,22 @@ bool ProcessGDBRemote::MonitorDebugserverProcess( Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); const bool handled = true; - if (log) - log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 - ", signo=%i (0x%x), exit_status=%i)", - __FUNCTION__, debugserver_pid, signo, signo, exit_status); + LLDB_LOGF(log, + "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 + ", signo=%i (0x%x), exit_status=%i)", + __FUNCTION__, debugserver_pid, signo, signo, exit_status); std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock(); - if (log) - log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__, - static_cast<void *>(process_sp.get())); + LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__, + static_cast<void *>(process_sp.get())); if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid) return handled; // Sleep for a half a second to make sure our inferior process has time to // set its exit status before we set it incorrectly when both the debugserver // and the inferior process shut down. - usleep(500000); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + // If our process hasn't yet exited, debugserver might have died. If the // process did exit, then we are reaping it. const StateType state = process_sp->GetState(); @@ -3692,8 +3617,7 @@ void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) { bool ProcessGDBRemote::StartAsyncThread() { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__); std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex); if (!m_async_thread.IsJoinable()) { @@ -3709,10 +3633,11 @@ bool ProcessGDBRemote::StartAsyncThread() { return false; } m_async_thread = *async_thread; - } else if (log) - log->Printf("ProcessGDBRemote::%s () - Called when Async thread was " - "already running.", - __FUNCTION__); + } else + LLDB_LOGF(log, + "ProcessGDBRemote::%s () - Called when Async thread was " + "already running.", + __FUNCTION__); return m_async_thread.IsJoinable(); } @@ -3720,8 +3645,7 @@ bool ProcessGDBRemote::StartAsyncThread() { void ProcessGDBRemote::StopAsyncThread() { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__); std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex); if (m_async_thread.IsJoinable()) { @@ -3733,8 +3657,9 @@ void ProcessGDBRemote::StopAsyncThread() { // Stop the stdio thread m_async_thread.Join(nullptr); m_async_thread.Reset(); - } else if (log) - log->Printf( + } else + LLDB_LOGF( + log, "ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__); } @@ -3768,25 +3693,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { ProcessGDBRemote *process = (ProcessGDBRemote *)arg; Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") thread starting...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") thread starting...", + __FUNCTION__, arg, process->GetID()); EventSP event_sp; bool done = false; while (!done) { - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") listener.WaitForEvent (NULL, event_sp)...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") listener.WaitForEvent (NULL, event_sp)...", + __FUNCTION__, arg, process->GetID()); if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { const uint32_t event_type = event_sp->GetType(); if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) { - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") Got an event of type: %d...", - __FUNCTION__, arg, process->GetID(), event_type); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") Got an event of type: %d...", + __FUNCTION__, arg, process->GetID(), event_type); switch (event_type) { case eBroadcastBitAsyncContinue: { @@ -3797,10 +3722,10 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { const char *continue_cstr = (const char *)continue_packet->GetBytes(); const size_t continue_cstr_len = continue_packet->GetByteSize(); - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") got eBroadcastBitAsyncContinue: %s", - __FUNCTION__, arg, process->GetID(), continue_cstr); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") got eBroadcastBitAsyncContinue: %s", + __FUNCTION__, arg, process->GetID(), continue_cstr); if (::strstr(continue_cstr, "vAttach") == nullptr) process->SetPrivateState(eStateRunning); @@ -3891,18 +3816,18 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { break; case eBroadcastBitAsyncThreadShouldExit: - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") got eBroadcastBitAsyncThreadShouldExit...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") got eBroadcastBitAsyncThreadShouldExit...", + __FUNCTION__, arg, process->GetID()); done = true; break; default: - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") got unknown event 0x%8.8x", - __FUNCTION__, arg, process->GetID(), event_type); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") got unknown event 0x%8.8x", + __FUNCTION__, arg, process->GetID(), event_type); done = true; break; } @@ -3925,27 +3850,27 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { } default: - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") got unknown event 0x%8.8x", - __FUNCTION__, arg, process->GetID(), event_type); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") got unknown event 0x%8.8x", + __FUNCTION__, arg, process->GetID(), event_type); done = true; break; } } } else { - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") listener.WaitForEvent (NULL, event_sp) => false", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") listener.WaitForEvent (NULL, event_sp) => false", + __FUNCTION__, arg, process->GetID()); done = true; } } - if (log) - log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 - ") thread exiting...", - __FUNCTION__, arg, process->GetID()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 + ") thread exiting...", + __FUNCTION__, arg, process->GetID()); return {}; } @@ -3977,8 +3902,7 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit( // thread when it starts to // run so I can stop it if that's what I want to do. Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log) - log->Printf("Hit New Thread Notification breakpoint."); + LLDB_LOGF(log, "Hit New Thread Notification breakpoint."); return false; } @@ -4023,7 +3947,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (m_thread_create_bp_sp) { if (log && log->GetVerbose()) - log->Printf("Enabled noticing new thread breakpoint."); + LLDB_LOGF(log, "Enabled noticing new thread breakpoint."); m_thread_create_bp_sp->SetEnabled(true); } else { PlatformSP platform_sp(GetTarget().GetPlatform()); @@ -4032,14 +3956,13 @@ bool ProcessGDBRemote::StartNoticingNewThreads() { platform_sp->SetThreadCreationBreakpoint(GetTarget()); if (m_thread_create_bp_sp) { if (log && log->GetVerbose()) - log->Printf( - "Successfully created new thread notification breakpoint %i", + LLDB_LOGF( + log, "Successfully created new thread notification breakpoint %i", m_thread_create_bp_sp->GetID()); m_thread_create_bp_sp->SetCallback( ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true); } else { - if (log) - log->Printf("Failed to create new thread notification breakpoint."); + LLDB_LOGF(log, "Failed to create new thread notification breakpoint."); } } } @@ -4049,7 +3972,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() { bool ProcessGDBRemote::StopNoticingNewThreads() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) - log->Printf("Disabling new thread notification breakpoint."); + LLDB_LOGF(log, "Disabling new thread notification breakpoint."); if (m_thread_create_bp_sp) m_thread_create_bp_sp->SetEnabled(false); @@ -4325,19 +4248,18 @@ bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec, } if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) { - if (log) - log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s", - __FUNCTION__, module_file_spec.GetPath().c_str(), - arch.GetTriple().getTriple().c_str()); + LLDB_LOGF(log, "ProcessGDBRemote::%s - failed to get module info for %s:%s", + __FUNCTION__, module_file_spec.GetPath().c_str(), + arch.GetTriple().getTriple().c_str()); return false; } if (log) { StreamString stream; module_spec.Dump(stream); - log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s", - __FUNCTION__, module_file_spec.GetPath().c_str(), - arch.GetTriple().getTriple().c_str(), stream.GetData()); + LLDB_LOGF(log, "ProcessGDBRemote::%s - got module info for (%s:%s) : %s", + __FUNCTION__, module_file_spec.GetPath().c_str(), + arch.GetTriple().getTriple().c_str(), stream.GetData()); } m_cached_module_specs[key] = module_spec; @@ -4361,6 +4283,10 @@ llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() { return m_gdb_comm.GetOSVersion(); } +llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() { + return m_gdb_comm.GetMacCatalystVersion(); +} + namespace { typedef std::vector<std::string> stringVec; @@ -4492,14 +4418,13 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, } else if (name == "invalidate_regnums") { SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0); } else if (name == "dynamic_size_dwarf_expr_bytes") { - StringExtractor opcode_extractor; std::string opcode_string = value.str(); size_t dwarf_opcode_len = opcode_string.length() / 2; assert(dwarf_opcode_len > 0); dwarf_opcode_bytes.resize(dwarf_opcode_len); reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; - opcode_extractor.GetStringRef().swap(opcode_string); + StringExtractor opcode_extractor(opcode_string); uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); assert(dwarf_opcode_len == ret_val); @@ -4565,16 +4490,15 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, // information to the current process. It will call itself recursively // for nested register definition files. It returns true if it was able // to fetch and parse an xml file. -bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, - std::string xml_filename, - uint32_t &cur_reg_num, - uint32_t ®_offset) { +bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( + ArchSpec &arch_to_use, std::string xml_filename, uint32_t &cur_reg_num, + uint32_t ®_offset) { // request the target xml file std::string raw; lldb_private::Status lldberr; - if (!m_gdb_comm.ReadExtFeature(ConstString("features"), - ConstString(xml_filename.c_str()), - raw, lldberr)) { + if (!m_gdb_comm.ReadExtFeature(ConstString("features"), + ConstString(xml_filename.c_str()), raw, + lldberr)) { return false; } @@ -4676,8 +4600,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_u } for (const auto &include : target_info.includes) { - GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, - cur_reg_num, reg_offset); + GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num, + reg_offset); } } } else { @@ -4705,41 +4629,43 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { return m_register_info.GetNumRegisters() > 0; } -Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { +llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { // Make sure LLDB has an XML parser it can use first if (!XMLDocument::XMLEnabled()) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "XML parsing not available"); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS); - if (log) - log->Printf("ProcessGDBRemote::%s", __FUNCTION__); + LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__); + LoadedModuleInfoList list; GDBRemoteCommunicationClient &comm = m_gdb_comm; bool can_use_svr4 = GetGlobalPluginProperties()->GetUseSVR4(); // check that we have extended feature read support if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) { - list.clear(); - // request the loaded library list std::string raw; lldb_private::Status lldberr; if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""), raw, lldberr)) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error in libraries-svr4 packet"); // parse the xml file in memory - if (log) - log->Printf("parsing: %s", raw.c_str()); + LLDB_LOGF(log, "parsing: %s", raw.c_str()); XMLDocument doc; if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error reading noname.xml"); XMLNode root_element = doc.GetRootElement("library-list-svr4"); if (!root_element) - return Status(); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Error finding library-list-svr4 xml element"); // main link map structure llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); @@ -4791,10 +4717,11 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { module.get_base_is_offset(base_is_offset); module.get_dynamic(ld); - log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64 - "[%s], ld:0x%08" PRIx64 ", name:'%s')", - lm, base, (base_is_offset ? "offset" : "absolute"), ld, - name.c_str()); + LLDB_LOGF(log, + "found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64 + "[%s], ld:0x%08" PRIx64 ", name:'%s')", + lm, base, (base_is_offset ? "offset" : "absolute"), ld, + name.c_str()); } list.add(module); @@ -4803,29 +4730,30 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { }); if (log) - log->Printf("found %" PRId32 " modules in total", - (int)list.m_list.size()); + LLDB_LOGF(log, "found %" PRId32 " modules in total", + (int)list.m_list.size()); + return list; } else if (comm.GetQXferLibrariesReadSupported()) { - list.clear(); - // request the loaded library list std::string raw; lldb_private::Status lldberr; if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw, lldberr)) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error in libraries packet"); - if (log) - log->Printf("parsing: %s", raw.c_str()); + LLDB_LOGF(log, "parsing: %s", raw.c_str()); XMLDocument doc; if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error reading noname.xml"); XMLNode root_element = doc.GetRootElement("library-list"); if (!root_element) - return Status(); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error finding library-list xml element"); root_element.ForEachChildElementWithName( "library", [log, &list](const XMLNode &library) -> bool { @@ -4853,8 +4781,8 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { module.get_base(base); module.get_base_is_offset(base_is_offset); - log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base, - (base_is_offset ? "offset" : "absolute"), name.c_str()); + LLDB_LOGF(log, "found (base:0x%08" PRIx64 "[%s], name:'%s')", base, + (base_is_offset ? "offset" : "absolute"), name.c_str()); } list.add(module); @@ -4863,13 +4791,13 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { }); if (log) - log->Printf("found %" PRId32 " modules in total", - (int)list.m_list.size()); + LLDB_LOGF(log, "found %" PRId32 " modules in total", + (int)list.m_list.size()); + return list; } else { - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Remote libraries not supported"); } - - return Status(); } lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file, @@ -4884,17 +4812,18 @@ lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file, value_is_offset); } -size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { +llvm::Error ProcessGDBRemote::LoadModules() { using lldb_private::process_gdb_remote::ProcessGDBRemote; // request a list of loaded libraries from GDBServer - if (GetLoadedModuleList(module_list).Fail()) - return 0; + llvm::Expected<LoadedModuleInfoList> module_list = GetLoadedModuleList(); + if (!module_list) + return module_list.takeError(); // get a list of all the modules ModuleList new_modules; - for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) { + for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list->m_list) { std::string mod_name; lldb::addr_t mod_base; lldb::addr_t link_map; @@ -4961,12 +4890,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { m_process->GetTarget().ModulesDidLoad(new_modules); } - return new_modules.GetSize(); -} - -size_t ProcessGDBRemote::LoadModules() { - LoadedModuleInfoList module_list; - return LoadModules(module_list); + return llvm::ErrorSuccess(); } Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file, @@ -5149,7 +5073,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) { if (!packet.consume_front(s_async_json_packet_prefix)) { if (log) { - log->Printf( + LLDB_LOGF( + log, "GDBRemoteCommunicationClientBase::%s() received $J packet " "but was not a StructuredData packet: packet starts with " "%s", @@ -5164,16 +5089,18 @@ ParseStructuredDataPacket(llvm::StringRef packet) { if (log) { if (json_sp) { StreamString json_str; - json_sp->Dump(json_str); + json_sp->Dump(json_str, true); json_str.Flush(); - log->Printf("ProcessGDBRemote::%s() " - "received Async StructuredData packet: %s", - __FUNCTION__, json_str.GetData()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s() " + "received Async StructuredData packet: %s", + __FUNCTION__, json_str.GetData()); } else { - log->Printf("ProcessGDBRemote::%s" - "() received StructuredData packet:" - " parse failure", - __FUNCTION__); + LLDB_LOGF(log, + "ProcessGDBRemote::%s" + "() received StructuredData packet:" + " parse failure", + __FUNCTION__); } } return json_sp; @@ -5365,7 +5292,7 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); Stream &output_strm = result.GetOutputStream(); output_strm.Printf(" packet: %s\n", packet_cstr); - std::string &response_str = response.GetStringRef(); + std::string response_str = response.GetStringRef(); if (strstr(packet_cstr, "qGetProfileData") != nullptr) { response_str = process->HarmonizeThreadIdsForProfileData(response); @@ -5374,7 +5301,7 @@ public: if (response_str.empty()) output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n"); else - output_strm.Printf("response: %s\n", response.GetStringRef().c_str()); + output_strm.Printf("response: %s\n", response.GetStringRef().data()); } } return true; @@ -5423,7 +5350,7 @@ public: if (response_str.empty()) output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n"); else - output_strm.Printf("response: %s\n", response.GetStringRef().c_str()); + output_strm.Printf("response: %s\n", response.GetStringRef().data()); } return true; } diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 9c41fc2e5e988..0e3e3b39d9c8e 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -24,8 +24,8 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractor.h" #include "lldb/Utility/StringList.h" @@ -199,10 +199,11 @@ public: const llvm::Triple &triple) override; llvm::VersionTuple GetHostOSVersion() override; + llvm::VersionTuple GetHostMacCatalystVersion() override; - size_t LoadModules(LoadedModuleInfoList &module_list) override; + llvm::Error LoadModules() override; - size_t LoadModules() override; + llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() override; Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr) override; @@ -391,9 +392,6 @@ protected: // Query remote GDBServer for register information bool GetGDBServerRegisterInfo(ArchSpec &arch); - // Query remote GDBServer for a detailed loaded library list - Status GetLoadedModuleList(LoadedModuleInfoList &); - lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td new file mode 100644 index 0000000000000..16e7723e3061c --- /dev/null +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td @@ -0,0 +1,16 @@ +include "../../../../include/lldb/Core/PropertiesBase.td" + +let Definition = "processgdbremote" in { + def PacketTimeout: Property<"packet-timeout", "UInt64">, + Global, + DefaultUnsignedValue<5>, + Desc<"Specify the default packet timeout in seconds.">; + def TargetDefinitionFile: Property<"target-definition-file", "FileSpec">, + Global, + DefaultStringValue<"">, + Desc<"The file that provides the description for remote target registers.">; + def UseSVR4: Property<"use-libraries-svr4", "Boolean">, + Global, + DefaultFalse, + Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">; +} diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 6607bce4488b4..8a6a58c55450c 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -215,8 +215,7 @@ StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() { StructuredData::ObjectSP object_sp; const lldb::user_id_t tid = GetProtocolID(); Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); - if (log) - log->Printf("Fetching extended information for thread %4.4" PRIx64, tid); + LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid); ProcessSP process_sp(GetProcess()); if (process_sp) { ProcessGDBRemote *gdb_process = @@ -230,9 +229,8 @@ void ThreadGDBRemote::WillResume(StateType resume_state) { int signo = GetResumeSignal(); const lldb::user_id_t tid = GetProtocolID(); Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); - if (log) - log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, - StateAsCString(resume_state)); + LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid, + StateAsCString(resume_state)); ProcessSP process_sp(GetProcess()); if (process_sp) { diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp index ff015aa54b763..70933f91fe518 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -188,6 +188,7 @@ ArchSpec MinidumpParser::GetArchitecture() { case OSPlatform::Win32NT: case OSPlatform::Win32CE: triple.setOS(llvm::Triple::OSType::Win32); + triple.setVendor(llvm::Triple::VendorType::PC); break; case OSPlatform::Linux: triple.setOS(llvm::Triple::OSType::Linux); @@ -313,13 +314,15 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() { return filtered_modules; } -const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() { - llvm::ArrayRef<uint8_t> data = GetStream(StreamType::Exception); +const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { + auto ExpectedStream = GetMinidumpFile().getExceptionStream(); + if (ExpectedStream) + return &*ExpectedStream; - if (data.size() == 0) - return nullptr; - - return MinidumpExceptionStream::Parse(data); + LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS), + ExpectedStream.takeError(), + "Failed to read minidump exception stream: {0}"); + return nullptr; } llvm::Optional<minidump::Range> @@ -426,23 +429,35 @@ CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, static bool CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, std::vector<MemoryRegionInfo> ®ions) { - auto data = parser.GetStream(StreamType::MemoryInfoList); - if (data.empty()) - return false; - auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data); - if (mem_info_list.empty()) + Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES); + auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList(); + if (!ExpectedInfo) { + LLDB_LOG_ERROR(log, ExpectedInfo.takeError(), + "Failed to read memory info list: {0}"); return false; + } constexpr auto yes = MemoryRegionInfo::eYes; constexpr auto no = MemoryRegionInfo::eNo; - regions.reserve(mem_info_list.size()); - for (const auto &entry : mem_info_list) { + for (const MemoryInfo &entry : *ExpectedInfo) { MemoryRegionInfo region; - region.GetRange().SetRangeBase(entry->base_address); - region.GetRange().SetByteSize(entry->region_size); - region.SetReadable(entry->isReadable() ? yes : no); - region.SetWritable(entry->isWritable() ? yes : no); - region.SetExecutable(entry->isExecutable() ? yes : no); - region.SetMapped(entry->isMapped() ? yes : no); + region.GetRange().SetRangeBase(entry.BaseAddress); + region.GetRange().SetByteSize(entry.RegionSize); + + MemoryProtection prot = entry.Protect; + region.SetReadable(bool(prot & MemoryProtection::NoAccess) ? no : yes); + region.SetWritable( + bool(prot & (MemoryProtection::ReadWrite | MemoryProtection::WriteCopy | + MemoryProtection::ExecuteReadWrite | + MemoryProtection::ExeciteWriteCopy)) + ? yes + : no); + region.SetExecutable( + bool(prot & (MemoryProtection::Execute | MemoryProtection::ExecuteRead | + MemoryProtection::ExecuteReadWrite | + MemoryProtection::ExeciteWriteCopy)) + ? yes + : no); + region.SetMapped(entry.State != MemoryState::Free ? yes : no); regions.push_back(region); } return !regions.empty(); diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h index fce64f0ed5fc4..d206fe6c9a00e 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.h +++ b/source/Plugins/Process/minidump/MinidumpParser.h @@ -82,7 +82,7 @@ public: // have the same name, it keeps the copy with the lowest load address. std::vector<const minidump::Module *> GetFilteredModuleList(); - const MinidumpExceptionStream *GetExceptionStream(); + const llvm::minidump::ExceptionStream *GetExceptionStream(); llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr); diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp index d7fc6e43d090c..ed00b1cc07db5 100644 --- a/source/Plugins/Process/minidump/MinidumpTypes.cpp +++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp @@ -57,17 +57,6 @@ LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) { lldb::pid_t LinuxProcStatus::GetPid() const { return pid; } -// Exception stuff -const MinidumpExceptionStream * -MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) { - const MinidumpExceptionStream *exception_stream = nullptr; - Status error = consumeObject(data, exception_stream); - if (error.Fail()) - return nullptr; - - return exception_stream; -} - std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t> MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) { const llvm::support::ulittle64_t *mem_ranges_count; @@ -87,29 +76,3 @@ MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) { *mem_ranges_count), *base_rva); } - -std::vector<const MinidumpMemoryInfo *> -MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) { - const MinidumpMemoryInfoListHeader *header; - Status error = consumeObject(data, header); - if (error.Fail() || - header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) || - header->size_of_entry < sizeof(MinidumpMemoryInfo)) - return {}; - - data = data.drop_front(header->size_of_header - - sizeof(MinidumpMemoryInfoListHeader)); - - if (header->size_of_entry * header->num_of_entries > data.size()) - return {}; - - std::vector<const MinidumpMemoryInfo *> result; - result.reserve(header->num_of_entries); - - for (uint64_t i = 0; i < header->num_of_entries; ++i) { - result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>( - data.data() + i * header->size_of_entry)); - } - - return result; -} diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h index b4878e82de5de..a9c807930ebf4 100644 --- a/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/source/Plugins/Process/minidump/MinidumpTypes.h @@ -85,90 +85,6 @@ struct MinidumpMemoryDescriptor64 { static_assert(sizeof(MinidumpMemoryDescriptor64) == 16, "sizeof MinidumpMemoryDescriptor64 is not correct!"); -// Reference: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx -struct MinidumpMemoryInfoListHeader { - llvm::support::ulittle32_t size_of_header; - llvm::support::ulittle32_t size_of_entry; - llvm::support::ulittle64_t num_of_entries; -}; -static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16, - "sizeof MinidumpMemoryInfoListHeader is not correct!"); - -enum class MinidumpMemoryInfoState : uint32_t { - MemCommit = 0x1000, - MemFree = 0x10000, - MemReserve = 0x2000, - LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree) -}; - -enum class MinidumpMemoryInfoType : uint32_t { - MemImage = 0x1000000, - MemMapped = 0x40000, - MemPrivate = 0x20000, - LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage) -}; - -// Reference: -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx -enum class MinidumpMemoryProtectionContants : uint32_t { - PageExecute = 0x10, - PageExecuteRead = 0x20, - PageExecuteReadWrite = 0x40, - PageExecuteWriteCopy = 0x80, - PageNoAccess = 0x01, - PageReadOnly = 0x02, - PageReadWrite = 0x04, - PageWriteCopy = 0x08, - PageTargetsInvalid = 0x40000000, - PageTargetsNoUpdate = 0x40000000, - - PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite | - PageWriteCopy, - PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite | - PageExecuteWriteCopy, - LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid) -}; - -// Reference: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx -struct MinidumpMemoryInfo { - llvm::support::ulittle64_t base_address; - llvm::support::ulittle64_t allocation_base; - llvm::support::ulittle32_t allocation_protect; - llvm::support::ulittle32_t alignment1; - llvm::support::ulittle64_t region_size; - llvm::support::ulittle32_t state; - llvm::support::ulittle32_t protect; - llvm::support::ulittle32_t type; - llvm::support::ulittle32_t alignment2; - - static std::vector<const MinidumpMemoryInfo *> - ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data); - - bool isReadable() const { - const auto mask = MinidumpMemoryProtectionContants::PageNoAccess; - return (static_cast<uint32_t>(mask) & protect) == 0; - } - - bool isWritable() const { - const auto mask = MinidumpMemoryProtectionContants::PageWritable; - return (static_cast<uint32_t>(mask) & protect) != 0; - } - - bool isExecutable() const { - const auto mask = MinidumpMemoryProtectionContants::PageExecutable; - return (static_cast<uint32_t>(mask) & protect) != 0; - } - - bool isMapped() const { - return state != static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree); - } -}; - -static_assert(sizeof(MinidumpMemoryInfo) == 48, - "sizeof MinidumpMemoryInfo is not correct!"); - // TODO misc2, misc3 ? // Reference: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx @@ -202,35 +118,6 @@ private: LinuxProcStatus() = default; }; -// Exception stuff -struct MinidumpException { - enum : unsigned { - ExceptonInfoMaxParams = 15, - DumpRequested = 0xFFFFFFFF, - }; - - llvm::support::ulittle32_t exception_code; - llvm::support::ulittle32_t exception_flags; - llvm::support::ulittle64_t exception_record; - llvm::support::ulittle64_t exception_address; - llvm::support::ulittle32_t number_parameters; - llvm::support::ulittle32_t unused_alignment; - llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams]; -}; -static_assert(sizeof(MinidumpException) == 152, - "sizeof MinidumpException is not correct!"); - -struct MinidumpExceptionStream { - llvm::support::ulittle32_t thread_id; - llvm::support::ulittle32_t alignment; - MinidumpException exception_record; - LocationDescriptor thread_context; - - static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data); -}; -static_assert(sizeof(MinidumpExceptionStream) == 168, - "sizeof MinidumpExceptionStream is not correct!"); - } // namespace minidump } // namespace lldb_private #endif // liblldb_MinidumpTypes_h_ diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index a7fc42cad16c9..e30a3c82a8873 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -49,16 +49,19 @@ namespace { class PlaceholderObjectFile : public ObjectFile { public: PlaceholderObjectFile(const lldb::ModuleSP &module_sp, - const ModuleSpec &module_spec, lldb::offset_t base, - lldb::offset_t size) + const ModuleSpec &module_spec, lldb::addr_t base, + lldb::addr_t size) : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), m_base(base), m_size(size) { - m_symtab_up = llvm::make_unique<Symtab>(this); + m_symtab_up = std::make_unique<Symtab>(this); } - ConstString GetPluginName() override { return ConstString("placeholder"); } + static ConstString GetStaticPluginName() { + return ConstString("placeholder"); + } + ConstString GetPluginName() override { return GetStaticPluginName(); } uint32_t GetPluginVersion() override { return 1; } bool ParseHeader() override { return true; } Type CalculateType() override { return eTypeUnknown; } @@ -80,7 +83,7 @@ public: } void CreateSections(SectionList &unified_section_list) override { - m_sections_up = llvm::make_unique<SectionList>(); + m_sections_up = std::make_unique<SectionList>(); auto section_sp = std::make_shared<Section>( GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"), eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0, @@ -109,11 +112,12 @@ public: GetFileSpec(), m_base, m_base + m_size); } + lldb::addr_t GetBaseImageAddress() const { return m_base; } private: ArchSpec m_arch; UUID m_uuid; - lldb::offset_t m_base; - lldb::offset_t m_size; + lldb::addr_t m_base; + lldb::addr_t m_size; }; } // namespace @@ -215,6 +219,9 @@ Status ProcessMinidump::DoLoadCore() { m_thread_list = m_minidump_parser->GetThreads(); m_active_exception = m_minidump_parser->GetExceptionStream(); + + SetUnixSignals(UnixSignals::Create(GetArchitecture())); + ReadModuleList(); llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid(); @@ -234,39 +241,56 @@ uint32_t ProcessMinidump::GetPluginVersion() { return 1; } Status ProcessMinidump::DoDestroy() { return Status(); } void ProcessMinidump::RefreshStateAfterStop() { + if (!m_active_exception) return; - if (m_active_exception->exception_record.exception_code == - MinidumpException::DumpRequested) { + constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF; + if (m_active_exception->ExceptionRecord.ExceptionCode == + BreakpadDumpRequested) { + // This "ExceptionCode" value is a sentinel that is sometimes used + // when generating a dump for a process that hasn't crashed. + + // TODO: The definition and use of this "dump requested" constant + // in Breakpad are actually Linux-specific, and for similar use + // cases on Mac/Windows it defines differnt constants, referring + // to them as "simulated" exceptions; consider moving this check + // down to the OS-specific paths and checking each OS for its own + // constant. return; } lldb::StopInfoSP stop_info; lldb::ThreadSP stop_thread; - Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id); + Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId); stop_thread = Process::m_thread_list.GetSelectedThread(); ArchSpec arch = GetArchitecture(); if (arch.GetTriple().getOS() == llvm::Triple::Linux) { + uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode; + + if (signo == 0) { + // No stop. + return; + } + stop_info = StopInfo::CreateStopReasonWithSignal( - *stop_thread, m_active_exception->exception_record.exception_code); + *stop_thread, signo); } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { stop_info = StopInfoMachException::CreateStopReasonWithMachException( - *stop_thread, m_active_exception->exception_record.exception_code, 2, - m_active_exception->exception_record.exception_flags, - m_active_exception->exception_record.exception_address, 0); + *stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2, + m_active_exception->ExceptionRecord.ExceptionFlags, + m_active_exception->ExceptionRecord.ExceptionAddress, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); desc_stream << "Exception " << llvm::format_hex( - m_active_exception->exception_record.exception_code, 8) + m_active_exception->ExceptionRecord.ExceptionCode, 8) << " encountered at address " << llvm::format_hex( - m_active_exception->exception_record.exception_address, - 8); + m_active_exception->ExceptionRecord.ExceptionAddress, 8); stop_info = StopInfo::CreateStopReasonWithException( *stop_thread, desc_stream.str().c_str()); } @@ -331,8 +355,8 @@ bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, // If the minidump contains an exception context, use it if (m_active_exception != nullptr && - m_active_exception->thread_id == thread.ThreadId) { - context_location = m_active_exception->thread_context; + m_active_exception->ThreadId == thread.ThreadId) { + context_location = m_active_exception->ThreadContext; } llvm::ArrayRef<uint8_t> context; @@ -351,14 +375,15 @@ void ProcessMinidump::ReadModuleList() { std::vector<const minidump::Module *> filtered_modules = m_minidump_parser->GetFilteredModuleList(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); for (auto module : filtered_modules) { std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString( module->ModuleNameRVA)); + const uint64_t load_addr = module->BaseOfImage; + const uint64_t load_size = module->SizeOfImage; LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name, - module->BaseOfImage, module->BaseOfImage + module->SizeOfImage, - module->SizeOfImage); + load_addr, load_addr + load_size, load_size); // check if the process is wow64 - a 32 bit windows process running on a // 64 bit windows @@ -373,7 +398,7 @@ void ProcessMinidump::ReadModuleList() { Status error; // Try and find a module with a full UUID that matches. This function will // add the module to the target if it finds one. - lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec, + lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error); if (!module_sp) { // Try and find a module without specifying the UUID and only looking for @@ -386,8 +411,8 @@ void ProcessMinidump::ReadModuleList() { ModuleSpec basename_module_spec(module_spec); basename_module_spec.GetUUID().Clear(); basename_module_spec.GetFileSpec().GetDirectory().Clear(); - module_sp = GetTarget().GetOrCreateModule(basename_module_spec, - true /* notify */, &error); + module_sp = GetTarget().GetOrCreateModule(basename_module_spec, + true /* notify */, &error); if (module_sp) { // We consider the module to be a match if the minidump UUID is a // prefix of the actual UUID, or if either of the UUIDs are empty. @@ -401,6 +426,19 @@ void ProcessMinidump::ReadModuleList() { } } } + if (module_sp) { + // Watch out for place holder modules that have different paths, but the + // same UUID. If the base address is different, create a new module. If + // we don't then we will end up setting the load address of a different + // PlaceholderObjectFile and an assertion will fire. + auto *objfile = module_sp->GetObjectFile(); + if (objfile && objfile->GetPluginName() == + PlaceholderObjectFile::GetStaticPluginName()) { + if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() != + load_addr) + module_sp.reset(); + } + } if (!module_sp) { // We failed to locate a matching local object file. Fortunately, the // minidump format encodes enough information about each module's memory @@ -415,12 +453,12 @@ void ProcessMinidump::ReadModuleList() { name); module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>( - module_spec, module->BaseOfImage, module->SizeOfImage); + module_spec, load_addr, load_size); GetTarget().GetImages().Append(module_sp, true /* notify */); } bool load_addr_changed = false; - module_sp->SetLoadAddress(GetTarget(), module->BaseOfImage, false, + module_sp->SetLoadAddress(GetTarget(), load_addr, false, load_addr_changed); } } @@ -444,7 +482,7 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) { // debug information than needed. JITLoaderList &ProcessMinidump::GetJITLoaders() { if (!m_jit_loaders_up) { - m_jit_loaders_up = llvm::make_unique<JITLoaderList>(); + m_jit_loaders_up = std::make_unique<JITLoaderList>(); } return *m_jit_loaders_up; } diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h index c39040f61dc5e..22dc24af7c0ef 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/source/Plugins/Process/minidump/ProcessMinidump.h @@ -108,7 +108,7 @@ private: FileSpec m_core_file; lldb::DataBufferSP m_core_data; llvm::ArrayRef<minidump::Thread> m_thread_list; - const MinidumpExceptionStream *m_active_exception; + const minidump::ExceptionStream *m_active_exception; lldb::CommandObjectSP m_command_sp; bool m_is_wow64; }; diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index f2e456097dfcc..72dead07dcb48 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -9,6 +9,7 @@ #include "RegisterContextMinidump_ARM.h" #include "Utility/ARM_DWARF_Registers.h" +#include "Utility/ARM_ehframe_Registers.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" @@ -29,14 +30,14 @@ using namespace minidump; #define DEF_R(i) \ { \ "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ - {dwarf_r##i, dwarf_r##i, INV, INV, reg_r##i}, \ + {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, \ nullptr, nullptr, nullptr, 0 \ } #define DEF_R_ARG(i, n) \ { \ "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ - {dwarf_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ + {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ nullptr, nullptr, nullptr, 0 \ } @@ -173,7 +174,7 @@ static RegisterInfo g_reg_info_apple_fp = { OFFSET(r) + 7 * 4, eEncodingUint, eFormatHex, - {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, + {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, nullptr, nullptr, nullptr, @@ -186,7 +187,7 @@ static RegisterInfo g_reg_info_fp = { OFFSET(r) + 11 * 4, eEncodingUint, eFormatHex, - {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, + {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, nullptr, nullptr, nullptr, @@ -213,7 +214,7 @@ static RegisterInfo g_reg_infos[] = { OFFSET(r) + 13 * 4, eEncodingUint, eFormatHex, - {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, nullptr, nullptr, nullptr, @@ -224,7 +225,7 @@ static RegisterInfo g_reg_infos[] = { OFFSET(r) + 14 * 4, eEncodingUint, eFormatHex, - {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, nullptr, nullptr, nullptr, @@ -235,7 +236,7 @@ static RegisterInfo g_reg_infos[] = { OFFSET(r) + 15 * 4, eEncodingUint, eFormatHex, - {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, nullptr, nullptr, nullptr, @@ -246,7 +247,7 @@ static RegisterInfo g_reg_infos[] = { OFFSET(cpsr), eEncodingUint, eFormatHex, - {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, nullptr, nullptr, nullptr, @@ -476,12 +477,22 @@ RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( lldbassert(k_num_regs == k_num_reg_infos); } -size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } +size_t RegisterContextMinidump_ARM::GetRegisterCountStatic() { + return k_num_regs; +} + +// Used for unit testing so we can verify register info is filled in for +// all register flavors (DWARF, EH Frame, generic, etc). +size_t RegisterContextMinidump_ARM::GetRegisterCount() { + return GetRegisterCountStatic(); +} +// Used for unit testing so we can verify register info is filled in. const RegisterInfo * -RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { +RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(size_t reg, + bool apple) { if (reg < k_num_reg_infos) { - if (m_apple) { + if (apple) { if (reg == reg_r7) return &g_reg_info_apple_fp; } else { @@ -493,6 +504,11 @@ RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { return nullptr; } +const RegisterInfo * +RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { + return GetRegisterInfoAtIndexStatic(reg, m_apple); +} + size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { return k_num_reg_sets; } diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h index eff8cdfef00a0..7af3b98a6fe7b 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -38,6 +38,12 @@ public: // Do nothing... registers are always valid... } + // Used for unit testing. + static size_t GetRegisterCountStatic(); + // Used for unit testing. + static const lldb_private::RegisterInfo * + GetRegisterInfoAtIndexStatic(size_t reg, bool apple); + size_t GetRegisterCount() override; const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; |