Skip to content

Haiku: Add Haiku support for CoreCLR/PAL #93907

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 3 commits into from
Nov 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
8 changes: 8 additions & 0 deletions src/coreclr/ilasm/ilasmpch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@
#include "mdfileformat.h"
#include "stgpooli.h"

#ifdef _EXPORT
#undef _EXPORT
#endif

#ifdef _IMPORT
#undef _IMPORT
#endif

#endif
4 changes: 4 additions & 0 deletions src/coreclr/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,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 @@ -3952,7 +3954,9 @@ unsigned int __cdecl _rotr(unsigned int value, int shift)
PALIMPORT DLLEXPORT char * __cdecl PAL_getenv(const char *);
PALIMPORT DLLEXPORT int __cdecl _putenv(const char *);

#ifndef ERANGE
#define ERANGE 34
#endif

/****************PAL Perf functions for PInvoke*********************/
#if PAL_PERF
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
2 changes: 2 additions & 0 deletions src/coreclr/pal/src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#cmakedefine01 HAVE_PTHREAD_NP_H
#cmakedefine01 HAVE_AUXV_HWCAP_H
#cmakedefine01 HAVE_SYS_PTRACE_H
#cmakedefine01 HAVE_SYS_UCONTEXT_H
#cmakedefine01 HAVE_SYS_MOUNT_H
#cmakedefine01 HAVE_UCONTEXT_H
#cmakedefine01 HAVE_GETAUXVAL

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/pal/src/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ check_include_files(semaphore.h HAVE_SEMAPHORE_H)
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/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 @@ -44,11 +44,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,11 +32,14 @@ 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>
#include <fcntl.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 @@ -935,6 +937,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
1 change: 0 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
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
4 changes: 2 additions & 2 deletions src/coreclr/pal/src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2110,7 +2110,7 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
#endif
SIZE_T reserveSize = 0;
bool forceOveralign = false;
int readWriteFlags = MAP_FILE|MAP_PRIVATE|MAP_FIXED;
int readWriteFlags = MAP_PRIVATE|MAP_FIXED;
int readOnlyFlags = readWriteFlags;

ENTRY("MAPMapPEFile (hFile=%p offset=%zx)\n", hFile, offset);
Expand Down Expand Up @@ -2317,7 +2317,7 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
// If PAL_MAP_READONLY_PE_HUGE_PAGE_AS_SHARED is set to 1. map the readonly sections as shared
// which works well with the behavior of the hugetlbfs
if (mapAsShared != NULL && (strcmp(mapAsShared, "1") == 0))
readOnlyFlags = MAP_FILE|MAP_SHARED|MAP_FIXED;
readOnlyFlags = MAP_SHARED|MAP_FIXED;
}

//we have now reserved memory (potentially we got rebased). Walk the PE sections and map each part
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
24 changes: 23 additions & 1 deletion src/coreclr/pal/src/thread/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ extern "C"
#include <sys/user.h>
#endif

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

extern char *g_szCoreCLRPath;
extern bool g_running_in_exe;

Expand Down Expand Up @@ -1397,7 +1402,7 @@ PALIMPORT
VOID
PALAPI
PAL_SetCreateDumpCallback(
IN PCREATEDUMP_CALLBACK callback)
IN PCREATEDUMP_CALLBACK callback)
{
_ASSERTE(g_createdumpCallback == nullptr);
g_createdumpCallback = callback;
Expand Down Expand Up @@ -1680,6 +1685,23 @@ GetProcessIdDisambiguationKey(DWORD processId, UINT64 *disambiguationKey)

return TRUE;

#elif defined(__HAIKU__)

// On Haiku, we return the process start time expressed in microseconds since boot time.

team_info info;

if (get_team_info(processId, &info) == B_OK)
{
*disambiguationKey = info.start_time;
return TRUE;
}
else
{
WARN("Failed to get start time of a process.");
return FALSE;
}

#elif HAVE_PROCFS_STAT

// Here we read /proc/<pid>/stat file to get the start time for the process.
Expand Down
Loading
Loading