Skip to content

Target: implement the Darwin ARM64 support to complete the port #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,12 @@ jobs:
${{ github.workspace }}/BinaryCache/ds2/ds2.exe

macos:
# The macos-latest runner image runs on an M1 ARM CPU which is not currently
# supported by ds2. Build on macos-13, which is x86_64-based, until Darwin
# on ARM support is implemented.
runs-on: macos-13
runs-on: macos-latest

strategy:
fail-fast: false
matrix:
processor: [ arm64, x86_64 ]

steps:
- uses: actions/checkout@v4
Expand All @@ -157,14 +159,15 @@ jobs:
cmake -B ${{ github.workspace }}/BinaryCache/ds2 \
-C ${{ github.workspace }}/cmake/caches/ClangWarnings.cmake \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_SYSTEM_PROCESSOR="${{ matrix.processor }}" \
-G Ninja \
-S ${{ github.workspace }}
- name: Build
run: cmake --build ${{ github.workspace }}/BinaryCache/ds2 --config Release

- uses: actions/upload-artifact@v4
with:
name: macOS-x86_64-ds2
name: macOS-${{ matrix.processor }}-ds2
path: |
${{ github.workspace }}/BinaryCache/ds2/ds2

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ if(DS2_ARCHITECTURE MATCHES "ARM|ARM64")
set_source_files_properties(
Sources/Architecture/ARM/ThumbBranchInfo.cpp
PROPERTIES
COMPILE_OPTIONS $<$<CXX_COMPILER_ID:Clang>:-Wno-error=comma>)
COMPILE_OPTIONS $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-error=comma>)

target_sources(ds2 PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/Headers/DebugServer2/Architecture/ARM/RegistersDescriptors.h
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ platforms at various times.

- [x] ARM64
- [x] Android
- [ ] Darwin
- [x] Darwin
- [x] Linux
- [x] MinGW
- [ ] Windows
Expand Down
104 changes: 92 additions & 12 deletions Sources/Target/Darwin/ARM64/ProcessARM64.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,64 @@
//
// Copyright (c) 2014-present, Saleem Abdulrasool <[email protected]>
// All rights reserved.
//
// This source code is licensed under the University of Illinois/NCSA Open
// Source License found in the LICENSE file in the root directory of this
// source tree. An additional grant of patent rights can be found in the
// PATENTS file in the same directory.
//
// Copyright 2024-2025 Saleem Abdulrasool <[email protected]>

#include "DebugServer2/Target/Process.h"

#include <cmath>

#include <stddef.h>
#include <sys/mman.h>
#include <sys/syscall.h>

namespace {
template <typename T>
inline void InsertBytes(ds2::ByteVector &bytes, T value) {
uint8_t *data = reinterpret_cast<uint8_t *>(&value);
bytes.insert(std::end(bytes), data, data + sizeof(T));
}

namespace syscalls {
inline void mmap(size_t size, int protection, ds2::ByteVector &code) {
DS2ASSERT(std::log2(MAP_ANON | MAP_PRIVATE) <= 16);
DS2ASSERT(std::log2(SYS_mmap) <= 16);
DS2ASSERT(std::log2(protection) <= 16);

for (uint32_t instruction: {
static_cast<uint32_t>(0xd2800000), // mov x0, 0
static_cast<uint32_t>(0x580000e1), // ldr x1, .Lsize
static_cast<uint32_t>(0xd2800002 | protection << 5), // mov x2, protection
static_cast<uint32_t>(0xd2800003 | (MAP_ANON | MAP_PRIVATE) << 5), // mov x3, MAP_ANON | MAP_PRIVATE
static_cast<uint32_t>(0x92800004), // mov x4, -1
static_cast<uint32_t>(0xd2800005), // mov x5, 0
static_cast<uint32_t>(0xd2800008 | SYS_mmap << 5), // mov x8, =SYS_mmap
static_cast<uint32_t>(0xd4000001), // svc 0
static_cast<uint32_t>(0xd43e0000), // brk #0xf000
// .Lsize:
// .quad size
})
InsertBytes(code, instruction);
InsertBytes(code, size);
}

inline void munmap(uintptr_t address, size_t size, ds2::ByteVector &code) {
DS2ASSERT(std::log2(SYS_munmap) <= 16);

for (uint32_t instruction: {
static_cast<uint32_t>(0x580000a0), // ldr x0, .Laddress
static_cast<uint32_t>(0x580000c1), // ldr x1, .Lsize
static_cast<uint32_t>(0xd2800008 | SYS_munmap << 5), // mov x8, =SYS_munmap
static_cast<uint32_t>(0xd4000001), // svc 0
static_cast<uint32_t>(0xd43e0000), // brk #0xf000
// .Laddress:
// .quad address
// .Lsize:
// .quad size
})
InsertBytes(code, instruction);
InsertBytes(code, address);
InsertBytes(code, size);
}
}
}

namespace ds2 {
namespace Target {
namespace Darwin {
Expand All @@ -18,12 +67,43 @@ ErrorCode Process::allocateMemory(size_t size, uint32_t protection,
if (address == nullptr || size == 0)
return kErrorInvalidArgument;

*address = 0;
return kErrorUnsupported;
ProcessInfo info;
ErrorCode error = getInfo(info);
if (error != kSuccess)
return error;

ByteVector code;
syscalls::mmap(size, convertMemoryProtectionFromPOSIX(protection), code);

error = ptrace().execute(_pid, info, &code[0], code.size(), *address);
if (error != kSuccess)
return error;

if (*address == reinterpret_cast<uint64_t>(MAP_FAILED))
return kErrorNoMemory;
return kSuccess;
}

ErrorCode Process::deallocateMemory(uint64_t address, size_t size) {
return kErrorUnsupported;
if (size == 0)
return kErrorInvalidArgument;

ProcessInfo info;
ErrorCode error = getInfo(info);
if (error != kSuccess)
return error;

ByteVector code;
syscalls::munmap(address, size, code);

uint64_t result = 0;
error = ptrace().execute(_pid, info, &code[0], code.size(), result);
if (error != kSuccess)
return error;

if (static_cast<int64_t>(result) < 0)
return kErrorInvalidArgument;
return kSuccess;
}
}
}
Expand Down
Loading