Skip to content

Commit dc4d2cb

Browse files
authored
Merge pull request #1 from OpenHarmony-NET/try-fix-Marshall
try-fix-Marshall
2 parents 0f602b2 + 7818731 commit dc4d2cb

File tree

4 files changed

+86
-12
lines changed

4 files changed

+86
-12
lines changed

src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ project(Runtime)
66
# Include auto-generated files on include path
77
set(CMAKE_INCLUDE_CURRENT_DIR ON)
88

9-
if (CLR_CMAKE_TARGET_APPLE)
9+
if (CLR_CMAKE_TARGET_APPLE OR CLR_CMAKE_TARGET_LINUX_MUSL)
1010
list(APPEND RUNTIME_SOURCES_ARCH_ASM
1111
${ARCH_SOURCES_DIR}/ThunkPoolThunks.${ASM_SUFFIX}
1212
)

src/coreclr/nativeaot/Runtime/ThunksMapping.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ EXTERN_C void* QCALLTYPE RhAllocateThunksMapping()
359359
int thunkBlockSize = RhpGetThunkBlockSize();
360360
int templateSize = thunkBlocksPerMapping * thunkBlockSize;
361361

362-
#ifndef TARGET_APPLE // Apple platforms cannot use the initial template
362+
#ifndef TARGET_APPLE || TARGET_LINUX // Apple platforms cannot use the initial template
363363
if (pThunksTemplateAddress == NULL)
364364
{
365365
// First, we use the thunks directly from the thunks template sections in the module until all
@@ -377,8 +377,9 @@ EXTERN_C void* QCALLTYPE RhAllocateThunksMapping()
377377
uint8_t* pModuleBase = (uint8_t*)PalGetModuleHandleFromPointer(RhpGetThunksBase());
378378
int templateRva = (int)((uint8_t*)RhpGetThunksBase() - pModuleBase);
379379

380-
if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap))
380+
if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap)){
381381
return NULL;
382+
}
382383
}
383384

384385
if (!PalMarkThunksAsValidCallTargets(

src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212

1313
#define THUNKS_MAP_SIZE 0x8000
1414

15-
#ifdef TARGET_APPLE
16-
#define PAGE_SIZE 0x4000
17-
#define PAGE_SIZE_LOG2 14
15+
#ifdef TARGET_LINUX
16+
#define PAGE_SIZE 0x1000
17+
#define PAGE_SIZE_LOG2 12
1818
#else
1919
#error Unsupported OS
2020
#endif
2121

2222
// THUNK_POOL_NUM_THUNKS_PER_PAGE = min(PAGE_SIZE / THUNK_CODESIZE, (PAGE_SIZE - POINTER_SIZE) / THUNK_DATASIZE)
23-
#define THUNK_POOL_NUM_THUNKS_PER_PAGE 0x3ff
23+
#define THUNK_POOL_NUM_THUNKS_PER_PAGE 0xFF
2424

25-
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Thunk Pages ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25+
#ifdef TARGET_LINUX
2626

2727
.macro THUNKS_PAGE_BLOCK
2828
IN_PAGE_INDEX = 0
@@ -45,16 +45,17 @@
4545
.endr
4646
.endm
4747

48-
#ifdef TARGET_APPLE
4948
// Thunk pool
50-
.text
49+
.section .thunks ,"ax"
5150
.p2align PAGE_SIZE_LOG2
5251
PATCH_LABEL ThunkPool
5352
.rept (THUNKS_MAP_SIZE / PAGE_SIZE)
5453
.p2align PAGE_SIZE_LOG2
5554
THUNKS_PAGE_BLOCK
5655
.endr
56+
.space THUNKS_MAP_SIZE
5757
.p2align PAGE_SIZE_LOG2
58+
.section .text
5859
#else
5960
#error Unsupported OS
6061
#endif
@@ -66,8 +67,8 @@ PATCH_LABEL ThunkPool
6667
//
6768
LEAF_ENTRY RhpGetThunksBase
6869
// Return the address of the first thunk pool to the caller (this is really the base address)
69-
adrp x0, C_FUNC(ThunkPool)@PAGE
70-
add x0, x0, C_FUNC(ThunkPool)@PAGEOFF
70+
adrp x0, C_FUNC(ThunkPool)
71+
add x0, x0, #:lo12:C_FUNC(ThunkPool)
7172
ret
7273
LEAF_END RhpGetThunksBase
7374

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757

5858
#ifdef TARGET_APPLE
5959
#include <mach/mach.h>
60+
#elif defined(TARGET_LINUX)
61+
#include <unistd.h>
62+
#include <sys/mman.h>
63+
#include <string.h>
64+
#include <stdint.h>
6065
#endif
6166

6267
using std::nullptr_t;
@@ -566,6 +571,45 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(HANDL
566571

567572
*newThunksOut = (void*)addr;
568573

574+
return UInt32_TRUE;
575+
#elif defined(TARGET_LINUX)
576+
if (templateSize == 0)
577+
{
578+
return UInt32_FALSE;
579+
}
580+
581+
long pageSize = sysconf(_SC_PAGESIZE);
582+
if (pageSize == -1)
583+
{
584+
return UInt32_FALSE;
585+
}
586+
587+
// Align templateSize to page boundary
588+
size_t alignedSize = (templateSize + (size_t)pageSize - 1) & ~((size_t)pageSize - 1);
589+
if (alignedSize > SIZE_MAX / 2)
590+
{
591+
return UInt32_FALSE; // Prevent overflow
592+
}
593+
594+
size_t totalSize = 2 * alignedSize;
595+
void* allocation = mmap(NULL, totalSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
596+
if (allocation == MAP_FAILED)
597+
{
598+
return UInt32_FALSE;
599+
}
600+
601+
// Copy template code to the first block
602+
const void* templateSrc = (const void*)((uintptr_t)hTemplateModule + templateRva);
603+
memcpy(allocation, templateSrc, templateSize);
604+
__builtin___clear_cache((char*)allocation, (char*)allocation + templateSize);
605+
// Set first block to RX permissions
606+
if (mprotect(allocation, alignedSize, PROT_READ | PROT_EXEC) == -1)
607+
{
608+
munmap(allocation, totalSize);
609+
return UInt32_FALSE;
610+
}
611+
__builtin___clear_cache((char*)allocation, (char*)allocation + templateSize);
612+
*newThunksOut = allocation;
569613
return UInt32_TRUE;
570614
#else
571615
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
@@ -583,6 +627,34 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBa
583627
} while (ret == KERN_ABORTED);
584628

585629
return ret == KERN_SUCCESS ? UInt32_TRUE : UInt32_FALSE;
630+
#elif defined(TARGET_LINUX)
631+
if (pBaseAddress == NULL || templateSize == 0) {
632+
return UInt32_FALSE;
633+
}
634+
635+
// 获取系统页面大小
636+
long pageSize = sysconf(_SC_PAGESIZE);
637+
if (pageSize == -1) {
638+
return UInt32_FALSE;
639+
}
640+
641+
// 计算对齐后的内存大小(与分配时相同的计算方式)
642+
size_t alignedSize = (templateSize + (size_t)pageSize - 1) & ~((size_t)pageSize - 1);
643+
644+
// 防止整数溢出
645+
if (alignedSize > SIZE_MAX / 2) {
646+
return UInt32_FALSE;
647+
}
648+
649+
// 计算实际分配的总内存大小(2倍对齐大小)
650+
size_t totalSize = 2 * alignedSize;
651+
652+
// 释放内存
653+
if (munmap(pBaseAddress, totalSize) == -1) {
654+
return UInt32_FALSE;
655+
}
656+
657+
return UInt32_TRUE;
586658
#else
587659
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
588660
#endif

0 commit comments

Comments
 (0)