[compiler-rt] r276336 - [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:08:54 PDT 2016
Author: etienneb
Date: Thu Jul 21 16:08:54 2016
New Revision: 276336
URL: http://llvm.org/viewvc/llvm-project?rev=276336&view=rev
Log:
[compiler-rt] Add support for relative offset adjustment in interception
Summary:
Some instructions can only be copied if the relative offset is adjusted.
This patch adds support for two common instruction.
It's quite common to have a indirect load in the prologue
(loading the security cookie).
Reviewers: rnk
Subscribers: llvm-commits, wang0109, chrisha
Differential Revision: https://reviews.llvm.org/D22647
Modified:
compiler-rt/trunk/lib/interception/interception_win.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=276336&r1=276335&r2=276336&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_win.cc (original)
+++ compiler-rt/trunk/lib/interception/interception_win.cc Thu Jul 21 16:08:54 2016
@@ -229,10 +229,6 @@ static void WritePadding(uptr from, uptr
_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 @@ static uptr AllocateMemoryForTrampoline(
}
// 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 @@ static size_t GetInstructionSize(uptr ad
// 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,28 @@ static size_t RoundUpToInstrBoundary(siz
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 +691,8 @@ bool OverrideFunctionWithHotPatch(
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 +741,8 @@ bool OverrideFunctionWithTrampoline(
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;
More information about the llvm-commits
mailing list