[compiler-rt] r286997 - [asan] Don't assert that a target is within 2GB on 32-bit Windows

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 15 10:29:17 PST 2016


Author: rnk
Date: Tue Nov 15 12:29:17 2016
New Revision: 286997

URL: http://llvm.org/viewvc/llvm-project?rev=286997&view=rev
Log:
[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

Modified:
    compiler-rt/trunk/lib/interception/interception_win.cc
    compiler-rt/trunk/lib/interception/tests/CMakeLists.txt
    compiler-rt/trunk/lib/interception/tests/interception_win_test.cc

Modified: compiler-rt/trunk/lib/interception/interception_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception_win.cc?rev=286997&r1=286996&r2=286997&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_win.cc (original)
+++ compiler-rt/trunk/lib/interception/interception_win.cc Tue Nov 15 12:29:17 2016
@@ -148,10 +148,16 @@ static void InterceptionFailed() {
 }
 
 static bool DistanceIsWithin2Gig(uptr from, uptr target) {
+#if SANITIZER_WINDOWS64
   if (from < target)
     return target - from <= (uptr)0x7FFFFFFFU;
   else
     return from - target <= (uptr)0x80000000U;
+#else
+  // In a 32-bit address space, the address calculation will wrap, so this check
+  // is unnecessary.
+  return true;
+#endif
 }
 
 static uptr GetMmapGranularity() {

Modified: compiler-rt/trunk/lib/interception/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/tests/CMakeLists.txt?rev=286997&r1=286996&r2=286997&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/interception/tests/CMakeLists.txt Tue Nov 15 12:29:17 2016
@@ -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)
 

Modified: compiler-rt/trunk/lib/interception/tests/interception_win_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/tests/interception_win_test.cc?rev=286997&r1=286996&r2=286997&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/tests/interception_win_test.cc (original)
+++ compiler-rt/trunk/lib/interception/tests/interception_win_test.cc Tue Nov 15 12:29:17 2016
@@ -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;




More information about the llvm-commits mailing list