Skip to content

Haiku: Initial CoreCLR support #109580

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

Merged
merged 2 commits into from
Dec 6, 2024
Merged
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
2 changes: 2 additions & 0 deletions eng/native/tryrun.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ if(DARWIN)
set_cache_value(HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE 1)
set_cache_value(HAVE_CLOCK_MONOTONIC_EXITCODE 0)
set_cache_value(HAVE_CLOCK_REALTIME_EXITCODE 0)
set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0)
set_cache_value(HAVE_CLOCK_GETTIME_NSEC_NP_EXITCODE 0)
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 1)
set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 1)
Expand All @@ -79,6 +80,7 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|riscv64|s39
set_cache_value(HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE 0)
set_cache_value(HAVE_CLOCK_MONOTONIC_EXITCODE 0)
set_cache_value(HAVE_CLOCK_REALTIME_EXITCODE 0)
set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0)
set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 0)
set_cache_value(HAVE_PROCFS_CTL_EXITCODE 1)
set_cache_value(HAVE_PROCFS_STAT_EXITCODE 0)
Expand Down
1 change: 1 addition & 0 deletions eng/native/tryrun_ios_tvos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 1)
set_cache_value(HAVE_BROKEN_FIFO_KEVENT_EXITCODE 1)
set_cache_value(HAVE_BROKEN_FIFO_SELECT_EXITCODE 1)
set_cache_value(HAVE_CLOCK_REALTIME_EXITCODE 0)
set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0)
set_cache_value(HAVE_CLOCK_GETTIME_NSEC_NP_EXITCODE 0)
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 1)
set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 1)
Expand Down
16 changes: 14 additions & 2 deletions src/coreclr/debug/dbgutil/elfreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@
#include <inttypes.h>
#include "elfreader.h"

#ifndef Elf_Ehdr
#define Elf_Ehdr ElfW(Ehdr)
#endif
#ifndef Elf_Phdr
#define Elf_Phdr ElfW(Phdr)
#endif
#ifndef Elf_Shdr
#define Elf_Shdr ElfW(Shdr)
#endif
#ifndef Elf_Nhdr
#define Elf_Nhdr ElfW(Nhdr)
#endif
#ifndef Elf_Dyn
#define Elf_Dyn ElfW(Dyn)
#endif
#ifndef Elf_Sym
#define Elf_Sym ElfW(Sym)
#endif

#if TARGET_64BIT
#define PRIx PRIx64
Expand Down Expand Up @@ -314,7 +326,7 @@ ElfReader::GetStringAtIndex(int index, std::string& result)
return true;
}

#ifdef HOST_UNIX
#if defined(HOST_UNIX) && !defined(TARGET_HAIKU)

//
// Enumerate all the ELF info starting from the root program header. This
Expand Down Expand Up @@ -414,7 +426,7 @@ ElfReader::EnumerateLinkMapEntries(Elf_Dyn* dynamicAddr)
return true;
}

#endif // HOST_UNIX
#endif // defined(HOST_UNIX) && !defined(TARGET_HAIKU)

bool
ElfReader::EnumerateProgramHeaders(uint64_t baseAddress, uint64_t* ploadbias, Elf_Dyn** pdynamicAddr)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/dbgutil/elfreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class ElfReader
void* m_symbolTableAddr; // DT_SYMTAB

GnuHashTable m_hashTable; // gnu hash table info
int32_t* m_buckets; // gnu hash table buckets
int32_t* m_buckets; // gnu hash table buckets
void* m_chainsAddress;

public:
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/gc/unix/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Module Name:
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#else
#elif !defined(__HAIKU__)
#include <sys/vfs.h>
#endif
#include <errno.h>
Expand Down Expand Up @@ -55,7 +55,7 @@ Module Name:

extern bool ReadMemoryValueFromFile(const char* filename, uint64_t* val);

namespace
namespace
{
class CGroup
{
Expand Down
26 changes: 22 additions & 4 deletions src/coreclr/gc/unix/gcenv.unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ extern "C"

#endif // __APPLE__

#ifdef __HAIKU__
#include <OS.h>
#endif // __HAIKU__

#ifdef __linux__
#include <sys/syscall.h> // __NR_membarrier
// Ensure __NR_membarrier is defined for portable builds.
Expand Down Expand Up @@ -572,7 +576,11 @@ static void* VirtualReserveInner(size_t size, size_t alignment, uint32_t flags,
}

size_t alignedSize = size + (alignment - OS_PAGE_SIZE);
void * pRetVal = mmap(nullptr, alignedSize, PROT_NONE, MAP_ANON | MAP_PRIVATE | hugePagesFlag, -1, 0);
int mmapFlags = MAP_ANON | MAP_PRIVATE | hugePagesFlag;
#ifdef __HAIKU__
mmapFlags |= MAP_NORESERVE;
#endif
void * pRetVal = mmap(nullptr, alignedSize, PROT_NONE, mmapFlags, -1, 0);

if (pRetVal != MAP_FAILED)
{
Expand Down Expand Up @@ -721,7 +729,11 @@ bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
// that much more clear to the operating system that we no
// longer need these pages. Also, GC depends on re-committed pages to
// be zeroed-out.
bool bRetVal = mmap(address, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) != MAP_FAILED;
int mmapFlags = MAP_FIXED | MAP_ANON | MAP_PRIVATE;
#ifdef TARGET_HAIKU
mmapFlags |= MAP_NORESERVE;
#endif
bool bRetVal = mmap(address, size, PROT_NONE, mmapFlags, -1, 0) != MAP_FAILED;

#ifdef MADV_DONTDUMP
if (bRetVal)
Expand Down Expand Up @@ -1022,7 +1034,7 @@ static uint64_t GetMemorySizeMultiplier(char units)
return 1;
}

#ifndef __APPLE__
#if !defined(__APPLE__) && !defined(__HAIKU__)
// Try to read the MemAvailable entry from /proc/meminfo.
// Return true if the /proc/meminfo existed, the entry was present and we were able to parse it.
static bool ReadMemAvailable(uint64_t* memAvailable)
Expand Down Expand Up @@ -1055,7 +1067,7 @@ static bool ReadMemAvailable(uint64_t* memAvailable)

return foundMemAvailable;
}
#endif // __APPLE__
#endif // !defined(__APPLE__) && !defined(__HAIKU__)

// Get size of the largest cache on the processor die
// Parameters:
Expand Down Expand Up @@ -1284,6 +1296,12 @@ uint64_t GetAvailablePhysicalMemory()
sysctlbyname("vm.stats.vm.v_free_count", &free_count, &sz, NULL, 0);

available = (inactive_count + laundry_count + free_count) * sysconf(_SC_PAGESIZE);
#elif defined(__HAIKU__)
system_info info;
if (get_system_info(&info) == B_OK)
{
available = info.free_memory;
}
#else // Linux
static volatile bool tryReadMemInfo = true;

Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/gc/unix/numasupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
#include <dirent.h>
#include <string.h>
#include <limits.h>
#include <sys/syscall.h>
#include <minipal/utils.h>

#ifdef TARGET_LINUX
#include <sys/syscall.h>
#endif

// The highest NUMA node available
int g_highestNumaNode = 0;
// Is numa available
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/inc/crosscomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
#define DAC_CS_NATIVE_DATA_SIZE 56
#elif defined(__sun) && defined(TARGET_AMD64)
#define DAC_CS_NATIVE_DATA_SIZE 48
#elif defined(TARGET_HAIKU) && defined(TARGET_AMD64)
#define DAC_CS_NATIVE_DATA_SIZE 56
#else
#warning
#error DAC_CS_NATIVE_DATA_SIZE is not defined for this architecture. This should be same value as PAL_CS_NATIVE_DATA_SIZE (aka sizeof(PAL_CS_NATIVE_DATA)).
Expand Down
33 changes: 22 additions & 11 deletions src/coreclr/minipal/Unix/doublemapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,22 @@ bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecu

#ifdef TARGET_FREEBSD
int fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, S_IRWXU);
#elif defined(TARGET_SUNOS) // has POSIX implementation
char name[24];
sprintf(name, "/shm-dotnet-%d", getpid());
name[sizeof(name) - 1] = '\0';
shm_unlink(name);
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
#else // TARGET_FREEBSD
#elif defined(TARGET_LINUX)
int fd = memfd_create("doublemapper", MFD_CLOEXEC);
#endif // TARGET_FREEBSD
#else
int fd = -1;
#endif

// POSIX fallback
if (fd == -1)
{
char name[24];
sprintf(name, "/shm-dotnet-%d", getpid());
name[sizeof(name) - 1] = '\0';
shm_unlink(name);
fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
shm_unlink(name);
}

if (fd == -1)
{
Expand Down Expand Up @@ -135,10 +142,14 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs

void* result = PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(rangeStart, rangeEnd, size, 0 /* fStoreAllocationInfo */);
#ifndef TARGET_OSX
int mmapFlags = MAP_SHARED;
#ifdef TARGET_HAIKU
mmapFlags |= MAP_NORESERVE;
#endif // TARGET_HAIKU
if (result != NULL)
{
// Map the shared memory over the range reserved from the executable memory allocator.
result = mmap(result, size, PROT_NONE, MAP_SHARED | MAP_FIXED, fd, offset);
result = mmap(result, size, PROT_NONE, mmapFlags | MAP_FIXED, fd, offset);
if (result == MAP_FAILED)
{
assert(false);
Expand All @@ -154,15 +165,15 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs
}

#ifndef TARGET_OSX
result = mmap(NULL, size, PROT_NONE, MAP_SHARED, fd, offset);
result = mmap(NULL, size, PROT_NONE, mmapFlags, fd, offset);
#else
int mmapFlags = MAP_ANON | MAP_PRIVATE;
if (IsMapJitFlagNeeded())
{
mmapFlags |= MAP_JIT;
}
result = mmap(NULL, size, PROT_NONE, mmapFlags, -1, 0);
#endif
#endif
if (result == MAP_FAILED)
{
assert(false);
Expand Down
9 changes: 8 additions & 1 deletion src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <sched.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
Expand All @@ -44,6 +43,10 @@
#include <signal.h>
#include <minipal/thread.h>

#ifdef TARGET_LINUX
#include <sys/syscall.h>
#endif

#if HAVE_PTHREAD_GETTHREADID_NP
#include <pthread_np.h>
#endif
Expand All @@ -60,6 +63,10 @@
#include <mach/mach.h>
#endif

#ifdef TARGET_HAIKU
#include <OS.h>
#endif

using std::nullptr_t;

#define PalRaiseFailFastException RaiseFailFastException
Expand Down
20 changes: 20 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/UnixContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@

#endif // HOST_ARM64

#elif defined(__HAIKU__)

#define MCREG_Rip(mc) ((mc).rip)
#define MCREG_Rsp(mc) ((mc).rsp)
#define MCREG_Rax(mc) ((mc).rax)
#define MCREG_Rbx(mc) ((mc).rbx)
#define MCREG_Rcx(mc) ((mc).rcx)
#define MCREG_Rdx(mc) ((mc).rdx)
#define MCREG_Rsi(mc) ((mc).rsi)
#define MCREG_Rdi(mc) ((mc).rdi)
#define MCREG_Rbp(mc) ((mc).rbp)
#define MCREG_R8(mc) ((mc).r8)
#define MCREG_R9(mc) ((mc).r9)
#define MCREG_R10(mc) ((mc).r10)
#define MCREG_R11(mc) ((mc).r11)
#define MCREG_R12(mc) ((mc).r12)
#define MCREG_R13(mc) ((mc).r13)
#define MCREG_R14(mc) ((mc).r14)
#define MCREG_R15(mc) ((mc).r15)

#else

#if HAVE___GREGSET_T
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/UnixContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
#ifndef __UNIX_CONTEXT_H__
#define __UNIX_CONTEXT_H__

#if HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <signal.h>
#endif

// Convert Unix native context to PAL_LIMITED_CONTEXT
void NativeContextToPalContext(const void* context, PAL_LIMITED_CONTEXT* palContext);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/unix/cgroupcpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Module Name:
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#else
#elif !defined(__HAIKU__)
#include <sys/vfs.h>
#endif
#include <errno.h>
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/pal/src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#cmakedefine01 HAVE_CLOCK_MONOTONIC
#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE
#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP
#cmakedefine01 HAVE_CLOCK_THREAD_CPUTIME
#cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK
#cmakedefine01 MMAP_ANON_IGNORES_PROTECTION
#cmakedefine01 ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/pal/src/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,22 @@ int main()
exit((ret == 0) ? 1 : 0);
}" HAVE_CLOCK_GETTIME_NSEC_NP)

set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
check_cxx_source_runs("
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

int main()
{
int ret;
struct timespec ts;
ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);

exit(ret);
}" HAVE_CLOCK_THREAD_CPUTIME)
set(CMAKE_REQUIRED_LIBRARIES)

check_cxx_source_runs("
#include <sys/types.h>
#include <sys/mman.h>
Expand Down
12 changes: 0 additions & 12 deletions src/coreclr/utilcode/sstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1713,18 +1713,6 @@ void SString::Printf(const CHAR *format, ...)
va_end(args);
}

#ifndef EBADF
#define EBADF 9
#endif

#ifndef ENOMEM
#define ENOMEM 12
#endif

#ifndef ERANGE
#define ERANGE 34
#endif

#if defined(_MSC_VER)
#undef va_copy
#define va_copy(dest,src) (dest = src)
Expand Down
Loading