[PATCH] D22647: [compiler-rt] Add support for relative offset adjustment in interception

Etienne Bergeron via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 21 14:10:29 PDT 2016


etienneb updated this revision to Diff 64960.
etienneb added a comment.

nits


https://reviews.llvm.org/D22647

Files:
  lib/interception/interception_win.cc

Index: lib/interception/interception_win.cc
===================================================================
--- lib/interception/interception_win.cc
+++ lib/interception/interception_win.cc
@@ -229,10 +229,6 @@
   _memset((void*)from, 0xCC, (size_t)size);
 }
 
-static void CopyInstructions(uptr from, uptr to, uptr size) {
-  _memcpy((void*)from, (void*)to, (size_t)size);
-}
-
 static void WriteJumpInstruction(uptr from, uptr target) {
   if (!DistanceIsWithin2Gig(from + kJumpInstructionLength, target))
     InterceptionFailed();
@@ -384,7 +380,7 @@
 }
 
 // Returns 0 on error.
-static size_t GetInstructionSize(uptr address) {
+static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
   switch (*(u64*)address) {
     case 0x90909090909006EB:  // stub: jmp over 6 x nop.
       return 8;
@@ -505,8 +501,11 @@
                       //   mov rax, QWORD PTR [rip + XXXXXXXX]
     case 0x25ff48:    // 48 ff 25 XX XX XX XX :
                       //   rex.W jmp QWORD PTR [rip + XXXXXXXX]
-      // Instructions having offset relative to 'rip' cannot be copied.
-      return 0;
+
+      // Instructions having offset relative to 'rip' need offset adjustment.
+      if (rel_offset)
+        *rel_offset = 3;
+      return 7;
 
     case 0x2444c7:    // C7 44 24 XX YY YY YY YY
                       //   mov dword ptr [rsp + XX], YYYYYYYY
@@ -580,6 +579,29 @@
   return cursor;
 }
 
+static bool CopyInstructions(uptr to, uptr from, size_t size) {
+  size_t cursor = 0;
+  while (cursor != size) {
+    size_t rel_offset = 0;
+    size_t instruction_size = GetInstructionSize(from + cursor, &rel_offset);
+    _memcpy((void*)(to + cursor), (void*)(from + cursor),
+            (size_t)instruction_size);
+    if (rel_offset) {
+      uptr delta = to - from;
+      uptr relocated_offset = *(u32*)(to + cursor + rel_offset) - delta;
+#if SANITIZER_WINDOWS64
+      if (relocated_offset + 0x80000000U >= 0xFFFFFFFFU)
+        return false;
+#endif
+      *(u32*)(to + cursor + rel_offset) = relocated_offset;
+    }
+    cursor += instruction_size;
+  }
+
+  return true;
+}
+
+
 #if !SANITIZER_WINDOWS64
 bool OverrideFunctionWithDetour(
     uptr old_func, uptr new_func, uptr *orig_old_func) {
@@ -670,7 +692,8 @@
     uptr trampoline = AllocateMemoryForTrampoline(old_func, trampoline_length);
     if (!trampoline)
       return false;
-    CopyInstructions(trampoline, old_func, instruction_size);
+    if (!CopyInstructions(trampoline, old_func, instruction_size))
+      return false;
     WriteDirectBranch(trampoline + instruction_size,
                       old_func + instruction_size);
     *orig_old_func = trampoline;
@@ -719,7 +742,8 @@
     uptr trampoline = AllocateMemoryForTrampoline(old_func, trampoline_length);
     if (!trampoline)
       return false;
-    CopyInstructions(trampoline, old_func, instructions_length);
+    if (!CopyInstructions(trampoline, old_func, instructions_length))
+      return false;
     WriteDirectBranch(trampoline + instructions_length,
                       old_func + instructions_length);
     *orig_old_func = trampoline;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22647.64960.patch
Type: text/x-patch
Size: 3115 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160721/03a17196/attachment.bin>


More information about the llvm-commits mailing list