2#include "pedigree/kernel/process/Thread.h"
3#include "pedigree/kernel/process/Uninterruptible.h"
4#include "pedigree/kernel/processor/Processor.h"
5#include "pedigree/kernel/processor/ProcessorInformation.h"
6#include "pedigree/kernel/syscallError.h"
10#include "PosixSubsystem.h"
11#include "ptrace-syscalls.h"
12#include "trace-state.h"
15constexpr unsigned long TraceMe = 0, Continue = 7, GetRegisters = 12, Detach = 17;
16constexpr unsigned long GetSignalInfo = 0x4202, GetRegisterSet = 0x4204;
17constexpr uint32_t GeneralRegisters = 1;
20 uint64_t base, length;
22static_assert(
sizeof(LinuxIovec) == 16,
"Linux amd64 iovec size");
23static_assert(offsetof(LinuxIovec, length) == 8,
"Linux amd64 iov_len offset");
27 TraceResult() : m_Thread(*
Processor::information().getCurrentThread()) {}
29 m_Thread.setErrno(m_Error);
31 long finish(
long value) {
32 m_Error = value < 0 ? m_Thread.getErrno() : 0;
41int statusResult(TraceStatus status) {
43 case TraceStatus::Success:
45 case TraceStatus::Missing:
46 case TraceStatus::NotStopped:
47 SYSCALL_ERROR(NoSuchProcess);
49 case TraceStatus::Denied:
50 SYSCALL_ERROR(NotEnoughPermissions);
52 case TraceStatus::Busy:
53 case TraceStatus::Unsupported:
54 SYSCALL_ERROR(OperationNotSupported);
56 case TraceStatus::NoMemory:
57 SYSCALL_ERROR(OutOfMemory);
59 case TraceStatus::Full:
60 SYSCALL_ERROR(NoMoreProcesses);
62 case TraceStatus::Invalid:
63 SYSCALL_ERROR(InvalidArgument);
69bool deferredRequest(
unsigned long request) {
112int copyRegisters(
const Amd64UserRegisters& registers, uintptr_t destination,
size_t length) {
115 SYSCALL_ERROR(BadAddress);
122long posix_ptrace(
unsigned long request, int32_t pid, uintptr_t address, uintptr_t data,
127 SYSCALL_ERROR(OperationNotSupported);
128 return result.finish(-1);
130 if (!linuxAbi || deferredRequest(request)) {
131 SYSCALL_ERROR(OperationNotSupported);
132 return result.finish(-1);
134 if (request == TraceMe)
135 return result.finish(statusResult(posix_trace_traceme()));
136 if (request != Continue && request != Detach && request != GetRegisters &&
137 request != GetSignalInfo && request != GetRegisterSet) {
138 SYSCALL_ERROR(IoError);
139 return result.finish(-1);
143 if (statusResult(posix_trace_lookup(pid, relation)))
144 return result.finish(-1);
146 if (request == Continue || request == Detach) {
150 SYSCALL_ERROR(IoError);
151 return result.finish(-1);
153 return result.finish(statusResult(relation->resume(
static_cast<int>(data), request == Detach)));
155 if (request == GetSignalInfo) {
157 if (statusResult(relation->snapshotSignalInfo(info)))
158 return result.finish(-1);
161 SYSCALL_ERROR(BadAddress);
162 return result.finish(-1);
164 return result.finish(0);
168 if (statusResult(relation->snapshotRegisters(registers)))
169 return result.finish(-1);
171 if (request == GetRegisters)
172 return result.finish(copyRegisters(registers, data,
sizeof(registers)));
176 SYSCALL_ERROR(BadAddress);
177 return result.finish(-1);
179 if (
static_cast<uint32_t
>(address) != GeneralRegisters || vector.length %
sizeof(uint64_t)) {
180 SYSCALL_ERROR(InvalidArgument);
181 return result.finish(-1);
183 if (vector.length >
sizeof(registers))
184 vector.length =
sizeof(registers);
185 if (copyRegisters(registers, vector.base, vector.length))
186 return result.finish(-1);
190 &vector.length,
sizeof(vector.length))) {
191 SYSCALL_ERROR(BadAddress);
192 return result.finish(-1);
194 return result.finish(0);
static bool copyFromUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static bool copyToUser(void *destination, const void *source, size_t count, size_t elementSize=1)