Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler-rt/lib/interception/interception_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,10 @@ static const u8 kPrologueWithShortJump2[] = {

// Returns 0 on error.
static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
if (rel_offset) {
*rel_offset = 0;
}

#if SANITIZER_ARM64
// An ARM64 instruction is 4 bytes long.
return 4;
Expand Down Expand Up @@ -907,6 +911,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
return 0;
}

size_t TestOnlyGetInstructionSize(uptr address, size_t *rel_offset) {
return GetInstructionSize(address, rel_offset);
}

// Returns 0 on error.
static size_t RoundUpToInstrBoundary(size_t size, uptr address) {
size_t cursor = 0;
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/interception/interception_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ bool OverrideFunctionWithTrampoline(
// Exposed for unittests
void TestOnlyReleaseTrampolineRegions();

// Exposed for unittests
SIZE_T TestOnlyGetInstructionSize(uptr address, SIZE_T *rel_offset);

} // namespace __interception

#if defined(INTERCEPTION_DYNAMIC_CRT)
Expand Down
35 changes: 35 additions & 0 deletions compiler-rt/lib/interception/tests/interception_win_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,41 @@ TEST(Interception, EmptyExportTable) {
EXPECT_EQ(0U, FunPtr);
}

const struct InstructionSizeData {
size_t size; // hold instruction size or 0 for failure,
// e.g. on control instructions
u8 instr[16];
size_t rel_offset;
const char *comment;
} data[] = {
/* sorted list */
{1, {0x50}, 0, "50 : push eax / rax"},
};

std::string dumpInstruction(unsigned arrayIndex,
const InstructionSizeData &data) {
std::stringstream ret;
ret << " with arrayIndex=" << arrayIndex << " {";
for (size_t i = 0; i < data.size; i++) {
if (i > 0)
ret << ", ";
ret << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex
<< (int)data.instr[i];
}
ret << "} " << data.comment;
return ret.str();
}

TEST(Interception, GetInstructionSize) {
for (unsigned i = 0; i < sizeof(data) / sizeof(*data); i++) {
size_t rel_offset = ~0L;
size_t size = __interception::TestOnlyGetInstructionSize(
(uptr)data[i].instr, &rel_offset);
EXPECT_EQ(data[i].size, size) << dumpInstruction(i, data[i]);
EXPECT_EQ(data[i].rel_offset, rel_offset) << dumpInstruction(i, data[i]);
}
}

} // namespace __interception

# endif // !SANITIZER_WINDOWS_ARM64
Expand Down
Loading