diff options
| author | Reid Kleckner <rnk@google.com> | 2016-11-15 18:29:17 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2016-11-15 18:29:17 +0000 |
| commit | 0d7c42c7abb3a822ce5b3c5960923dee07cc496f (patch) | |
| tree | e0bf3ef2df0e321cf65e8b3d7c905f4bdcef3026 /compiler-rt/lib/interception/tests | |
| parent | b17efcbcc560859636c8e28c0388f750a73f1918 (diff) | |
| download | bcm5719-llvm-0d7c42c7abb3a822ce5b3c5960923dee07cc496f.tar.gz bcm5719-llvm-0d7c42c7abb3a822ce5b3c5960923dee07cc496f.zip | |
[asan] Don't assert that a target is within 2GB on 32-bit Windows
Summary:
In a 32-bit address space, PC-relative jump targets are wrapped, so a
direct branch at 0x90000001 can reach address 0x10000000 with a
displacement of 0x7FFFFFFFF. This can happen in applications, such as
Chrome, that are linked with /LARGEADDRESSAWARE.
Reviewers: etienneb
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D26650
llvm-svn: 286997
Diffstat (limited to 'compiler-rt/lib/interception/tests')
| -rw-r--r-- | compiler-rt/lib/interception/tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | compiler-rt/lib/interception/tests/interception_win_test.cc | 31 |
2 files changed, 26 insertions, 6 deletions
diff --git a/compiler-rt/lib/interception/tests/CMakeLists.txt b/compiler-rt/lib/interception/tests/CMakeLists.txt index bfe41fed2fe..5ea943f9a82 100644 --- a/compiler-rt/lib/interception/tests/CMakeLists.txt +++ b/compiler-rt/lib/interception/tests/CMakeLists.txt @@ -29,6 +29,7 @@ else() endif() if(MSVC) list(APPEND INTERCEPTION_TEST_CFLAGS_COMMON -gcodeview) + list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -Wl,-largeaddressaware) endif() list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -g) diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cc b/compiler-rt/lib/interception/tests/interception_win_test.cc index 67b40f70146..684ee030355 100644 --- a/compiler-rt/lib/interception/tests/interception_win_test.cc +++ b/compiler-rt/lib/interception/tests/interception_win_test.cc @@ -204,7 +204,29 @@ const u8 kUnpatchableCode6[] = { // A buffer holding the dynamically generated code under test. u8* ActiveCode; -size_t ActiveCodeLength = 4096; +const size_t ActiveCodeLength = 4096; + +int InterceptorFunction(int x); + +/// Allocate code memory more than 2GB away from Base. +u8 *AllocateCode2GBAway(u8 *Base) { + // Find a 64K aligned location after Base plus 2GB. + size_t TwoGB = 0x80000000; + size_t AllocGranularity = 0x10000; + Base = (u8 *)((((uptr)Base + TwoGB + AllocGranularity)) & ~(AllocGranularity - 1)); + + // Check if that location is free, and if not, loop over regions until we find + // one that is. + MEMORY_BASIC_INFORMATION mbi = {}; + while (sizeof(mbi) == VirtualQuery(Base, &mbi, sizeof(mbi))) { + if (mbi.State & MEM_FREE) break; + Base += mbi.RegionSize; + } + + // Allocate one RWX page at the free location. + return (u8 *)::VirtualAlloc(Base, ActiveCodeLength, MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); +} template<class T> static void LoadActiveCode( @@ -212,11 +234,8 @@ static void LoadActiveCode( uptr *entry_point, FunctionPrefixKind prefix_kind = FunctionPrefixNone) { if (ActiveCode == nullptr) { - ActiveCode = - (u8*)::VirtualAlloc(nullptr, ActiveCodeLength, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); - ASSERT_NE(ActiveCode, nullptr); + ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction); + ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away"; } size_t position = 0; |

