Skip to content

Commit b4919e8

Browse files
committed
[win/asan] Add a test skeleton for function GetInstructionSize.
1 parent 47ef5c4 commit b4919e8

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

compiler-rt/lib/interception/interception_win.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ static const u8 kPrologueWithShortJump2[] = {
544544

545545
// Returns 0 on error.
546546
static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
547+
if (rel_offset) {
548+
*rel_offset = 0;
549+
}
550+
547551
#if SANITIZER_ARM64
548552
// An ARM64 instruction is 4 bytes long.
549553
return 4;
@@ -907,6 +911,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
907911
return 0;
908912
}
909913

914+
size_t TestOnlyGetInstructionSize(uptr address, size_t *rel_offset) {
915+
return GetInstructionSize(address, rel_offset);
916+
}
917+
910918
// Returns 0 on error.
911919
static size_t RoundUpToInstrBoundary(size_t size, uptr address) {
912920
size_t cursor = 0;

compiler-rt/lib/interception/interception_win.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ bool OverrideFunctionWithTrampoline(
6363
// Exposed for unittests
6464
void TestOnlyReleaseTrampolineRegions();
6565

66+
// Exposed for unittests
67+
SIZE_T TestOnlyGetInstructionSize(uptr address, SIZE_T *rel_offset);
68+
6669
} // namespace __interception
6770

6871
#if defined(INTERCEPTION_DYNAMIC_CRT)

compiler-rt/lib/interception/tests/interception_win_test.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,41 @@ TEST(Interception, EmptyExportTable) {
793793
EXPECT_EQ(0U, FunPtr);
794794
}
795795

796+
const struct InstructionSizeData {
797+
size_t size; // hold instruction size or 0 for failure,
798+
// e.g. on control instructions
799+
u8 instr[16];
800+
size_t rel_offset;
801+
const char *comment;
802+
} data[] = {
803+
/* sorted list */
804+
{1, {0x50}, 0, "50 : push eax / rax"},
805+
};
806+
807+
std::string dumpInstruction(unsigned arrayIndex,
808+
const InstructionSizeData &data) {
809+
std::stringstream ret;
810+
ret << " with arrayIndex=" << arrayIndex << " {";
811+
for (size_t i = 0; i < data.size; i++) {
812+
if (i > 0)
813+
ret << ", ";
814+
ret << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex
815+
<< (int)data.instr[i];
816+
}
817+
ret << "} " << data.comment;
818+
return ret.str();
819+
}
820+
821+
TEST(Interception, GetInstructionSize) {
822+
for (unsigned i = 0; i < sizeof(data) / sizeof(*data); i++) {
823+
size_t rel_offset = ~0L;
824+
size_t size = __interception::TestOnlyGetInstructionSize(
825+
(uptr)data[i].instr, &rel_offset);
826+
EXPECT_EQ(data[i].size, size) << dumpInstruction(i, data[i]);
827+
EXPECT_EQ(data[i].rel_offset, rel_offset) << dumpInstruction(i, data[i]);
828+
}
829+
}
830+
796831
} // namespace __interception
797832

798833
# endif // !SANITIZER_WINDOWS_ARM64

0 commit comments

Comments
 (0)