Skip to content

Commit 72e7cc3

Browse files
trungnt2910jessicah
andcommitted
Haiku: Initial CoreCLR support
This contains the code required to build CoreCLR and get paltests to pass on Haiku. Co-authored-by: Jessica Hamilton <[email protected]>
1 parent 5c81a06 commit 72e7cc3

File tree

51 files changed

+542
-93
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+542
-93
lines changed

src/coreclr/debug/dbgutil/elfreader.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,24 @@
99
#include <inttypes.h>
1010
#include "elfreader.h"
1111

12+
#ifndef Elf_Ehdr
1213
#define Elf_Ehdr ElfW(Ehdr)
14+
#endif
15+
#ifndef Elf_Phdr
1316
#define Elf_Phdr ElfW(Phdr)
17+
#endif
18+
#ifndef Elf_Shdr
1419
#define Elf_Shdr ElfW(Shdr)
20+
#endif
21+
#ifndef Elf_Nhdr
1522
#define Elf_Nhdr ElfW(Nhdr)
23+
#endif
24+
#ifndef Elf_Dyn
1625
#define Elf_Dyn ElfW(Dyn)
26+
#endif
27+
#ifndef Elf_Sym
1728
#define Elf_Sym ElfW(Sym)
29+
#endif
1830

1931
#if TARGET_64BIT
2032
#define PRIx PRIx64
@@ -34,6 +46,10 @@
3446
static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
3547
#endif
3648

49+
#ifdef TARGET_HAIKU
50+
#define DT_GNU_HASH DT_HASH
51+
#endif
52+
3753
class ElfReaderExport : public ElfReader
3854
{
3955
private:
@@ -314,7 +330,7 @@ ElfReader::GetStringAtIndex(int index, std::string& result)
314330
return true;
315331
}
316332

317-
#ifdef HOST_UNIX
333+
#if defined(HOST_UNIX) && !defined(TARGET_HAIKU)
318334

319335
//
320336
// Enumerate all the ELF info starting from the root program header. This
@@ -414,7 +430,7 @@ ElfReader::EnumerateLinkMapEntries(Elf_Dyn* dynamicAddr)
414430
return true;
415431
}
416432

417-
#endif // HOST_UNIX
433+
#endif // defined(HOST_UNIX) && !defined(TARGET_HAIKU)
418434

419435
bool
420436
ElfReader::EnumerateProgramHeaders(uint64_t baseAddress, uint64_t* ploadbias, Elf_Dyn** pdynamicAddr)

src/coreclr/debug/dbgutil/elfreader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ElfReader
3838
void* m_symbolTableAddr; // DT_SYMTAB
3939

4040
GnuHashTable m_hashTable; // gnu hash table info
41-
int32_t* m_buckets; // gnu hash table buckets
41+
int32_t* m_buckets; // gnu hash table buckets
4242
void* m_chainsAddress;
4343

4444
public:

src/coreclr/gc/unix/cgroup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Module Name:
2424
#if defined(__APPLE__) || defined(__FreeBSD__)
2525
#include <sys/param.h>
2626
#include <sys/mount.h>
27-
#else
27+
#elif !defined(__HAIKU__)
2828
#include <sys/vfs.h>
2929
#endif
3030
#include <errno.h>
@@ -56,7 +56,7 @@ Module Name:
5656

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

59-
namespace
59+
namespace
6060
{
6161
class CGroup
6262
{

src/coreclr/gc/unix/gcenv.unix.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ extern "C"
9191

9292
#endif // __APPLE__
9393

94+
#ifdef __HAIKU__
95+
#include <OS.h>
96+
#endif // __HAIKU__
97+
9498
#ifdef __linux__
9599
#include <sys/syscall.h> // __NR_membarrier
96100
// Ensure __NR_membarrier is defined for portable builds.
@@ -527,7 +531,11 @@ static void* VirtualReserveInner(size_t size, size_t alignment, uint32_t flags,
527531
}
528532

529533
size_t alignedSize = size + (alignment - OS_PAGE_SIZE);
530-
void * pRetVal = mmap(nullptr, alignedSize, PROT_NONE, MAP_ANON | MAP_PRIVATE | hugePagesFlag, -1, 0);
534+
int mmapFlags = MAP_ANON | MAP_PRIVATE | hugePagesFlag;
535+
#ifdef __HAIKU__
536+
mmapFlags |= MAP_NORESERVE;
537+
#endif
538+
void * pRetVal = mmap(nullptr, alignedSize, PROT_NONE, mmapFlags, -1, 0);
531539

532540
if (pRetVal != MAP_FAILED)
533541
{
@@ -661,7 +669,11 @@ bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
661669
// that much more clear to the operating system that we no
662670
// longer need these pages. Also, GC depends on re-committed pages to
663671
// be zeroed-out.
664-
bool bRetVal = mmap(address, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) != MAP_FAILED;
672+
int mmapFlags = MAP_FIXED | MAP_ANON | MAP_PRIVATE;
673+
#ifdef TARGET_HAIKU
674+
mmapFlags |= MAP_NORESERVE;
675+
#endif
676+
bool bRetVal = mmap(address, size, PROT_NONE, mmapFlags, -1, 0) != MAP_FAILED;
665677

666678
#ifdef MADV_DONTDUMP
667679
if (bRetVal)
@@ -955,7 +967,7 @@ static uint64_t GetMemorySizeMultiplier(char units)
955967
return 1;
956968
}
957969

958-
#ifndef __APPLE__
970+
#if !defined(__APPLE__) && !defined(__HAIKU__)
959971
// Try to read the MemAvailable entry from /proc/meminfo.
960972
// Return true if the /proc/meminfo existed, the entry was present and we were able to parse it.
961973
static bool ReadMemAvailable(uint64_t* memAvailable)
@@ -988,7 +1000,7 @@ static bool ReadMemAvailable(uint64_t* memAvailable)
9881000

9891001
return foundMemAvailable;
9901002
}
991-
#endif // __APPLE__
1003+
#endif // !defined(__APPLE__) && !defined(__HAIKU__)
9921004

9931005
// Get size of the largest cache on the processor die
9941006
// Parameters:
@@ -1189,15 +1201,21 @@ uint64_t GetAvailablePhysicalMemory()
11891201
#elif defined(__FreeBSD__)
11901202
size_t inactive_count = 0, laundry_count = 0, free_count = 0;
11911203
size_t sz = sizeof(inactive_count);
1192-
sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count, &sz, NULL, 0);
1204+
sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count, &sz, NULL, 0);
11931205

11941206
sz = sizeof(laundry_count);
1195-
sysctlbyname("vm.stats.vm.v_laundry_count", &laundry_count, &sz, NULL, 0);
1207+
sysctlbyname("vm.stats.vm.v_laundry_count", &laundry_count, &sz, NULL, 0);
11961208

11971209
sz = sizeof(free_count);
11981210
sysctlbyname("vm.stats.vm.v_free_count", &free_count, &sz, NULL, 0);
11991211

12001212
available = (inactive_count + laundry_count + free_count) * sysconf(_SC_PAGESIZE);
1213+
#elif defined(__HAIKU__)
1214+
system_info info;
1215+
if (get_system_info(&info) == B_OK)
1216+
{
1217+
available = info.free_memory;
1218+
}
12011219
#else // Linux
12021220
static volatile bool tryReadMemInfo = true;
12031221

src/coreclr/gc/unix/numasupport.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
#include <stdio.h>
1010
#include <dirent.h>
1111
#include <string.h>
12-
#include <sys/syscall.h>
1312
#include <minipal/utils.h>
1413

14+
#ifdef TARGET_LINUX
15+
#include <sys/syscall.h>
16+
#endif
17+
1518
// The highest NUMA node available
1619
int g_highestNumaNode = 0;
1720
// Is numa available

src/coreclr/hosts/corerun/corerun.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,10 @@ class platform_specific_actions final
314314
#include <ctype.h>
315315
#endif // !__APPLE__
316316

317+
#if defined(__HAIKU__)
318+
#include <OS.h>
319+
#endif // __HAIKU__
320+
317321
// CMake generated
318322
#include <config.h>
319323
#include <minipal/getexepath.h>
@@ -441,6 +445,15 @@ namespace pal
441445

442446
return ( (info.kp_proc.p_flag & P_TRACED) != 0 ) ? debugger_state_t::attached : debugger_state_t::not_attached;
443447

448+
#elif defined(__HAIKU__)
449+
team_info info;
450+
assert(get_team_info(B_CURRENT_TEAM, &info) == B_OK);
451+
452+
// A "nub thread" is spawned by the debugger when it attaches to a process.
453+
// While being debugged, the id of this thread is recorded in the team_info struct.
454+
// Otherwise the field should be -1.
455+
456+
return (info.debugger_nub_thread > 0) ? debugger_state_t::attached : debugger_state_t::not_attached;
444457
#else // !__APPLE__
445458
// Use procfs to detect if there is a tracer process.
446459
// See https://www.kernel.org/doc/html/latest/filesystems/proc.html

src/coreclr/inc/crosscomp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
722722
#define DAC_CS_NATIVE_DATA_SIZE 56
723723
#elif defined(__sun) && defined(TARGET_AMD64)
724724
#define DAC_CS_NATIVE_DATA_SIZE 48
725+
#elif defined(TARGET_HAIKU) && defined(TARGET_AMD64)
726+
#define DAC_CS_NATIVE_DATA_SIZE 56
725727
#else
726728
#warning
727729
#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)).

src/coreclr/minipal/Unix/doublemapping.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,22 @@ bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecu
5353

5454
#ifdef TARGET_FREEBSD
5555
int fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, S_IRWXU);
56-
#elif defined(TARGET_SUNOS) // has POSIX implementation
57-
char name[24];
58-
sprintf(name, "/shm-dotnet-%d", getpid());
59-
name[sizeof(name) - 1] = '\0';
60-
shm_unlink(name);
61-
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
62-
#else // TARGET_FREEBSD
56+
#elif defined(TARGET_LINUX)
6357
int fd = memfd_create("doublemapper", MFD_CLOEXEC);
64-
#endif // TARGET_FREEBSD
58+
#else
59+
int fd = -1;
60+
#endif
61+
62+
// POSIX fallback
63+
if (fd == -1)
64+
{
65+
char name[24];
66+
sprintf(name, "/shm-dotnet-%d", getpid());
67+
name[sizeof(name) - 1] = '\0';
68+
shm_unlink(name);
69+
fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
70+
shm_unlink(name);
71+
}
6572

6673
if (fd == -1)
6774
{
@@ -148,10 +155,14 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs
148155

149156
void* result = PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(rangeStart, rangeEnd, size, 0 /* fStoreAllocationInfo */);
150157
#ifndef TARGET_OSX
158+
int mmapFlags = MAP_SHARED;
159+
#ifdef TARGET_HAIKU
160+
mmapFlags |= MAP_NORESERVE;
161+
#endif // TARGET_HAIKU
151162
if (result != NULL)
152163
{
153164
// Map the shared memory over the range reserved from the executable memory allocator.
154-
result = mmap(result, size, PROT_NONE, MAP_SHARED | MAP_FIXED, fd, offset);
165+
result = mmap(result, size, PROT_NONE, mmapFlags | MAP_FIXED, fd, offset);
155166
if (result == MAP_FAILED)
156167
{
157168
assert(false);
@@ -167,15 +178,15 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs
167178
}
168179

169180
#ifndef TARGET_OSX
170-
result = mmap(NULL, size, PROT_NONE, MAP_SHARED, fd, offset);
181+
result = mmap(NULL, size, PROT_NONE, mmapFlags, fd, offset);
171182
#else
172183
int mmapFlags = MAP_ANON | MAP_PRIVATE;
173184
if (IsMapJitFlagNeeded())
174185
{
175186
mmapFlags |= MAP_JIT;
176187
}
177188
result = mmap(NULL, size, PROT_NONE, mmapFlags, -1, 0);
178-
#endif
189+
#endif
179190
if (result == MAP_FAILED)
180191
{
181192
assert(false);

src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
// Crash dump generating program arguments. MAX_ARGV_ENTRIES is the max number
5656
// of entries if every createdump option/argument is passed.
57-
#define MAX_ARGV_ENTRIES 32
57+
#define MAX_ARGV_ENTRIES 32
5858
const char* g_argvCreateDump[MAX_ARGV_ENTRIES] = { nullptr };
5959
char* g_szCreateDumpPath = nullptr;
6060
char* g_ppidarg = nullptr;
@@ -80,6 +80,9 @@ inline uint32_t PlatformGetCurrentThreadId() {
8080
#elif defined(__NetBSD__)
8181
#include <lwp.h>
8282
#define PlatformGetCurrentThreadId() (uint32_t)_lwp_self()
83+
#elif defined(__HAIKU__)
84+
#include <OS.h>
85+
#define PlatformGetCurrentThreadId() (uint32_t)find_thread(NULL)
8386
#else
8487
#define PlatformGetCurrentThreadId() (uint32_t)pthread_self()
8588
#endif

src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include <sched.h>
3333
#include <sys/mman.h>
3434
#include <sys/types.h>
35-
#include <sys/syscall.h>
3635
#include <dlfcn.h>
3736
#include <dirent.h>
3837
#include <string.h>
@@ -43,6 +42,10 @@
4342
#include <cstdarg>
4443
#include <signal.h>
4544

45+
#ifdef TARGET_LINUX
46+
#include <sys/syscall.h>
47+
#endif
48+
4649
#if HAVE_PTHREAD_GETTHREADID_NP
4750
#include <pthread_np.h>
4851
#endif
@@ -60,6 +63,10 @@
6063
#include <mach-o/getsect.h>
6164
#endif
6265

66+
#ifdef TARGET_HAIKU
67+
#include <OS.h>
68+
#endif
69+
6370
using std::nullptr_t;
6471

6572
#define PalRaiseFailFastException RaiseFailFastException
@@ -1242,6 +1249,8 @@ extern "C" uint64_t PalGetCurrentOSThreadId()
12421249
return (uint64_t)pthread_getthreadid_np();
12431250
#elif HAVE_LWP_SELF
12441251
return (uint64_t)_lwp_self();
1252+
#elif defined(__HAIKU__)
1253+
return (uint64_t)find_thread(NULL);
12451254
#else
12461255
// Fallback in case we don't know how to get integer thread id on the current platform
12471256
return (uint64_t)pthread_self();

0 commit comments

Comments
 (0)