Skip to content

Commit 36b1811

Browse files
authored
[win/asan] Add a test skeleton for function GetInstructionSize. (#116948)
Was first part of PR #113085.
1 parent 79f59af commit 36b1811

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;
@@ -911,6 +915,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
911915
return 0;
912916
}
913917

918+
size_t TestOnlyGetInstructionSize(uptr address, size_t *rel_offset) {
919+
return GetInstructionSize(address, rel_offset);
920+
}
921+
914922
// Returns 0 on error.
915923
static size_t RoundUpToInstrBoundary(size_t size, uptr address) {
916924
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
@@ -797,6 +797,41 @@ TEST(Interception, EmptyExportTable) {
797797
EXPECT_EQ(0U, FunPtr);
798798
}
799799

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

802837
# endif // !SANITIZER_WINDOWS_ARM64

0 commit comments

Comments
 (0)