Add ptrace extensions to query a register set.

Patch by Ashok Thirumurthi.

llvm-svn: 177173
This commit is contained in:
Matt Kopec 2013-03-15 19:06:45 +00:00
parent 559008649b
commit 6773276351
4 changed files with 201 additions and 9 deletions

View File

@ -82,7 +82,10 @@ PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
//PtraceDisplayBytes(req, data);
errno = 0;
result = ptrace(req, pid, (caddr_t) addr, data);
if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
result = ptrace(req, pid, *(unsigned int *)addr, data);
else
result = ptrace(req, pid, (caddr_t) addr, data);
//PtraceDisplayBytes(req, data);
@ -121,7 +124,10 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data)
{
long result = 0;
errno = 0;
result = ptrace(req, pid, addr, data);
if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
result = ptrace(req, pid, *(unsigned int *)addr, data);
else
result = ptrace(req, pid, addr, data);
return result;
}
@ -395,6 +401,35 @@ ReadFPROperation::Execute(ProcessMonitor *monitor)
m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadRegisterSetOperation
/// @brief Implements ProcessMonitor::ReadRegisterSet.
class ReadRegisterSetOperation : public Operation
{
public:
ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
const unsigned int m_regset;
bool &m_result;
};
void
ReadRegisterSetOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf) < 0)
m_result = false;
else
m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteGPROperation
/// @brief Implements ProcessMonitor::WriteGPR.
@ -447,6 +482,35 @@ WriteFPROperation::Execute(ProcessMonitor *monitor)
m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteRegisterSetOperation
/// @brief Implements ProcessMonitor::WriteRegisterSet.
class WriteRegisterSetOperation : public Operation
{
public:
WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
const unsigned int m_regset;
bool &m_result;
};
void
WriteRegisterSetOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf) < 0)
m_result = false;
else
m_result = true;
}
//------------------------------------------------------------------------------
/// @class ResumeOperation
/// @brief Implements ProcessMonitor::Resume.
@ -1474,6 +1538,15 @@ ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
return result;
}
bool
ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
ReadRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
@ -1492,6 +1565,15 @@ ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
return result;
}
bool
ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
WriteRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
{

View File

@ -126,23 +126,33 @@ public:
bool
ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads all floating point registers into the specified buffer.
/// Reads generic floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes all general purpose registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all floating point registers into the specified buffer.
/// Writes generic floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
WriteFPR(lldb::tid_t tid, void *buf);
WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.

View File

@ -109,6 +109,13 @@ static void PtraceDisplayBytes(__ptrace_request &req, void *data, size_t data_si
verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
break;
}
case PTRACE_SETREGSET:
{
// Extract iov_base from data, which is a pointer to the struct IOVEC
DisplayBytes(buf, *(void **)data, data_size);
verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
break;
}
default:
{
}
@ -133,7 +140,10 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t da
PtraceDisplayBytes(req, data, data_size);
errno = 0;
result = ptrace(req, pid, addr, data);
if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
result = ptrace(req, pid, *(unsigned int *)addr, data);
else
result = ptrace(req, pid, addr, data);
PtraceDisplayBytes(req, data, data_size);
@ -159,8 +169,12 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t da
extern long
PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t data_size)
{
long result = 0;
errno = 0;
long result = ptrace(req, pid, addr, data);
if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
result = ptrace(req, pid, *(unsigned int *)addr, data);
else
result = ptrace(req, pid, addr, data);
return result;
}
@ -555,6 +569,35 @@ ReadFPROperation::Execute(ProcessMonitor *monitor)
m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadRegisterSetOperation
/// @brief Implements ProcessMonitor::ReadRegisterSet.
class ReadRegisterSetOperation : public Operation
{
public:
ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
const unsigned int m_regset;
bool &m_result;
};
void
ReadRegisterSetOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteGPROperation
/// @brief Implements ProcessMonitor::WriteGPR.
@ -611,6 +654,35 @@ WriteFPROperation::Execute(ProcessMonitor *monitor)
m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteRegisterSetOperation
/// @brief Implements ProcessMonitor::WriteRegisterSet.
class WriteRegisterSetOperation : public Operation
{
public:
WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
const unsigned int m_regset;
bool &m_result;
};
void
WriteRegisterSetOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
}
//------------------------------------------------------------------------------
/// @class ResumeOperation
/// @brief Implements ProcessMonitor::Resume.
@ -1663,6 +1735,15 @@ ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
return result;
}
bool
ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
ReadRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
@ -1681,6 +1762,15 @@ ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
return result;
}
bool
ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
WriteRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
{

View File

@ -122,18 +122,28 @@ public:
bool
ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads all floating point registers into the specified buffer.
/// Reads generic floating point registers into the specified buffer.
bool
ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes all general purpose registers into the specified buffer.
bool
WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all floating point registers into the specified buffer.
/// Writes generic floating point registers into the specified buffer.
bool
WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
bool