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>
102
113#include " DebugServer2/Target/Process.h"
124
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+
1362namespace ds2 {
1463namespace Target {
1564namespace Darwin {
@@ -18,12 +67,43 @@ ErrorCode Process::allocateMemory(size_t size, uint32_t protection,
1867 if (address == nullptr || size == 0 )
1968 return kErrorInvalidArgument ;
2069
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 ;
2385}
2486
2587ErrorCode 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 ;
27107}
28108}
29109}
0 commit comments