Skip to content

Commit

Permalink
Haiku: Initial CoreCLR support (dotnet#109580)
Browse files Browse the repository at this point in the history
* Haiku: Initial CoreCLR support

This contains a part of the code required to build CoreCLR and get
`paltests` to pass on Haiku.

This commit covers `src/coreclr/**`, except the PAL files included
in the previous commit.

Co-authored-by: Jessica Hamilton <[email protected]>

* pal: Add back checks for HAVE_CLOCK_THREAD_CPUTIME

This was removed in dotnet#103441 but required for Haiku builds.

---------

Co-authored-by: Jessica Hamilton <[email protected]>
  • Loading branch information
trungnt2910 and jessicah authored Dec 6, 2024
1 parent 5fe72c1 commit bf44aaa
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 35 deletions.
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

0 comments on commit bf44aaa

Please sign in to comment.