Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -63,28 +63,8 @@ /// one that spawned or attached to the process from the start. Therefore, when /// a NativeProcessLinux is asked to deliver or change the state of an inferior /// process the operation must be "funneled" to a specific thread to perform the - /// task. The Operation class provides an abstract base for all services the - /// NativeProcessLinux must perform via the single virtual function Execute, thus - /// encapsulating the code that needs to run in the privileged context. - class Operation - { - public: - Operation () : m_error() { } - - virtual - ~Operation() {} - - virtual void - Execute (NativeProcessLinux *process) = 0; - - const Error & - GetError () const { return m_error; } - - protected: - Error m_error; - }; - - typedef std::unique_ptr OperationUP; + /// task. + typedef std::function Operation; // --------------------------------------------------------------------- // NativeProcessProtocol Interface @@ -159,10 +139,7 @@ // Interface used by NativeRegisterContext-derived classes. // --------------------------------------------------------------------- Error - DoOperation(Operation* op); - - Error - DoOperation(OperationUP op) { return DoOperation(op.get()); } + DoOperation(const Operation &op); static long PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error); Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -226,18 +226,17 @@ // NativeProcessLinux::WriteMemory. This enables mutual recursion between these // functions without needed to go thru the thread funnel. - size_t + Error DoReadMemory( lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size, - Error &error) + size_t &bytes_read) { // ptrace word size is determined by the host, not the child static const unsigned word_size = sizeof(void*); unsigned char *dst = static_cast(buf); - size_t bytes_read; size_t remainder; long data; @@ -251,12 +250,13 @@ assert(sizeof(data) >= word_size); for (bytes_read = 0; bytes_read < size; bytes_read += remainder) { + Error error; data = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error); if (error.Fail()) { if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_read; + return error; } remainder = size - bytes_read; @@ -284,22 +284,22 @@ if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_read; + return Error(); } - size_t + Error DoWriteMemory( lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf, size_t size, - Error &error) + size_t &bytes_written) { // ptrace word size is determined by the host, not the child static const unsigned word_size = sizeof(void*); const unsigned char *src = static_cast(buf); - size_t bytes_written = 0; size_t remainder; + Error error; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); if (log) @@ -331,28 +331,30 @@ { if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_written; + return error; } } else { unsigned char buff[8]; - if (DoReadMemory(pid, vm_addr, - buff, word_size, error) != word_size) + size_t bytes_read; + error = DoReadMemory(pid, vm_addr, buff, word_size, bytes_read); + if (error.Fail()) { if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_written; + return error; } memcpy(buff, src, remainder); - if (DoWriteMemory(pid, vm_addr, - buff, word_size, error) != word_size) + size_t bytes_written_rec; + error = DoWriteMemory(pid, vm_addr, buff, word_size, bytes_written_rec); + if (error.Fail()) { if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_written; + return error; } if (log && ProcessPOSIXLog::AtTopNestLevel() && @@ -368,197 +370,7 @@ } if (log) ProcessPOSIXLog::DecNestLevel(); - return bytes_written; - } - - //------------------------------------------------------------------------------ - /// @class ReadOperation - /// @brief Implements NativeProcessLinux::ReadMemory. - class ReadOperation : public NativeProcessLinux::Operation - { - public: - ReadOperation( - lldb::addr_t addr, - void *buff, - size_t size, - size_t &result) : - Operation (), - m_addr (addr), - m_buff (buff), - m_size (size), - m_result (result) - { - } - - void Execute (NativeProcessLinux *process) override; - - private: - lldb::addr_t m_addr; - void *m_buff; - size_t m_size; - size_t &m_result; - }; - - void - ReadOperation::Execute (NativeProcessLinux *process) - { - m_result = DoReadMemory (process->GetID (), m_addr, m_buff, m_size, m_error); - } - - //------------------------------------------------------------------------------ - /// @class WriteOperation - /// @brief Implements NativeProcessLinux::WriteMemory. - class WriteOperation : public NativeProcessLinux::Operation - { - public: - WriteOperation( - lldb::addr_t addr, - const void *buff, - size_t size, - size_t &result) : - Operation (), - m_addr (addr), - m_buff (buff), - m_size (size), - m_result (result) - { - } - - void Execute (NativeProcessLinux *process) override; - - private: - lldb::addr_t m_addr; - const void *m_buff; - size_t m_size; - size_t &m_result; - }; - - void - WriteOperation::Execute(NativeProcessLinux *process) - { - m_result = DoWriteMemory (process->GetID (), m_addr, m_buff, m_size, m_error); - } - - //------------------------------------------------------------------------------ - /// @class ResumeOperation - /// @brief Implements NativeProcessLinux::Resume. - class ResumeOperation : public NativeProcessLinux::Operation - { - public: - ResumeOperation(lldb::tid_t tid, uint32_t signo) : - m_tid(tid), m_signo(signo) { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uint32_t m_signo; - }; - - void - ResumeOperation::Execute(NativeProcessLinux *monitor) - { - intptr_t data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - NativeProcessLinux::PtraceWrapper(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error); - if (m_error.Fail()) - { - Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); - - if (log) - log->Printf ("ResumeOperation (%" PRIu64 ") failed: %s", m_tid, m_error.AsCString()); - } - } - - //------------------------------------------------------------------------------ - /// @class SingleStepOperation - /// @brief Implements NativeProcessLinux::SingleStep. - class SingleStepOperation : public NativeProcessLinux::Operation - { - public: - SingleStepOperation(lldb::tid_t tid, uint32_t signo) - : m_tid(tid), m_signo(signo) { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uint32_t m_signo; - }; - - void - SingleStepOperation::Execute(NativeProcessLinux *monitor) - { - intptr_t data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error); - } - - //------------------------------------------------------------------------------ - /// @class SiginfoOperation - /// @brief Implements NativeProcessLinux::GetSignalInfo. - class SiginfoOperation : public NativeProcessLinux::Operation - { - public: - SiginfoOperation(lldb::tid_t tid, void *info) - : m_tid(tid), m_info(info) { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_info; - }; - - void - SiginfoOperation::Execute(NativeProcessLinux *monitor) - { - NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error); - } - - //------------------------------------------------------------------------------ - /// @class EventMessageOperation - /// @brief Implements NativeProcessLinux::GetEventMessage. - class EventMessageOperation : public NativeProcessLinux::Operation - { - public: - EventMessageOperation(lldb::tid_t tid, unsigned long *message) - : m_tid(tid), m_message(message) { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - unsigned long *m_message; - }; - - void - EventMessageOperation::Execute(NativeProcessLinux *monitor) - { - NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error); - } - - class DetachOperation : public NativeProcessLinux::Operation - { - public: - DetachOperation(lldb::tid_t tid) : m_tid(tid) { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - }; - - void - DetachOperation::Execute(NativeProcessLinux *monitor) - { - NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error); + return error; } } // end of anonymous namespace @@ -610,10 +422,10 @@ HostThread m_thread; // current operation which must be executed on the priviliged thread - Mutex m_operation_mutex; - Operation *m_operation = nullptr; - sem_t m_operation_sem; - Error m_operation_error; + Mutex m_operation_mutex; + const Operation *m_operation = nullptr; + sem_t m_operation_sem; + Error m_operation_error; unsigned m_operation_nesting_level = 0; @@ -671,8 +483,8 @@ void Terminate(); - void - DoOperation(Operation *op); + Error + DoOperation(const Operation &op); class ScopedOperationLock { Monitor &m_monitor; @@ -728,24 +540,23 @@ return WaitForAck(); } -void -NativeProcessLinux::Monitor::DoOperation(Operation *op) +Error +NativeProcessLinux::Monitor::DoOperation(const Operation &op) { if (m_thread.EqualsThread(pthread_self())) { // If we're on the Monitor thread, we can simply execute the operation. - op->Execute(m_native_process); - return; + return op(); } // Otherwise we need to pass the operation to the Monitor thread so it can handle it. Mutex::Locker lock(m_operation_mutex); - m_operation = op; + m_operation = &op; // notify the thread that an operation is ready to be processed write(m_pipefd[WRITE], &operation_command, sizeof operation_command); - WaitForAck(); + return WaitForAck(); } void @@ -899,7 +710,7 @@ switch (command) { case operation_command: - m_operation->Execute(m_native_process); + m_operation_error = (*m_operation)(); break; case begin_block_command: ++m_operation_nesting_level; @@ -3329,9 +3140,7 @@ // the call failed for some reason, let's retry the read using ptrace api. } - ReadOperation op(addr, buf, size, bytes_read); - m_monitor_up->DoOperation(&op); - return op.GetError (); + return DoOperation([&] { return DoReadMemory(GetID(), addr, buf, size, bytes_read); }); } Error @@ -3345,9 +3154,7 @@ Error NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { - WriteOperation op(addr, buf, size, bytes_written); - m_monitor_up->DoOperation(&op); - return op.GetError (); + return DoOperation([&] { return DoWriteMemory(GetID(), addr, buf, size, bytes_written); }); } Error @@ -3358,35 +3165,58 @@ if (log) log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " with signal %s", __FUNCTION__, tid, GetUnixSignals().GetSignalAsCString (signo)); - ResumeOperation op (tid, signo); - m_monitor_up->DoOperation (&op); + + + + intptr_t data = 0; + + if (signo != LLDB_INVALID_SIGNAL_NUMBER) + data = signo; + + Error error = DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data, 0, error); + return error; + }); + if (log) - log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " result = %s", __FUNCTION__, tid, op.GetError().Success() ? "true" : "false"); - return op.GetError(); + log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " result = %s", __FUNCTION__, tid, error.Success() ? "true" : "false"); + return error; } Error NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo) { - SingleStepOperation op(tid, signo); - m_monitor_up->DoOperation(&op); - return op.GetError(); + intptr_t data = 0; + + if (signo != LLDB_INVALID_SIGNAL_NUMBER) + data = signo; + + return DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, tid, nullptr, (void*)data, 0, error); + return error; + }); } Error NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) { - SiginfoOperation op(tid, siginfo); - m_monitor_up->DoOperation(&op); - return op.GetError(); + return DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo, 0, error); + return error; + }); } Error NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message) { - EventMessageOperation op(tid, message); - m_monitor_up->DoOperation(&op); - return op.GetError(); + return DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message, 0, error); + return error; + }); } Error @@ -3395,9 +3225,11 @@ if (tid == LLDB_INVALID_THREAD_ID) return Error(); - DetachOperation op(tid); - m_monitor_up->DoOperation(&op); - return op.GetError(); + return DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, tid, nullptr, 0, 0, error); + return error; + }); } bool @@ -3893,10 +3725,9 @@ } Error -NativeProcessLinux::DoOperation(Operation* op) +NativeProcessLinux::DoOperation(const Operation &op) { - m_monitor_up->DoOperation(op); - return op->GetError(); + return m_monitor_up->DoOperation(op); } // Wrapper for ptrace to catch errors and log calls. Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.h @@ -74,28 +74,31 @@ virtual size_t GetFPRSize() { return 0; } - virtual NativeProcessLinux::OperationUP - GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value); - - virtual NativeProcessLinux::OperationUP - GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value); - - virtual NativeProcessLinux::OperationUP - GetReadGPROperation(void *buf, size_t buf_size); - virtual NativeProcessLinux::OperationUP - GetWriteGPROperation(void *buf, size_t buf_size); + // The Do*** functions are executed on the privileged thread and can perform ptrace + // operations directly. + virtual Error + DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value); - virtual NativeProcessLinux::OperationUP - GetReadFPROperation(void *buf, size_t buf_size); + virtual Error + DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value); - virtual NativeProcessLinux::OperationUP - GetWriteFPROperation(void *buf, size_t buf_size); + virtual Error + DoReadGPR(void *buf, size_t buf_size); + + virtual Error + DoWriteGPR(void *buf, size_t buf_size); + + virtual Error + DoReadFPR(void *buf, size_t buf_size); + + virtual Error + DoWriteFPR(void *buf, size_t buf_size); }; } // namespace process_linux Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp @@ -19,204 +19,6 @@ using namespace lldb_private; using namespace lldb_private::process_linux; -namespace -{ - -class ReadRegOperation : public NativeProcessLinux::Operation -{ -public: - ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, RegisterValue &value) : - m_tid(tid), - m_offset(static_cast(offset)), - m_reg_name(reg_name), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - RegisterValue &m_value; -}; - -class WriteRegOperation : public NativeProcessLinux::Operation -{ -public: - WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) : - m_tid(tid), - m_offset(offset), - m_reg_name(reg_name), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - const RegisterValue &m_value; -}; - -class ReadGPROperation : public NativeProcessLinux::Operation -{ -public: - ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class WriteGPROperation : public NativeProcessLinux::Operation -{ -public: - WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class ReadFPROperation : public NativeProcessLinux::Operation -{ -public: - ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class WriteFPROperation : public NativeProcessLinux::Operation -{ -public: - WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class ReadRegisterSetOperation : public NativeProcessLinux::Operation -{ -public: - ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - const unsigned int m_regset; -}; - -class WriteRegisterSetOperation : public NativeProcessLinux::Operation -{ -public: - WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - const unsigned int m_regset; -}; - -} // end of anonymous namespace - -void -ReadRegOperation::Execute(NativeProcessLinux *monitor) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - lldb::addr_t data = static_cast(NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSER, m_tid, (void*)m_offset, nullptr, 0, m_error)); - if (m_error.Success()) - m_value = data; - - if (log) - log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__, m_reg_name, data); -} - -void -WriteRegOperation::Execute(NativeProcessLinux *monitor) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - void* buf = (void*)m_value.GetAsUInt64(); - - if (log) - log->Printf ("NativeProcessLinux::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf); - NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0, m_error); -} - -void -ReadGPROperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -} - -void -WriteGPROperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -} - -void -ReadFPROperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -} - -void -WriteFPROperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -} - -void -ReadRegisterSetOperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error); -} - -void -WriteRegisterSetOperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error); -} - NativeRegisterContextLinux::NativeRegisterContextLinux(NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) : @@ -253,10 +55,9 @@ return Error("NativeProcessProtocol is NULL"); NativeProcessLinux* process_p = static_cast(process_sp.get()); - return process_p->DoOperation(GetReadRegisterValueOperation(reg_info->byte_offset, - reg_info->name, - reg_info->byte_size, - reg_value)); + return process_p->DoOperation([&] { + return DoReadRegisterValue(reg_info->byte_offset, reg_info->name, reg_info->byte_size, reg_value); + }); } Error @@ -317,9 +118,9 @@ return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write); NativeProcessLinux* process_p = static_cast (process_sp.get ()); - return process_p->DoOperation(GetWriteRegisterValueOperation(reg_info->byte_offset, - reg_info->name, - reg_value)); + return process_p->DoOperation([&] { + return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value); + }); } Error @@ -335,7 +136,7 @@ size_t buf_size = GetGPRSize(); NativeProcessLinux* process_p = static_cast(process_sp.get()); - return process_p->DoOperation(GetReadGPROperation(buf, buf_size)); + return process_p->DoOperation([&] { return DoReadGPR(buf, buf_size); }); } Error @@ -351,7 +152,7 @@ size_t buf_size = GetGPRSize(); NativeProcessLinux* process_p = static_cast(process_sp.get()); - return process_p->DoOperation(GetWriteGPROperation(buf, buf_size)); + return process_p->DoOperation([&] { return DoWriteGPR(buf, buf_size); }); } Error @@ -367,7 +168,7 @@ size_t buf_size = GetFPRSize(); NativeProcessLinux* process_p = static_cast(process_sp.get()); - return process_p->DoOperation(GetReadFPROperation(buf, buf_size)); + return process_p->DoOperation([&] { return DoReadFPR(buf, buf_size); }); } Error @@ -383,7 +184,7 @@ size_t buf_size = GetFPRSize(); NativeProcessLinux* process_p = static_cast(process_sp.get()); - return process_p->DoOperation(GetWriteFPROperation(buf, buf_size)); + return process_p->DoOperation([&] { return DoWriteFPR(buf, buf_size); }); } Error @@ -394,8 +195,12 @@ return Error("NativeProcessProtocol is NULL"); NativeProcessLinux* process_p = static_cast(process_sp.get()); - ReadRegisterSetOperation op(m_thread.GetID(), buf, buf_size, regset); - return process_p->DoOperation(&op); + return process_p->DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), + static_cast(®set), buf, buf_size, error); + return error; + }); } Error @@ -406,47 +211,82 @@ return Error("NativeProcessProtocol is NULL"); NativeProcessLinux* process_p = static_cast(process_sp.get()); - WriteRegisterSetOperation op(m_thread.GetID(), buf, buf_size, regset); - return process_p->DoOperation(&op); + return process_p->DoOperation([&] { + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), + static_cast(®set), buf, buf_size, error); + return error; + }); } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) +Error +NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value) { - return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, reg_name, value)); + Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); + Error error; + + lldb::addr_t data = NativeProcessLinux::PtraceWrapper( + PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast(offset), nullptr, 0, error); + + if (error.Success()) + value = data; + + if (log) + log->Printf ("NativeRegisterContextLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__, reg_name, data); + + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value) +Error +NativeRegisterContextLinux::DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value) { - return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value)); + Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); + + void* buf = reinterpret_cast(value.GetAsUInt64()); + + if (log) + log->Printf ("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__, reg_name, buf); + + Error error; + NativeProcessLinux::PtraceWrapper( + PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast(offset), buf, 0, error); + + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetReadGPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new ReadGPROperation(m_thread.GetID(), buf, buf_size)); + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), nullptr, buf, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetWriteGPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new WriteGPROperation(m_thread.GetID(), buf, buf_size)); + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(), nullptr, buf, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetReadFPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new ReadFPROperation(m_thread.GetID(), buf, buf_size)); + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(), nullptr, buf, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux::GetWriteFPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new WriteFPROperation(m_thread.GetID(), buf, buf_size)); + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(), nullptr, buf, buf_size, error); + return error; } Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -80,28 +80,28 @@ WatchpointIsEnabled(uint32_t wp_index); protected: - NativeProcessLinux::OperationUP - GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) override; - - NativeProcessLinux::OperationUP - GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value) override; - - NativeProcessLinux::OperationUP - GetReadGPROperation(void *buf, size_t buf_size) override; + Error + DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value) override; + + Error + DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value) override; + + Error + DoReadGPR(void *buf, size_t buf_size) override; - NativeProcessLinux::OperationUP - GetWriteGPROperation(void *buf, size_t buf_size) override; + Error + DoWriteGPR(void *buf, size_t buf_size) override; - NativeProcessLinux::OperationUP - GetReadFPROperation(void *buf, size_t buf_size) override; + Error + DoReadFPR(void *buf, size_t buf_size) override; - NativeProcessLinux::OperationUP - GetWriteFPROperation(void *buf, size_t buf_size) override; + Error + DoWriteFPR(void *buf, size_t buf_size) override; void* GetGPRBuffer() override { return &m_gpr_arm64; } Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -137,327 +137,6 @@ { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 } }; -namespace -{ - -class ReadRegOperation : public NativeProcessLinux::Operation -{ -public: - ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, RegisterValue &value) : - m_tid(tid), - m_offset(static_cast(offset)), - m_reg_name(reg_name), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - RegisterValue &m_value; -}; - -class WriteRegOperation : public NativeProcessLinux::Operation -{ -public: - WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) : - m_tid(tid), - m_offset(offset), - m_reg_name(reg_name), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - const RegisterValue &m_value; -}; - -class ReadGPROperation : public NativeProcessLinux::Operation -{ -public: - ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class WriteGPROperation : public NativeProcessLinux::Operation -{ -public: - WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) : - m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class ReadFPROperation : public NativeProcessLinux::Operation -{ -public: - ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), - m_buf(buf), - m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class WriteFPROperation : public NativeProcessLinux::Operation -{ -public: - WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; -}; - -class ReadDBGROperation : public NativeProcessLinux::Operation -{ -public: - ReadDBGROperation(lldb::tid_t tid, unsigned int &count_wp, unsigned int &count_bp) - : m_tid(tid), - m_count_wp(count_wp), - m_count_bp(count_bp) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - unsigned int &m_count_wp; - unsigned int &m_count_bp; -}; - -class WriteDBGROperation : public NativeProcessLinux::Operation -{ -public: - WriteDBGROperation(lldb::tid_t tid, lldb::addr_t *addr_buf, - uint32_t *cntrl_buf, int type, int count) - : m_tid(tid), - m_address(addr_buf), - m_control(cntrl_buf), - m_type(type), - m_count(count) - { } - - void Execute(NativeProcessLinux *monitor) override; - -private: - lldb::tid_t m_tid; - lldb::addr_t * m_address; - uint32_t * m_control; - int m_type; - int m_count; -}; - -} // end of anonymous namespace - -void -ReadRegOperation::Execute(NativeProcessLinux *monitor) -{ - if (m_offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = m_offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - m_error.SetErrorString("invalid offset value"); - return; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } - } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } - } -} - -void -WriteRegOperation::Execute(NativeProcessLinux *monitor) -{ - if (m_offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = m_offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - m_error.SetErrorString("invalid offset value"); - return; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + offset), m_value.GetBytes(), 16); - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - } - } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - } - } -} - -void -ReadGPROperation::Execute(NativeProcessLinux *monitor) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -} - -void -WriteGPROperation::Execute(NativeProcessLinux *monitor) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -} - -void -ReadFPROperation::Execute(NativeProcessLinux *monitor) -{ - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -} - -void -WriteFPROperation::Execute(NativeProcessLinux *monitor) -{ - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -} - -void -ReadDBGROperation::Execute(NativeProcessLinux *monitor) -{ - int regset = NT_ARM_HW_WATCH; - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - - ioVec.iov_base = &dreg_state; - ioVec.iov_len = sizeof (dreg_state); - - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, ioVec.iov_len, m_error); - - m_count_wp = dreg_state.dbg_info & 0xff; - regset = NT_ARM_HW_BREAK; - - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, ®set, &ioVec, ioVec.iov_len, m_error); - m_count_bp = dreg_state.dbg_info & 0xff; -} - -void -WriteDBGROperation::Execute(NativeProcessLinux *monitor) -{ - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - - memset (&dreg_state, 0, sizeof (dreg_state)); - ioVec.iov_base = &dreg_state; - ioVec.iov_len = sizeof (dreg_state); - - if (m_type == 0) - m_type = NT_ARM_HW_WATCH; - else - m_type = NT_ARM_HW_BREAK; - - for (int i = 0; i < m_count; i++) - { - dreg_state.dbg_regs[i].addr = m_address[i]; - dreg_state.dbg_regs[i].ctrl = m_control[i]; - } - - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &m_type, &ioVec, ioVec.iov_len, m_error); -} - NativeRegisterContextLinux* NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch, NativeThreadProtocol &native_thread, @@ -1046,9 +725,25 @@ if (!process_sp) return Error("NativeProcessProtocol is NULL"); NativeProcessLinux *const process_p = reinterpret_cast(process_sp.get()); + ::pid_t tid = m_thread.GetID(); + + return process_p->DoOperation([&] { + int regset = NT_ARM_HW_WATCH; + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + Error error; + + ioVec.iov_base = &dreg_state; + ioVec.iov_len = sizeof (dreg_state); + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len, error); + watch_count = dreg_state.dbg_info & 0xff; + + regset = NT_ARM_HW_BREAK; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len, error); + break_count = dreg_state.dbg_info & 0xff; - ReadDBGROperation op(m_thread.GetID(), watch_count, break_count); - return process_p->DoOperation(&op); + return error; + }); } Error @@ -1062,49 +757,182 @@ return Error("NativeProcessProtocol is NULL"); NativeProcessLinux *const process_p = reinterpret_cast(process_sp.get()); - WriteDBGROperation op(m_thread.GetID(), addr_buf, cntrl_buf, type, count); - return process_p->DoOperation(&op); + return process_p->DoOperation([&] { + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + Error error; + + memset (&dreg_state, 0, sizeof (dreg_state)); + ioVec.iov_base = &dreg_state; + ioVec.iov_len = sizeof (dreg_state); + + if (type == 0) + type = NT_ARM_HW_WATCH; + else + type = NT_ARM_HW_BREAK; + + for (int i = 0; i < count; i++) + { + dreg_state.dbg_regs[i].addr = addr_buf[i]; + dreg_state.dbg_regs[i].ctrl = cntrl_buf[i]; + } + + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &type, &ioVec, ioVec.iov_len, error); + return error; + }); } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) +Error +NativeRegisterContextLinux_arm64::DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value) { - return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, reg_name, value)); + Error error; + if (offset > sizeof(struct user_pt_regs)) + { + uintptr_t offset = offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) + { + error.SetErrorString("invalid offset value"); + return error; + } + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + NativeProcessLinux::PtraceWrapper( + PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs, error); + if (error.Success()) + { + ArchSpec arch; + if (m_thread.GetProcess()->GetArchitecture(arch)) + value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, arch.GetByteOrder()); + else + error.SetErrorString("failed to get architecture"); + } + } + else + { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + NativeProcessLinux::PtraceWrapper( + PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs, error); + if (error.Success()) + { + ArchSpec arch; + if (m_thread.GetProcess()->GetArchitecture(arch)) + value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, arch.GetByteOrder()); + else + error.SetErrorString("failed to get architecture"); + } + } + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value) +Error +NativeRegisterContextLinux_arm64::DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value) { - return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value)); + Error error; + ::pid_t tid = m_thread.GetID(); + if (offset > sizeof(struct user_pt_regs)) + { + uintptr_t offset = offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) + { + error.SetErrorString("invalid offset value"); + return error; + } + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + NativeProcessLinux::PtraceWrapper( PTRACE_GETREGSET, tid, ®set, &ioVec, sizeof regs, error); + + if (error.Success()) + { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), 16); + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, &ioVec, sizeof regs, error); + } + } + else + { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, sizeof regs, error); + if (error.Success()) + { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), 8); + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, &ioVec, sizeof regs, error); + } + } + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetReadGPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new ReadGPROperation(m_thread.GetID(), buf, buf_size)); + int regset = NT_PRSTATUS; + struct iovec ioVec; + Error error; + + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetWriteGPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new WriteGPROperation(m_thread.GetID(), buf, buf_size)); + int regset = NT_PRSTATUS; + struct iovec ioVec; + Error error; + + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetReadFPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new ReadFPROperation(m_thread.GetID(), buf, buf_size)); + int regset = NT_FPREGSET; + struct iovec ioVec; + Error error; + + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_arm64::GetWriteFPROperation(void *buf, size_t buf_size) +Error +NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size) { - return NativeProcessLinux::OperationUP(new WriteFPROperation(m_thread.GetID(), buf, buf_size)); + int regset = NT_FPREGSET; + struct iovec ioVec; + Error error; + + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size, error); + return error; } #endif // defined (__arm64__) || defined (__aarch64__) Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h @@ -87,24 +87,22 @@ NumSupportedHardwareWatchpoints () override; protected: - NativeProcessLinux::OperationUP - GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) override; - - NativeProcessLinux::OperationUP - GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value) override; - - NativeProcessLinux::OperationUP - GetReadWatchPointRegisterValueOperation(lldb::tid_t tid, - void* watch_readback); - - NativeProcessLinux::OperationUP - GetWriteWatchPointRegisterValueOperation(lldb::tid_t tid, - void* watch_readback); + Error + DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value) override; + + Error + DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value) override; + + Error + DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback); + + Error + DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback); bool IsFR0(); Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -290,126 +290,8 @@ { "Floating Point Registers", "fpu", k_num_fpr_registers_mips64, g_fp_regnums_mips64 } }; - class ReadRegOperation : public NativeProcessLinux::Operation - { - public: - ReadRegOperation(lldb::tid_t tid, uint32_t offset, RegisterValue &value) : - m_tid(tid), - m_offset(static_cast(offset)), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uintptr_t m_offset; - RegisterValue &m_value; - }; - - class WriteRegOperation : public NativeProcessLinux::Operation - { - public: - WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) : - m_tid(tid), - m_offset(offset), - m_reg_name(reg_name), - m_value(value) - { } - - void - Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - const RegisterValue &m_value; - }; - - //------------------------------------------------------------------------------ - /// @class ReadWatchPointRegOperation - /// @brief Implements NativeRegisterContextLinux_mips64::ReadWatchPointRegisterValue. - class ReadWatchPointRegOperation : public NativeProcessLinux::Operation - { - public: - ReadWatchPointRegOperation ( - lldb::tid_t tid, - void* watch_readback) : - m_tid(tid), - m_watch_readback(watch_readback) - { - } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void* m_watch_readback; - }; - - //------------------------------------------------------------------------------ - /// @class SetWatchPointRegOperation - /// @brief Implements NativeRegisterContextLinux_mips64::SetWatchPointRegisterValue. - class SetWatchPointRegOperation : public NativeProcessLinux::Operation - { - public: - SetWatchPointRegOperation ( - lldb::tid_t tid, - void* watch_reg_value) : - m_tid(tid), - m_watch_reg_value(watch_reg_value) - { - } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void* m_watch_reg_value; - }; } // end of anonymous namespace -void -ReadRegOperation::Execute(NativeProcessLinux *monitor) -{ - elf_gregset_t regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - if (m_error.Success()) - { - lldb_private::ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } -} - -void -WriteRegOperation::Execute(NativeProcessLinux *monitor) -{ - elf_gregset_t regs; - NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); - NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - } -} - -void -ReadWatchPointRegOperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS, m_tid, m_watch_readback, NULL, NULL, m_error); -} - -void -SetWatchPointRegOperation::Execute(NativeProcessLinux *monitor) -{ - NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS, m_tid, m_watch_reg_value, NULL, NULL, m_error); -} - NativeRegisterContextLinux* NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch, NativeThreadProtocol &native_thread, @@ -996,14 +878,18 @@ // reading the current state of watch regs struct pt_watch_regs watch_readback; NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); - NativeProcessLinux *const process_p = reinterpret_cast (process_sp.get ()); - Error error = process_p->DoOperation(GetReadWatchPointRegisterValueOperation(m_thread.GetID(),(void*)&watch_readback)); + NativeProcessLinux *const process_p = static_cast (process_sp.get ()); + Error error = process_p->DoOperation([&] { + return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(&watch_readback)); + }); if (GetWatchHi (&watch_readback, wp_index) & (IRW)) { // clear hit flag in watchhi SetWatchHi (&watch_readback, wp_index, (GetWatchHi (&watch_readback, wp_index) & ~(IRW))); - process_p->DoOperation(GetWriteWatchPointRegisterValueOperation(m_thread.GetID(), (void*)&watch_readback)); + process_p->DoOperation([&] { + return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast(&watch_readback)); + }); is_hit = true; return error; @@ -1045,8 +931,10 @@ struct pt_watch_regs regs; // First reading the current state of watch regs NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); - NativeProcessLinux *const process_p = reinterpret_cast (process_sp.get ()); - process_p->DoOperation(GetReadWatchPointRegisterValueOperation(m_thread.GetID(),(void*)®s)); + NativeProcessLinux *const process_p = static_cast (process_sp.get ()); + process_p->DoOperation([&] { + return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + }); if (regs.style == pt_watch_style_mips32) { @@ -1061,7 +949,9 @@ regs.mips64.watch_masks[wp_index] = default_watch_regs.mips64.watch_masks[wp_index]; } - Error error = process_p->DoOperation(GetWriteWatchPointRegisterValueOperation(m_thread.GetID(), (void*)®s)); + Error error = process_p->DoOperation([&] { + return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + }); if(!error.Fail()) { hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS; @@ -1074,8 +964,10 @@ NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() { NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); - NativeProcessLinux *const process_p = reinterpret_cast (process_sp.get ()); - return process_p->DoOperation(GetWriteWatchPointRegisterValueOperation(m_thread.GetID(), (void*)&default_watch_regs)); + NativeProcessLinux *const process_p = static_cast (process_sp.get ()); + return process_p->DoOperation([&] { + return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast(&default_watch_regs)); + }); } Error @@ -1095,8 +987,10 @@ // First reading the current state of watch regs NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); - NativeProcessLinux *const process_p = reinterpret_cast (process_sp.get ()); - process_p->DoOperation(GetReadWatchPointRegisterValueOperation(m_thread.GetID(),(void*)®s)); + NativeProcessLinux *const process_p = static_cast (process_sp.get ()); + process_p->DoOperation([&] { + return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + }); // Try if a new watch point fits in this state int index = GetVacantWatchIndex (®s, addr, size, watch_flags, NumSupportedHardwareWatchpoints()); @@ -1107,7 +1001,9 @@ // It fits, so we go ahead with updating the state of watch regs - process_p->DoOperation(GetWriteWatchPointRegisterValueOperation(m_thread.GetID(), (void*)®s)); + process_p->DoOperation([&] { + return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + }); // Storing exact address hw_addr_map[index] = addr; @@ -1138,8 +1034,10 @@ return 0; } - NativeProcessLinux *const process_p = reinterpret_cast (process_sp.get ()); - process_p->DoOperation(GetReadWatchPointRegisterValueOperation(m_thread.GetID(),(void*)®s)); + NativeProcessLinux *const process_p = static_cast (process_sp.get ()); + process_p->DoOperation([&] { + return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + }); default_watch_regs = regs; // Keeping default watch regs values for future use switch (regs.style) { @@ -1156,34 +1054,58 @@ } return num_valid; } - -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_mips64::GetReadRegisterValueOperation(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) +Error +NativeRegisterContextLinux_mips64::DoReadRegisterValue(uint32_t offset, + const char* reg_name, + uint32_t size, + RegisterValue &value) { - return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, value)); + Error error; + elf_gregset_t regs; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), NULL, ®s, sizeof regs, error); + if (error.Success()) + { + lldb_private::ArchSpec arch; + if (m_thread.GetProcess()->GetArchitecture(arch)) + value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, arch.GetByteOrder()); + else + error.SetErrorString("failed to get architecture"); + } + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_mips64::GetWriteRegisterValueOperation(uint32_t offset, - const char* reg_name, - const RegisterValue &value) +Error +NativeRegisterContextLinux_mips64::DoWriteRegisterValue(uint32_t offset, + const char* reg_name, + const RegisterValue &value) { - return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value)); + Error error; + elf_gregset_t regs; + NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), NULL, ®s, sizeof regs, error); + if (error.Success()) + { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), 8); + NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(), NULL, ®s, sizeof regs, error); + } + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_mips64::GetReadWatchPointRegisterValueOperation(lldb::tid_t tid, void* watch_readback) +Error +NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback) { - return NativeProcessLinux::OperationUP(new ReadWatchPointRegOperation(m_thread.GetID(), watch_readback)); + Error error; + NativeProcessLinux::PtraceWrapper( + PTRACE_GET_WATCH_REGS, m_thread.GetID(), watch_readback, NULL, 0, error); + return error; } -NativeProcessLinux::OperationUP -NativeRegisterContextLinux_mips64::GetWriteWatchPointRegisterValueOperation(lldb::tid_t tid, void* watch_reg_value) +Error +NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_reg_value) { - return NativeProcessLinux::OperationUP(new SetWatchPointRegOperation(m_thread.GetID(), watch_reg_value)); + Error error; + NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS, + m_thread.GetID(), watch_reg_value, NULL, 0, error); + return error; } #endif // defined (__mips__)