From: Nico Weber Date: Wed, 25 Sep 2019 11:57:51 +0000 (+0000) Subject: builtins test: Move clear_cache_test.c from a mprotect()ed global to a mmap()ed variable X-Git-Tag: llvmorg-11-init~8355 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cddc153102d91f24ff2120cae77ff523e4381faf;p=platform%2Fupstream%2Fllvm.git builtins test: Move clear_cache_test.c from a mprotect()ed global to a mmap()ed variable ld64 in the macOS 10.15 SDK gives __DATA a maxprot of 3, meaning it can't be made executable at runtime by default. Change clear_cache_test.c to use mmap()ed data that's mapped as writable and executable from the beginning, instead of trying to mprotect()ing a __DATA variable as executable. This fixes the test on macOS with the 10.15 SDK. PR43407. Differential Revision: https://reviews.llvm.org/D67929 llvm-svn: 372849 --- diff --git a/compiler-rt/test/builtins/Unit/clear_cache_test.c b/compiler-rt/test/builtins/Unit/clear_cache_test.c index e85cc30..4220ba6 100644 --- a/compiler-rt/test/builtins/Unit/clear_cache_test.c +++ b/compiler-rt/test/builtins/Unit/clear_cache_test.c @@ -13,25 +13,16 @@ #include #include #include + #if defined(_WIN32) #include -static uintptr_t get_page_size() { - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} #else #include #include - -static uintptr_t get_page_size() { - return sysconf(_SC_PAGE_SIZE); -} #endif extern void __clear_cache(void* start, void* end); - typedef int (*pfunc)(void); // Make these static to avoid ILT jumps for incremental linking on Windows. @@ -51,34 +42,36 @@ memcpy_f(void *dst, const void *src, size_t n) { #endif } -unsigned char execution_buffer[128] __attribute__((aligned(8))); - int main() { - // make executable the page containing execution_buffer - uintptr_t page_size = get_page_size(); - char* start = (char*)((uintptr_t)execution_buffer & (-page_size)); - char* end = (char*)((uintptr_t)(&execution_buffer[128+page_size]) & (-page_size)); -#if defined(_WIN32) - DWORD dummy_oldProt; - MEMORY_BASIC_INFORMATION b; - if (!VirtualQuery(start, &b, sizeof(b))) - return 1; - if (!VirtualProtect(b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, &b.Protect)) + const int kSize = 128; +#if !defined(_WIN32) + uint8_t *execution_buffer = mmap(0, kSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (execution_buffer == MAP_FAILED) + return 1; #else - if (mprotect(start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) -#endif + HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, + PAGE_EXECUTE_READWRITE, 0, kSize, NULL); + if (mapping == NULL) return 1; + uint8_t* execution_buffer = MapViewOfFile( + mapping, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0); + if (execution_buffer == NULL) + return 1; +#endif + // verify you can copy and execute a function - pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, 128); - __clear_cache(execution_buffer, &execution_buffer[128]); + pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, kSize); + __clear_cache(execution_buffer, execution_buffer + kSize); if ((*f1)() != 1) return 1; // verify you can overwrite a function with another - pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, 128); - __clear_cache(execution_buffer, &execution_buffer[128]); + pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, kSize); + __clear_cache(execution_buffer, execution_buffer + kSize); if ((*f2)() != 2) return 1;