1
- //
2
- // Copyright (c) 2014-present, Saleem Abdulrasool <compnerd@compnerd.org>
3
- // All rights reserved.
4
- //
5
- // This source code is licensed under the University of Illinois/NCSA Open
6
- // Source License found in the LICENSE file in the root directory of this
7
- // source tree. An additional grant of patent rights can be found in the
8
- // PATENTS file in the same directory.
9
- //
1
+ // Copyright 2024-2025 Saleem Abdulrasool <compnerd@compnerd.org>
10
2
11
3
#include " DebugServer2/Target/Process.h"
12
4
5
+ #include < cmath>
6
+
7
+ #include < stddef.h>
8
+ #include < sys/mman.h>
9
+ #include < sys/syscall.h>
10
+
11
+ namespace {
12
+ template <typename T>
13
+ inline void InsertBytes (ds2::ByteVector &bytes, T value) {
14
+ uint8_t *data = reinterpret_cast <uint8_t *>(&value);
15
+ bytes.insert (std::end (bytes), data, data + sizeof (T));
16
+ }
17
+
18
+ namespace syscalls {
19
+ inline void mmap (size_t size, int protection, ds2::ByteVector &code) {
20
+ DS2ASSERT (std::log2 (MAP_ANON | MAP_PRIVATE) <= 16 );
21
+ DS2ASSERT (std::log2 (SYS_mmap) <= 16 );
22
+ DS2ASSERT (std::log2 (protection) <= 16 );
23
+
24
+ for (uint32_t instruction: {
25
+ static_cast <uint32_t >(0xd2800000 ), // mov x0, 0
26
+ static_cast <uint32_t >(0x580000e1 ), // ldr x1, .Lsize
27
+ static_cast <uint32_t >(0xd2800002 | protection << 5 ), // mov x2, protection
28
+ static_cast <uint32_t >(0xd2800003 | (MAP_ANON | MAP_PRIVATE) << 5 ), // mov x3, MAP_ANON | MAP_PRIVATE
29
+ static_cast <uint32_t >(0x92800004 ), // mov x4, -1
30
+ static_cast <uint32_t >(0xd2800005 ), // mov x5, 0
31
+ static_cast <uint32_t >(0xd2800008 | SYS_mmap << 5 ), // mov x8, =SYS_mmap
32
+ static_cast <uint32_t >(0xd4000001 ), // svc 0
33
+ static_cast <uint32_t >(0xd43e0000 ), // brk #0xf000
34
+ // .Lsize:
35
+ // .quad size
36
+ })
37
+ InsertBytes (code, instruction);
38
+ InsertBytes (code, size);
39
+ }
40
+
41
+ inline void munmap (uintptr_t address, size_t size, ds2::ByteVector &code) {
42
+ DS2ASSERT (std::log2 (SYS_munmap) <= 16 );
43
+
44
+ for (uint32_t instruction: {
45
+ static_cast <uint32_t >(0x580000a0 ), // ldr x0, .Laddress
46
+ static_cast <uint32_t >(0x580000c1 ), // ldr x1, .Lsize
47
+ static_cast <uint32_t >(0xd2800008 | SYS_munmap << 5 ), // mov x8, =SYS_munmap
48
+ static_cast <uint32_t >(0xd4000001 ), // svc 0
49
+ static_cast <uint32_t >(0xd43e0000 ), // brk #0xf000
50
+ // .Laddress:
51
+ // .quad address
52
+ // .Lsize:
53
+ // .quad size
54
+ })
55
+ InsertBytes (code, instruction);
56
+ InsertBytes (code, address);
57
+ InsertBytes (code, size);
58
+ }
59
+ }
60
+ }
61
+
13
62
namespace ds2 {
14
63
namespace Target {
15
64
namespace Darwin {
@@ -18,12 +67,43 @@ ErrorCode Process::allocateMemory(size_t size, uint32_t protection,
18
67
if (address == nullptr || size == 0 )
19
68
return kErrorInvalidArgument ;
20
69
21
- *address = 0 ;
22
- return kErrorUnsupported ;
70
+ ProcessInfo info;
71
+ ErrorCode error = getInfo (info);
72
+ if (error != kSuccess )
73
+ return error;
74
+
75
+ ByteVector code;
76
+ syscalls::mmap (size, convertMemoryProtectionFromPOSIX (protection), code);
77
+
78
+ error = ptrace ().execute (_pid, info, &code[0 ], code.size (), *address);
79
+ if (error != kSuccess )
80
+ return error;
81
+
82
+ if (*address == reinterpret_cast <uint64_t >(MAP_FAILED))
83
+ return kErrorNoMemory ;
84
+ return kSuccess ;
23
85
}
24
86
25
87
ErrorCode Process::deallocateMemory (uint64_t address, size_t size) {
26
- return kErrorUnsupported ;
88
+ if (size == 0 )
89
+ return kErrorInvalidArgument ;
90
+
91
+ ProcessInfo info;
92
+ ErrorCode error = getInfo (info);
93
+ if (error != kSuccess )
94
+ return error;
95
+
96
+ ByteVector code;
97
+ syscalls::munmap (address, size, code);
98
+
99
+ uint64_t result = 0 ;
100
+ error = ptrace ().execute (_pid, info, &code[0 ], code.size (), result);
101
+ if (error != kSuccess )
102
+ return error;
103
+
104
+ if (static_cast <int64_t >(result) < 0 )
105
+ return kErrorInvalidArgument ;
106
+ return kSuccess ;
27
107
}
28
108
}
29
109
}
0 commit comments