Skip to content

Commit

Permalink
Haiku: Add Haiku support for CoreCLR/PAL
Browse files Browse the repository at this point in the history
This contains a part of the code required to build CoreCLR and get
`paltests` to pass on Haiku.

This commit covers `src/coreclr/pal/**`.

Co-authored-by: Jessica Hamilton <jessica.l.hamilton@gmail.com>
  • Loading branch information
trungnt2910 and jessicah committed Apr 30, 2024
1 parent bb61fb5 commit a7afb88
Show file tree
Hide file tree
Showing 23 changed files with 165 additions and 37 deletions.
25 changes: 23 additions & 2 deletions src/coreclr/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ extern bool g_arm64_atomics_present;
#endif // !_MSC_VER
#endif // !THROW_DECL

#ifdef __sun
#if defined(__sun) || defined(__HAIKU__)
#define MATH_THROW_DECL
#else
#define MATH_THROW_DECL THROW_DECL
Expand Down Expand Up @@ -2651,6 +2651,8 @@ PALIMPORT BOOL PALAPI PAL_GetUnwindInfoSize(SIZE_T baseAddress, ULONG64 ehFrameH
#define PAL_CS_NATIVE_DATA_SIZE 96
#elif defined(__linux__) && defined(__riscv) && __riscv_xlen == 64
#define PAL_CS_NATIVE_DATA_SIZE 96
#elif defined(__HAIKU__) && defined(__x86_64__)
#define PAL_CS_NATIVE_DATA_SIZE 56
#else
#error PAL_CS_NATIVE_DATA_SIZE is not defined for this architecture
#endif
Expand Down Expand Up @@ -3960,7 +3962,26 @@ unsigned int __cdecl _rotr(unsigned int value, int shift)
PALIMPORT DLLEXPORT char * __cdecl PAL_getenv(const char *);
PALIMPORT DLLEXPORT int __cdecl _putenv(const char *);

#define ERANGE 34
#ifndef PAL_STDCPP_COMPAT

#ifdef __HAIKU__
// Haiku uses different errno values
#define EINVAL ((int)0x80000005)
#define ERANGE ((int)0x80007011)
#define EILSEQ ((int)0x80007026)
#define ENOENT ((int)0x80006003)
#define EBADF ((int)0x80006000)
#define ENOMEM ((int)0x80000000)
#else // __HAIKU__
#define EINVAL 22
#define ERANGE 34
#define EILSEQ 42
#define ENOENT 2
#define EBADF 9
#define ENOMEM 12
#endif

#endif // !PAL_STDCPP_COMPAT

PALIMPORT WCHAR __cdecl PAL_ToUpperInvariant(WCHAR);
PALIMPORT WCHAR __cdecl PAL_ToLowerInvariant(WCHAR);
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/pal/inc/rt/safecrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,6 @@ typedef int errno_t; /* standard */
/* error codes */
#if !defined(_SECURECRT_ERRCODE_VALUES_DEFINED)
#define _SECURECRT_ERRCODE_VALUES_DEFINED
#if !defined(EINVAL)
#define EINVAL 22
#endif
#if !defined(ERANGE)
#define ERANGE 34
#endif
#if !defined(EILSEQ)
#define EILSEQ 42
#endif
#if !defined(STRUNCATE)
#define STRUNCATE 80
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/pal/src/arch/amd64/signalhandlerhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
#include "pal/context.h"
#include "pal/signal.hpp"
#include "pal/utils.h"

#if HAVE_SYS_UCONTEXT_H
#include <sys/ucontext.h>
#endif

/*++
Function :
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/pal/src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#cmakedefine01 HAVE_AUXV_HWCAP_H
#cmakedefine01 HAVE_SYS_PTRACE_H
#cmakedefine01 HAVE_SYS_UCONTEXT_H
#cmakedefine01 HAVE_SYS_USER_H
#cmakedefine01 HAVE_SYS_MOUNT_H
#cmakedefine01 HAVE_UCONTEXT_H
#cmakedefine01 HAVE_GETAUXVAL
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/pal/src/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ check_include_files(sys/prctl.h HAVE_PRCTL_H)
check_include_files("sys/auxv.h;asm/hwcap.h" HAVE_AUXV_HWCAP_H)
check_include_files("sys/ptrace.h" HAVE_SYS_PTRACE_H)
check_include_files("sys/ucontext.h" HAVE_SYS_UCONTEXT_H)
check_include_files("sys/user.h" HAVE_SYS_USER_H)
check_include_files("sys/mount.h" HAVE_SYS_MOUNT_H)
check_include_files(ucontext.h HAVE_UCONTEXT_H)
check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL)
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/pal/src/debug/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do
#include <unistd.h>
#elif defined(HAVE_TTRACE) // HAVE_PROCFS_CTL
#include <sys/ttrace.h>
#else // defined(HAVE_TTRACE)
#elif HAVE_SYS_PTRACE_H
#include <sys/ptrace.h>
#endif // HAVE_PROCFS_CTL
#if HAVE_VM_READ
Expand Down Expand Up @@ -635,7 +635,7 @@ PAL_CloseProcessMemory(
PAL_ReadProcessMemory
Abstract
Reads process memory.
Reads process memory.
Parameter
handle : from PAL_OpenProcessMemory
Expand Down Expand Up @@ -753,7 +753,7 @@ PAL_ProbeMemory(

flags = fcntl(fds[0], F_GETFL, 0);
fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);

flags = fcntl(fds[1], F_GETFL, 0);
fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/pal/src/exception/seh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ PAL_ERROR SEHEnable(CPalThread *pthrCurrent)
{
#if HAVE_MACH_EXCEPTIONS
return pthrCurrent->EnableMachExceptions();
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun)
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun) || defined(__HAIKU__)
return NO_ERROR;
#else// HAVE_MACH_EXCEPTIONS
#error not yet implemented
Expand All @@ -330,7 +330,7 @@ PAL_ERROR SEHDisable(CPalThread *pthrCurrent)
{
#if HAVE_MACH_EXCEPTIONS
return pthrCurrent->DisableMachExceptions();
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun)
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun) || defined(__HAIKU__)
return NO_ERROR;
#else // HAVE_MACH_EXCEPTIONS
#error not yet implemented
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/pal/src/exception/signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
#include "pal/utils.h"

#include <string.h>
#include <sys/ucontext.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <sys/mman.h>

#if HAVE_SYS_UCONTEXT_H
#include <sys/ucontext.h>
#endif // HAVE_SYS_UCONTEXT_H

#endif // !HAVE_MACH_EXCEPTIONS
#include "pal/context.h"
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/pal/src/file/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ SET_DEFAULT_DEBUG_CHANNEL(FILE); // some headers have code with asserts, so do t
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <errno.h>
#include <limits.h>

#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif

using namespace CorUnix;

int MaxWCharToAcpLengthFactor = 3;
Expand Down
37 changes: 37 additions & 0 deletions src/coreclr/pal/src/include/pal/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ extern "C"
/* A type to wrap the native context type, which is ucontext_t on some
* platforms and another type elsewhere. */
#if HAVE_UCONTEXT_T
#if HAVE_UCONTEXT_H
#include <ucontext.h>
#endif // HAVE_UCONTEXT_H

typedef ucontext_t native_context_t;
#else // HAVE_UCONTEXT_T
Expand Down Expand Up @@ -874,6 +876,41 @@ inline void *FPREG_Xstate_Hi16Zmm(const ucontext_t *uc, uint32_t *featureSize)
*featureSize = sizeof(_STRUCT_ZMM_REG) * 16;
return reinterpret_cast<void *>(&((_STRUCT_X86_AVX512_STATE64&)FPSTATE(uc)).__fpu_zmm16);
}
#elif defined(TARGET_HAIKU)

#define MCREG_Rbp(mc) ((mc).rbp)
#define MCREG_Rip(mc) ((mc).rip)
#define MCREG_Rsp(mc) ((mc).rsp)
#define MCREG_Rsi(mc) ((mc).rsi)
#define MCREG_Rdi(mc) ((mc).rdi)
#define MCREG_Rbx(mc) ((mc).rbx)
#define MCREG_Rdx(mc) ((mc).rdx)
#define MCREG_Rcx(mc) ((mc).rcx)
#define MCREG_Rax(mc) ((mc).rax)
#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)
#define MCREG_EFlags(mc) ((mc).rflags)
// Haiku: missing SegCs

#define FPSTATE(uc) ((uc)->uc_mcontext.fpu)
#define FPREG_ControlWord(uc) FPSTATE(uc).fp_fxsave.control
#define FPREG_StatusWord(uc) FPSTATE(uc).fp_fxsave.status
#define FPREG_TagWord(uc) FPSTATE(uc).fp_fxsave.tag
#define FPREG_MxCsr(uc) FPSTATE(uc).fp_fxsave.mxcsr
#define FPREG_MxCsr_Mask(uc) FPSTATE(uc).fp_fxsave.mscsr_mask
#define FPREG_ErrorOffset(uc) *(DWORD*) &(FPSTATE(uc).fp_fxsave.rip)
#define FPREG_ErrorSelector(uc) *((WORD*) &(FPSTATE(uc).fp_fxsave.rip) + 2)
#define FPREG_DataOffset(uc) *(DWORD*) &(FPSTATE(uc).fp_fxsave.rdp)
#define FPREG_DataSelector(uc) *((WORD*) &(FPSTATE(uc).fp_fxsave.rdp) + 2)

#define FPREG_Xmm(uc, index) *(M128A*) &(FPSTATE(uc).fp_fxsave.xmm[index])
#define FPREG_St(uc, index) *(M128A*) &(FPSTATE(uc).fp_fxsave.fp[index].value)
#else //TARGET_OSX

// For FreeBSD, as found in x86/ucontext.h
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/pal/src/include/pal/palinternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ function_name() to call the system's implementation
#undef sigsetjmp
#undef siglongjmp

#undef _SIZE_T_DEFINED

#define _DONT_USE_CTYPE_INLINE_
#if HAVE_RUNETYPE_H
#include <runetype.h>
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/pal/src/include/pal/thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Module Name:
#include "cs.hpp"

#include <pthread.h>
#include <sys/syscall.h>
#if HAVE_MACH_EXCEPTIONS
#include <mach/mach.h>
#endif // HAVE_MACH_EXCEPTIONS
Expand Down Expand Up @@ -745,6 +744,7 @@ extern PAL_SafeActivationCheckFunction g_safeActivationCheckFunction;
--*/
#if defined(__linux__)
#include <sys/syscall.h>
#define PlatformGetCurrentThreadId() (SIZE_T)syscall(SYS_gettid)
#elif defined(__APPLE__)
inline SIZE_T PlatformGetCurrentThreadId() {
Expand All @@ -758,6 +758,9 @@ inline SIZE_T PlatformGetCurrentThreadId() {
#elif defined(__NetBSD__)
#include <lwp.h>
#define PlatformGetCurrentThreadId() (SIZE_T)_lwp_self()
#elif defined(__HAIKU__)
#include <OS.h>
#define PlatformGetCurrentThreadId() (SIZE_T)find_thread(NULL)
#else
#define PlatformGetCurrentThreadId() (SIZE_T)pthread_self()
#endif
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/pal/src/init/pal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ int CacheLineSize;
#include <sys/user.h>
#endif

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

#include <algorithm>
#include <clrconfignocache.h>

Expand Down Expand Up @@ -897,6 +901,13 @@ PAL_IsDebuggerPresent()

close(fd);
return status.pr_flttrace.word[0] != 0;
#elif defined(__HAIKU__)
team_info info;
if (get_team_info(B_CURRENT_TEAM, &info) == B_OK)
{
return info.debugger_nub_thread > 0;
}
return FALSE;
#else
return FALSE;
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/pal/src/loader/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,16 @@ LPCSTR FixLibCName(LPCSTR shortAsciiName)
// As a result, we have to use the full name (i.e. lib.so.6) that is defined by LIBC_SO.
// * For macOS, use constant value absolute path "/usr/lib/libc.dylib".
// * For FreeBSD, use constant value "libc.so.7".
// * For Haiku, use constant value "libroot.so".
// * For rest of Unices, use constant value "libc.so".
if (strcmp(shortAsciiName, LIBC_NAME_WITHOUT_EXTENSION) == 0)
{
#if defined(__APPLE__)
return "/usr/lib/libc.dylib";
#elif defined(__FreeBSD__)
return "libc.so.7";
#elif defined(__HAIKU__)
return "libroot.so";
#elif defined(LIBC_SO)
return LIBC_SO;
#else
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/pal/src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ MAPmmapAndRecord(
#define MAP_ANON MAP_ANONYMOUS
#endif

/* Some platforms like Haiku does not provide MAP_FILE */
#ifndef MAP_FILE
#define MAP_FILE 0
#endif

void
FileMappingCleanupRoutine(
CPalThread *pThread,
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/pal/src/map/virtual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@ static LPVOID ReserveVirtualMemory(
}
#endif

#ifdef __HAIKU__
mmapFlags |= MAP_NORESERVE;
#endif

LPVOID pRetVal = mmap((LPVOID) StartBoundary,
MemSize,
PROT_NONE,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/pal/src/misc/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC);
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#else
#elif !defined(__HAIKU__)
#include <sys/vfs.h>
#endif

Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/pal/src/misc/sysinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ Revision History:
#include <mach/mach_host.h>
#endif // defined(TARGET_OSX)

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

#ifdef __FreeBSD__
// On some platforms sys/user.h ends up defining _DEBUG; if so
// remove the definition before including the header and put
// back our definition afterwards
Expand All @@ -78,6 +83,7 @@ Revision History:
#define _DEBUG OLD_DEBUG
#undef OLD_DEBUG
#endif
#endif // __FreeBSD__

#include "pal/dbgmsg.h"
#include "pal/process.h"
Expand Down Expand Up @@ -211,6 +217,8 @@ GetSystemInfo(
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) (1ull << 47);
#elif defined(__sun)
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) 0xfffffd7fffe00000ul;
#elif defined(__HAIKU__)
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) 0x7fffffe00000ul;
#elif defined(USERLIMIT)
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) USERLIMIT;
#elif defined(HOST_64BIT)
Expand Down
19 changes: 14 additions & 5 deletions src/coreclr/pal/src/thread/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,22 @@ typedef int __ptrace_request;
#endif // !HAVE_MACH_EXCEPTIONS

#ifdef HOST_AMD64
#ifdef __HAIKU__
#define ASSIGN_CONTROL_REGS \
ASSIGN_REG(Rbp) \
ASSIGN_REG(Rip) \
ASSIGN_REG(SegCs) \
ASSIGN_REG(EFlags) \
ASSIGN_REG(Rsp) \
ASSIGN_REG(Rbp) \
ASSIGN_REG(Rip) \
ASSIGN_REG(EFlags) \
ASSIGN_REG(Rsp) \

#else // __HAIKU__
#define ASSIGN_CONTROL_REGS \
ASSIGN_REG(Rbp) \
ASSIGN_REG(Rip) \
ASSIGN_REG(SegCs) \
ASSIGN_REG(EFlags) \
ASSIGN_REG(Rsp) \

#endif // __HAIKU__
#define ASSIGN_INTEGER_REGS \
ASSIGN_REG(Rdi) \
ASSIGN_REG(Rsi) \
Expand Down
Loading

0 comments on commit a7afb88

Please sign in to comment.