PtraceX64   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 102
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
B ptrace() 0 32 7
A __construct() 0 63 1
1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpProfiler\Lib\Libc\Sys\Ptrace;
15
16
use FFI\CData;
17
use FFI\CInteger;
18
use PhpProfiler\Lib\FFI\CannotAllocateBufferException;
19
use PhpProfiler\Lib\FFI\CannotCastCDataException;
20
use PhpProfiler\Lib\Libc\Addressable;
21
22
class PtraceX64 implements Ptrace
23
{
24
    /** @var \FFI\Libc\ptrace_ffi */
25
    private \FFI $ffi;
26
27
    public function __construct()
28
    {
29
        /** @var \FFI\Libc\ptrace_ffi ffi */
30
        $this->ffi = \FFI::cdef('
31
           struct user_regs_struct {
32
               unsigned long r15;
33
               unsigned long r14;
34
               unsigned long r13;
35
               unsigned long r12;
36
               unsigned long bp;
37
               unsigned long bx;
38
               unsigned long r11;
39
               unsigned long r10;
40
               unsigned long r9;
41
               unsigned long r8;
42
               unsigned long ax;
43
               unsigned long cx;
44
               unsigned long dx;
45
               unsigned long si;
46
               unsigned long di;
47
               unsigned long orig_ax;
48
               unsigned long ip;
49
               unsigned long cs;
50
               unsigned long flags;
51
               unsigned long sp;
52
               unsigned long ss;
53
               unsigned long fs_base;
54
               unsigned long gs_base;
55
               unsigned long ds;
56
               unsigned long es;
57
               unsigned long fs;
58
               unsigned long gs;
59
           };
60
           typedef int pid_t;
61
           enum __ptrace_request
62
           {
63
               PTRACE_TRACEME = 0,
64
               PTRACE_PEEKTEXT = 1,
65
               PTRACE_PEEKDATA = 2,
66
               PTRACE_PEEKUSER = 3,
67
               PTRACE_POKETEXT = 4,
68
               PTRACE_POKEDATA = 5,
69
               PTRACE_POKEUSER = 6,
70
               PTRACE_CONT = 7,
71
               PTRACE_KILL = 8,
72
               PTRACE_SINGLESTEP = 9,
73
               PTRACE_GETREGS = 12,
74
               PTRACE_SETREGS = 13,
75
               PTRACE_GETFPREGS = 14,
76
               PTRACE_SETFPREGS = 15,
77
               PTRACE_ATTACH = 16,
78
               PTRACE_DETACH = 17,
79
               PTRACE_GETFPXREGS = 18,
80
               PTRACE_SETFPXREGS = 19,
81
               PTRACE_SYSCALL = 24,
82
               PTRACE_SETOPTIONS = 0x4200,
83
               PTRACE_GETEVENTMSG = 0x4201,
84
               PTRACE_GETSIGINFO = 0x4202,
85
               PTRACE_SETSIGINFO = 0x4203
86
           };
87
           long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
88
           int errno;
89
       ', 'libc.so.6');
90
    }
91
92
    public function ptrace(
93
        PtraceRequest $request,
94
        int $pid,
95
        Addressable|CData|null|int $addr,
96
        Addressable|CData|null|int $data,
97
    ): int {
98
        if (is_null($addr) or is_int($addr)) {
99
            /** @var CInteger */
100
            $addr_holder = \FFI::new('long')
101
                ?? throw new CannotAllocateBufferException('cannot allocate buffer');
102
            $addr_holder->cdata = (int)$addr;
103
            $addr = \FFI::cast('void *', $addr_holder)
104
                ?? throw new CannotCastCDataException('cannot cast buffer');
105
        }
106
        if (is_null($data) or is_int($data)) {
107
            /** @var CInteger */
108
            $data_holder = \FFI::new('long')
109
                ?? throw new CannotAllocateBufferException('cannot allocate buffer');
110
            $data_holder->cdata = (int)$data;
111
            $data = \FFI::cast('void *', $data_holder)
112
                ?? throw new CannotCastCDataException('cannot cast buffer');
113
        }
114
115
        $addr_pointer = $addr instanceof Addressable ? $addr->toVoidPointer() : $addr;
116
        $data_pointer = $data instanceof Addressable ? $data->toVoidPointer() : $data;
117
118
        /** @var int */
119
        return $this->ffi->ptrace(
0 ignored issues
show
Bug introduced by
The method ptrace() does not exist on FFI. It seems like you code against a sub-type of FFI such as FFI\Libc\ptrace_ffi. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
        return $this->ffi->/** @scrutinizer ignore-call */ ptrace(
Loading history...
120
            $request->getValue(),
121
            $pid,
122
            $addr_pointer,
123
            $data_pointer,
124
        );
125
    }
126
}
127