Skip to content

Commit 47328b1

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

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

compiler-rt/lib/interception/interception_win.cpp

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

545545
// Returns 0 on error.
546546
static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
547+
548+
if (rel_offset) {
549+
*rel_offset = 0;
550+
}
551+
547552
#if SANITIZER_ARM64
548553
// An ARM64 instruction is 4 bytes long.
549554
return 4;
@@ -907,6 +912,11 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
907912
return 0;
908913
}
909914

915+
// Unfortunately size_t is not known when compiling asan_allocator.cpp
916+
SIZE_T TestOnlyGetInstructionSize(uptr address, SIZE_T* rel_offset) {
917+
return GetInstructionSize(address, rel_offset);
918+
}
919+
910920
// Returns 0 on error.
911921
static size_t RoundUpToInstrBoundary(size_t size, uptr address) {
912922
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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,38 @@ TEST(Interception, EmptyExportTable) {
793793
EXPECT_EQ(0U, FunPtr);
794794
}
795795

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

798830
# endif // !SANITIZER_WINDOWS_ARM64

0 commit comments

Comments
 (0)