libclues
Linux C++ Tracing Library
Loading...
Searching...
No Matches
clues::CloneSystemCall Struct Reference

Wrapper for the clone() and clone2() system calls. More...

#include <process.hxx>

+ Inheritance diagram for clues::CloneSystemCall:

Public Attributes

item::CloneFlagsValue flags
 
item::GenericPointerValue stack
 
std::optional< item::PointerToScalar< cosmos::ProcessID > > parent_tid
 TID of the new child written out to a pid_t* in the parent.
 
std::optional< item::PointerToScalar< cosmos::FileNum > > pidfd
 PID file descriptor referring to the new child.
 
std::optional< item::GenericPointerValuechild_tid
 TID of the new child written out to a pid_* in the child.
 
std::optional< item::GenericPointerValuetls
 Thread-local-storage data for the new child.
 
item::ProcessIDItem new_pid
 The new child's PID.
 

Protected Member Functions

bool check2ndPass (const Tracee &) override
 Check whether a second pass needs to be made processing parameters.
 
void prepareNewSystemCall () override
 Perform any necessary actions before processing a new system call entry event.
 
- Protected Member Functions inherited from clues::SystemCall
void fillParameters (const Tracee &proc, const SystemCallInfo &info)
 
void setReturnItem (SystemCallItem &ret)
 Sets the return value system call item.
 
void addParameters ()
 
template<typename T, typename... Targs>
void addParameters (T &par, Targs &...rest)
 
template<typename... Targs>
void setParameters (Targs &...args)
 
virtual void updateFDTracking (const Tracee &proc)
 Update file descriptor tracking.
 
void dropFD (const Tracee &proc, const cosmos::FileNum num)
 
void trackFD (const Tracee &proc, FDInfo &&info)
 

Additional Inherited Members

- Public Types inherited from clues::SystemCall
using ParameterVector = std::vector<SystemCallItemPtr>
 Vector of the parameters required for a system call.
 
- Public Member Functions inherited from clues::SystemCall
 SystemCall (const SystemCallNr nr)
 Instantiates a new SystemCall object with given properties.
 
 SystemCall (const SystemCall &other)=delete
 
SystemCalloperator= (const SystemCall &other)=delete
 
void setEntryInfo (const Tracee &proc, const SystemCallInfo &info)
 Update the stored parameter values from the given tracee.
 
void setExitInfo (const Tracee &proc, const SystemCallInfo &info)
 Update possible out and return parameter values from the given tracee.
 
std::string_view name () const
 Returns the system call's human readable name.
 
size_t numPars () const
 Returns the number of parameters for this system call.
 
SystemCallNr callNr () const
 Returns the system call table number for this system call.
 
const ParameterVectorparameters () const
 Access to the parameters associated with this system call.
 
SystemCallItemPtr result () const
 Access to the return value parameter associated with this system call.
 
std::optional< ErrnoResulterror () const
 Access to the errno result seen for this system call.
 
bool hasOutParameter () const
 
bool hasResultValue () const
 
bool hasErrorCode () const
 
ABI abi () const
 Returns the system call ABi seen during system call entry.
 
bool is32BitEmulationABI () const
 
const SystemCallInfocurrentInfo () const
 Access the current SystemCallInfo if currently processing syscall entry/exit.
 
- Static Public Member Functions inherited from clues::SystemCall
static const char * name (const SystemCallNr nr)
 Returns the name of the given system call or "<unknown>" if unknown.
 
static bool validNr (const SystemCallNr nr)
 Returns whether the given system call number is in a valid range.
 
- Protected Attributes inherited from clues::SystemCall
SystemCallNr m_nr
 The raw system call number of the system call.
 
const std::string_view m_name
 The basic name of the system call.
 
const SystemCallInfom_info = nullptr
 Current system call info during entry/exit processing, nullptr otherwise.
 
SystemCallItemPtr m_return
 The return value of the system call.
 
std::optional< ErrnoResultm_error
 If the system call fails, this is the error code.
 
ParameterVector m_pars
 The array of system call parameters, if any.
 
ABI m_abi = ABI::UNKNOWN
 The current system call ABI which is in effect.
 

Detailed Description

Wrapper for the clone() and clone2() system calls.

For clone3() a separate wrapper type is used, since the two variants of clone system calls differ too much from each other.

Definition at line 61 of file process.hxx.

Constructor & Destructor Documentation

◆ CloneSystemCall()

clues::CloneSystemCall::CloneSystemCall ( )
inline

Definition at line 64 of file process.hxx.

64 :
65 SystemCall{SystemCallNr::CLONE},
66 stack{"stack", "stack address"},
67 new_pid{ItemType::RETVAL, "child pid"} {
69 setParameters(flags, stack);
70 }
void setReturnItem(SystemCallItem &ret)
Sets the return value system call item.
SystemCall(const SystemCallNr nr)
Instantiates a new SystemCall object with given properties.
@ RETVAL
A system call return value.
item::ProcessIDItem new_pid
The new child's PID.
Definition process.hxx:112

Member Function Documentation

◆ check2ndPass()

bool clues::CloneSystemCall::check2ndPass ( const Tracee & )
overrideprotectedvirtual

Check whether a second pass needs to be made processing parameters.

This function can be overridden by the actual system call implementation to perform context-sensitive evaluation of system call parameters (e.g. for ioctl() style system calls) upon system call entry.

The implementation of this function is allowed to modify the amount and types of system call parameters and return parameter. In this case true must be returned to let the base class implementation reevaluate all system call parameters.

Reimplemented from clues::SystemCall.

Definition at line 64 of file process.cxx.

64 {
65 // we need these two sizes to match, since a `pid_t*` is used in
66 // clone() to store either the child pid or a pidfd at.
67 static_assert( sizeof(int) == sizeof(pid_t), "sizeof(int) != sizeof(pid_t)" );
68 using enum cosmos::CloneFlag;
69 const auto clone_flags = this->flags.flags();
70
71 auto maybe_add_unused_par = [this](const size_t need_index) {
72 while (need_index > m_pars.size()) {
73 addParameters(item::unused);
74 }
75 };
76
77 auto maybe_add_settid_par = [this, clone_flags, maybe_add_unused_par](const size_t pos) {
78 if (clone_flags[CHILD_SETTID]) {
79 child_tid.emplace(item::GenericPointerValue{"child_tid", "pointer to child TID in child's memory"});
80 maybe_add_unused_par(pos);
81 addParameters(*child_tid);
82 }
83 };
84
85 auto maybe_add_settls_par = [this, clone_flags, maybe_add_unused_par](const size_t pos) {
86 if (clone_flags[SETTLS]) {
87 tls.emplace(item::GenericPointerValue{"tls", "ABI-specific thread-local-storage data"});
88
89 maybe_add_unused_par(pos);
90 addParameters(*tls);
91 }
92 };
93
94 // these two are mutual-exclusive in the old clone() system call
95 if (clone_flags[PARENT_SETTID]) {
96 parent_tid.emplace(item::PointerToScalar<cosmos::ProcessID>{
97 "parent_tid", "pointer to child TID in parent's memory"});
98 addParameters(*parent_tid);
99 } else if (clone_flags[PIDFD]) {
100 pidfd.emplace(item::PointerToScalar<cosmos::FileNum>{
101 "pidfd", "pointer to pidfd in parent's memory (alternative use of parent_tid)"});
102 addParameters(*pidfd);
103 }
104
105 /*
106 * Things are messy with clone(), the order of parameters differs
107 * between ABIs and we might need to skip some parameters by adding
108 * item::unused.
109 *
110 * The man page is a bit sketchy on the ABI details. In the kernel
111 * source we have to look for `CONFIG_CLONE_BACKWARDS*`, define in
112 * "arch/.../KConfig" as CLONE_BACKWARDS*.
113 *
114 * The situation for the ABIs we support is as follows:
115 *
116 * X86_32 (I386), ARM, ARM64: CLONE_BACKWARDS
117 * X86_64 (seems to include X32): no define
118 *
119 * CLONE_BACKWARDS means the final two arguments are tls /
120 * child_tidptr.
121 *
122 * no define means the final two arguments are child_tidptr / tls.
123 */
124
125 if (const auto abi = this->abi(); abi == ABI::X86_64 || abi == ABI::X32) {
126 maybe_add_settid_par(3);
127 maybe_add_settls_par(4);
128 } else if (abi == ABI::AARCH64 || abi == ABI::I386) {
129 maybe_add_settls_par(3);
130 maybe_add_settid_par(4);
131 }
132
133 return m_pars.size() > 2;
134}
ABI abi() const
Returns the system call ABi seen during system call entry.
ParameterVector m_pars
The array of system call parameters, if any.
@ X32
X86_64 with 32-bit pointers.
Definition types.hxx:66
std::optional< item::GenericPointerValue > tls
Thread-local-storage data for the new child.
Definition process.hxx:107
std::optional< item::PointerToScalar< cosmos::FileNum > > pidfd
PID file descriptor referring to the new child.
Definition process.hxx:89
std::optional< item::GenericPointerValue > child_tid
TID of the new child written out to a pid_* in the child.
Definition process.hxx:99
std::optional< item::PointerToScalar< cosmos::ProcessID > > parent_tid
TID of the new child written out to a pid_t* in the parent.
Definition process.hxx:84

◆ prepareNewSystemCall()

void clues::CloneSystemCall::prepareNewSystemCall ( )
overrideprotectedvirtual

Perform any necessary actions before processing a new system call entry event.

Reimplemented from clues::SystemCall.

Definition at line 53 of file process.cxx.

53 {
54 /* drop all but the fixed initial two parameters */
55 m_pars.erase(m_pars.begin() + 2, m_pars.end());
56
57 /* args */
58 parent_tid.reset();
59 pidfd.reset();
60 child_tid.reset();
61 tls.reset();
62}

Member Data Documentation

◆ child_tid

std::optional<item::GenericPointerValue> clues::CloneSystemCall::child_tid

TID of the new child written out to a pid_* in the child.

This is only filled in if CLONE_CHILD_SETTID is set.

This is only placed into the child's memory, not to the parent's. Thus we have no reliable way of retrieving the value, which is why we're not using PointerToScalar here.

Definition at line 99 of file process.hxx.

◆ flags

item::CloneFlagsValue clues::CloneSystemCall::flags

Definition at line 73 of file process.hxx.

◆ new_pid

item::ProcessIDItem clues::CloneSystemCall::new_pid

The new child's PID.

Definition at line 112 of file process.hxx.

◆ parent_tid

std::optional<item::PointerToScalar<cosmos::ProcessID> > clues::CloneSystemCall::parent_tid

TID of the new child written out to a pid_t* in the parent.

This is only filled in if CLONE_PARENT_SETTID is set.

Definition at line 84 of file process.hxx.

◆ pidfd

std::optional<item::PointerToScalar<cosmos::FileNum> > clues::CloneSystemCall::pidfd

PID file descriptor referring to the new child.

This is only filled in if CLONE_PIDFD is set.

Definition at line 89 of file process.hxx.

◆ stack

item::GenericPointerValue clues::CloneSystemCall::stack

Definition at line 74 of file process.hxx.

◆ tls

std::optional<item::GenericPointerValue> clues::CloneSystemCall::tls

Thread-local-storage data for the new child.

This is only filled in if CLONE_SETTLS is set.

The interpretation is highly ABI-specific, which is why we currently model it generically as a pointer.

Definition at line 107 of file process.hxx.


The documentation for this struct was generated from the following files: