Skip to content
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
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ project(Runtime)
# Include auto-generated files on include path
set(CMAKE_INCLUDE_CURRENT_DIR ON)

if (CLR_CMAKE_TARGET_APPLE)
if (CLR_CMAKE_TARGET_APPLE OR CLR_CMAKE_TARGET_LINUX_MUSL)
list(APPEND RUNTIME_SOURCES_ARCH_ASM
${ARCH_SOURCES_DIR}/ThunkPoolThunks.${ASM_SUFFIX}
)
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ EXTERN_C void* QCALLTYPE RhAllocateThunksMapping()
int thunkBlockSize = RhpGetThunkBlockSize();
int templateSize = thunkBlocksPerMapping * thunkBlockSize;

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

if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap))
if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap)){
return NULL;
}
}

if (!PalMarkThunksAsValidCallTargets(
Expand Down
19 changes: 10 additions & 9 deletions src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@

#define THUNKS_MAP_SIZE 0x8000

#ifdef TARGET_APPLE
#define PAGE_SIZE 0x4000
#define PAGE_SIZE_LOG2 14
#ifdef TARGET_LINUX
#define PAGE_SIZE 0x1000
#define PAGE_SIZE_LOG2 12
#else
#error Unsupported OS
#endif

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

//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Thunk Pages ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#ifdef TARGET_LINUX

.macro THUNKS_PAGE_BLOCK
IN_PAGE_INDEX = 0
Expand All @@ -45,16 +45,17 @@
.endr
.endm

#ifdef TARGET_APPLE
// Thunk pool
.text
.section .thunks ,"ax"
.p2align PAGE_SIZE_LOG2
PATCH_LABEL ThunkPool
.rept (THUNKS_MAP_SIZE / PAGE_SIZE)
.p2align PAGE_SIZE_LOG2
THUNKS_PAGE_BLOCK
.endr
.space THUNKS_MAP_SIZE
.p2align PAGE_SIZE_LOG2
.section .text
#else
#error Unsupported OS
#endif
Expand All @@ -66,8 +67,8 @@ PATCH_LABEL ThunkPool
//
LEAF_ENTRY RhpGetThunksBase
// Return the address of the first thunk pool to the caller (this is really the base address)
adrp x0, C_FUNC(ThunkPool)@PAGE
add x0, x0, C_FUNC(ThunkPool)@PAGEOFF
adrp x0, C_FUNC(ThunkPool)
add x0, x0, #:lo12:C_FUNC(ThunkPool)
ret
LEAF_END RhpGetThunksBase

Expand Down
72 changes: 72 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@

#ifdef TARGET_APPLE
#include <mach/mach.h>
#elif defined(TARGET_LINUX)
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdint.h>
#endif

using std::nullptr_t;
Expand Down Expand Up @@ -566,6 +571,45 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(HANDL

*newThunksOut = (void*)addr;

return UInt32_TRUE;
#elif defined(TARGET_LINUX)
if (templateSize == 0)
{
return UInt32_FALSE;
}

long pageSize = sysconf(_SC_PAGESIZE);
if (pageSize == -1)
{
return UInt32_FALSE;
}

// Align templateSize to page boundary
size_t alignedSize = (templateSize + (size_t)pageSize - 1) & ~((size_t)pageSize - 1);
if (alignedSize > SIZE_MAX / 2)
{
return UInt32_FALSE; // Prevent overflow
}

size_t totalSize = 2 * alignedSize;
void* allocation = mmap(NULL, totalSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (allocation == MAP_FAILED)
{
return UInt32_FALSE;
}

// Copy template code to the first block
const void* templateSrc = (const void*)((uintptr_t)hTemplateModule + templateRva);
memcpy(allocation, templateSrc, templateSize);
__builtin___clear_cache((char*)allocation, (char*)allocation + templateSize);
// Set first block to RX permissions
if (mprotect(allocation, alignedSize, PROT_READ | PROT_EXEC) == -1)
{
munmap(allocation, totalSize);
return UInt32_FALSE;
}
__builtin___clear_cache((char*)allocation, (char*)allocation + templateSize);
*newThunksOut = allocation;
return UInt32_TRUE;
#else
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
Expand All @@ -583,6 +627,34 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBa
} while (ret == KERN_ABORTED);

return ret == KERN_SUCCESS ? UInt32_TRUE : UInt32_FALSE;
#elif defined(TARGET_LINUX)
if (pBaseAddress == NULL || templateSize == 0) {
return UInt32_FALSE;
}

// 获取系统页面大小
long pageSize = sysconf(_SC_PAGESIZE);
if (pageSize == -1) {
return UInt32_FALSE;
}

// 计算对齐后的内存大小(与分配时相同的计算方式)
size_t alignedSize = (templateSize + (size_t)pageSize - 1) & ~((size_t)pageSize - 1);

// 防止整数溢出
if (alignedSize > SIZE_MAX / 2) {
return UInt32_FALSE;
}

// 计算实际分配的总内存大小(2倍对齐大小)
size_t totalSize = 2 * alignedSize;

// 释放内存
if (munmap(pBaseAddress, totalSize) == -1) {
return UInt32_FALSE;
}

return UInt32_TRUE;
#else
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
#endif
Expand Down
Loading