Skip to content

Commit

Permalink
[compiler-rt][interception][win] Don't crash on unknown instructions
Browse files Browse the repository at this point in the history
Do not treat unknown instructions as a fatal error. In most cases,
failure to intercept a function is reported by the caller, though
requires setting verbosity to 1 or higher to be visible.

Better error message reporting for asan will be added in a separate
patch.

Differential Revision: https://reviews.llvm.org/D149549
  • Loading branch information
alvinhochun committed May 4, 2023
1 parent 814a75d commit 7b5571f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
10 changes: 7 additions & 3 deletions compiler-rt/lib/interception/interception_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ static const int kDirectBranchLength = kBranchLength + kAddressLength;

static void InterceptionFailed() {
// Do we have a good way to abort with an error message here?
// This acts like an abort when no debugger is attached. According to an old
// comment, calling abort() leads to an infinite recursion in CheckFailed.
__debugbreak();
}

Expand Down Expand Up @@ -658,9 +660,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
// Unknown instruction!
// FIXME: Unknown instruction failures might happen when we add a new
// interceptor or a new compiler version. In either case, they should result
// in visible and readable error messages. However, merely calling abort()
// leads to an infinite recursion in CheckFailed.
InterceptionFailed();
// in visible and readable error messages.
if (::IsDebuggerPresent())
__debugbreak();
return 0;
}

Expand All @@ -681,6 +683,8 @@ static bool CopyInstructions(uptr to, uptr from, size_t size) {
while (cursor != size) {
size_t rel_offset = 0;
size_t instruction_size = GetInstructionSize(from + cursor, &rel_offset);
if (!instruction_size)
return false;
_memcpy((void*)(to + cursor), (void*)(from + cursor),
(size_t)instruction_size);
if (rel_offset) {
Expand Down
14 changes: 14 additions & 0 deletions compiler-rt/lib/interception/tests/interception_win_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ const u8 kPatchableCode14[] = {
0x56, // push esi
};

const u8 kUnsupportedCode1[] = {
0x0f, 0x0b, // ud2
0x0f, 0x0b, // ud2
0x0f, 0x0b, // ud2
0x0f, 0x0b, // ud2
};

// A buffer holding the dynamically generated code under test.
u8* ActiveCode;
const size_t ActiveCodeLength = 4096;
Expand Down Expand Up @@ -717,6 +724,13 @@ TEST(Interception, PatchableFunctionWithTrampoline) {
EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
}

TEST(Interception, UnsupportedInstructionWithTrampoline) {
TestOverrideFunction override = OverrideFunctionWithTrampoline;
FunctionPrefixKind prefix = FunctionPrefixPadding;

EXPECT_FALSE(TestFunctionPatching(kUnsupportedCode1, override, prefix));
}

TEST(Interception, PatchableFunctionPadding) {
TestOverrideFunction override = OverrideFunction;
FunctionPrefixKind prefix = FunctionPrefixPadding;
Expand Down

0 comments on commit 7b5571f

Please sign in to comment.