1#ifndef POSIX_SYSCALL_TRACE_H
2#define POSIX_SYSCALL_TRACE_H
4#include "pedigree/kernel/Log.h"
5#include "pedigree/kernel/process/Process.h"
6#include "pedigree/kernel/process/Thread.h"
7#include "pedigree/kernel/processor/state.h"
8#include "pedigree/kernel/time/Time.h"
10#include "PosixSubsystem.h"
11#include "syscalls/translate.h"
16 SyscallTrace(SyscallState& state,
Thread& thread) {
17 static uint64_t nextId = 0;
18 m_Id = __atomic_add_fetch(&nextId,
static_cast<uint64_t
>(1), __ATOMIC_RELAXED);
20 const bool linuxAbi = state.getSyscallService() == linuxCompat;
21 const uintptr_t number = state.getSyscallNumber();
22 const size_t base = linuxAbi ? 6 : 0;
23 uintptr_t arguments[6];
24 for (
size_t i = 0; i < 6; ++i) {
25 arguments[i] = state.getSyscallParameter(base + i);
29 <<
" tid=" << thread.
getId() <<
" abi=" << (linuxAbi ?
"L" :
"P")
31 for (
size_t i = 0; i < 6; i += 3) {
32 NOTICE(
"STRACE A id=" <<
Hex << m_Id <<
" n=" << i <<
" x=" << arguments[i]
33 <<
" y=" << arguments[i + 1] <<
" z=" << arguments[i + 2]);
37 const unsigned paths = pathArguments(number);
38 for (
size_t i = 0; i < 6; ++i) {
39 if (
paths & (1U << i)) {
40 path(i,
reinterpret_cast<const char*
>(arguments[i]));
46 void finish(uintptr_t result,
int error, Time::Timestamp elapsed)
const {
48 NOTICE(
"STRACE X id=" <<
Hex << m_Id <<
" raw=" << result
49 <<
" err=" <<
static_cast<unsigned>(error) <<
" ns=" << elapsed);
53 static unsigned pathArguments(uintptr_t number) {
55 case PedigreeLinuxAmd64Syscall_open:
56 case PedigreeLinuxAmd64Syscall_stat:
57 case PedigreeLinuxAmd64Syscall_lstat:
58 case PedigreeLinuxAmd64Syscall_access:
59 case PedigreeLinuxAmd64Syscall_execve:
60 case PedigreeLinuxAmd64Syscall_chdir:
61 case PedigreeLinuxAmd64Syscall_mkdir:
62 case PedigreeLinuxAmd64Syscall_rmdir:
63 case PedigreeLinuxAmd64Syscall_creat:
64 case PedigreeLinuxAmd64Syscall_unlink:
65 case PedigreeLinuxAmd64Syscall_readlink:
66 case PedigreeLinuxAmd64Syscall_chmod:
67 case PedigreeLinuxAmd64Syscall_chown:
68 case PedigreeLinuxAmd64Syscall_lchown:
69 case PedigreeLinuxAmd64Syscall_utime:
70 case PedigreeLinuxAmd64Syscall_utimes:
71 case PedigreeLinuxAmd64Syscall_statfs:
72 case PedigreeLinuxAmd64Syscall_chroot:
73 case PedigreeLinuxAmd64Syscall_truncate:
74 case PedigreeLinuxAmd64Syscall_mknod:
75 case PedigreeLinuxAmd64Syscall_umount2:
76 case PedigreeLinuxAmd64Syscall_swapon:
77 case PedigreeLinuxAmd64Syscall_swapoff:
78 case PedigreeLinuxAmd64Syscall_acct:
79 case PedigreeLinuxAmd64Syscall_setxattr:
80 case PedigreeLinuxAmd64Syscall_lsetxattr:
81 case PedigreeLinuxAmd64Syscall_getxattr:
82 case PedigreeLinuxAmd64Syscall_lgetxattr:
83 case PedigreeLinuxAmd64Syscall_listxattr:
84 case PedigreeLinuxAmd64Syscall_llistxattr:
85 case PedigreeLinuxAmd64Syscall_removexattr:
86 case PedigreeLinuxAmd64Syscall_lremovexattr:
88 case PedigreeLinuxAmd64Syscall_rename:
89 case PedigreeLinuxAmd64Syscall_link:
90 case PedigreeLinuxAmd64Syscall_symlink:
91 case PedigreeLinuxAmd64Syscall_pivot_root:
92 case PedigreeLinuxAmd64Syscall_mount:
93 return (1U << 0) | (1U << 1);
94 case PedigreeLinuxAmd64Syscall_openat:
95 case PedigreeLinuxAmd64Syscall_mkdirat:
96 case PedigreeLinuxAmd64Syscall_fchownat:
97 case PedigreeLinuxAmd64Syscall_futimesat:
98 case PedigreeLinuxAmd64Syscall_newfstatat:
99 case PedigreeLinuxAmd64Syscall_unlinkat:
100 case PedigreeLinuxAmd64Syscall_readlinkat:
101 case PedigreeLinuxAmd64Syscall_fchmodat:
102 case PedigreeLinuxAmd64Syscall_faccessat:
103 case PedigreeLinuxAmd64Syscall_faccessat2:
104 case PedigreeLinuxAmd64Syscall_execveat:
105 case PedigreeLinuxAmd64Syscall_utimensat:
106 case PedigreeLinuxAmd64Syscall_statx:
107 case PedigreeLinuxAmd64Syscall_fchmodat2:
108 case PedigreeLinuxAmd64Syscall_mknodat:
109 case PedigreeLinuxAmd64Syscall_name_to_handle_at:
110 case PedigreeLinuxAmd64Syscall_inotify_add_watch:
112 case PedigreeLinuxAmd64Syscall_renameat:
113 case PedigreeLinuxAmd64Syscall_linkat:
114 case PedigreeLinuxAmd64Syscall_renameat2:
115 return (1U << 1) | (1U << 3);
116 case PedigreeLinuxAmd64Syscall_symlinkat:
117 return (1U << 0) | (1U << 2);
123 void path(
size_t argument,
const char* address)
const {
126 const char* status = result == PosixSubsystem::UserStringSuccess ?
"ok"
127 : result == PosixSubsystem::UserStringTooLong ?
"truncated"
129 constexpr char digits[] =
"0123456789abcdef";
131 for (
size_t offset = 0; offset < copy.length(); offset += 32) {
132 const size_t remaining = copy.length() - offset;
133 const size_t count = remaining < 32 ? remaining : 32;
135 for (
size_t i = 0; i < count; ++i) {
136 const uint8_t
byte =
static_cast<uint8_t
>(copy[offset + i]);
137 data[i * 2] = digits[
byte >> 4];
138 data[i * 2 + 1] = digits[
byte & 15];
140 data[count * 2] =
'\0';
141 NOTICE(
"STRACE P id=" <<
Hex << m_Id <<
" arg=" << argument <<
" off=" << offset
142 <<
" data=" << data);
144 NOTICE(
"STRACE S id=" <<
Hex << m_Id <<
" arg=" << argument <<
" status=" << status);
static UserStringResult copyUserString(const char *userString, String ©, size_t maxLength)
Process * getParent() const