[compiler-rt] [win/asan] Add a test skeleton for function GetInstructionSize. (PR #116948)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 20 02:13:59 PST 2024


https://github.com/bernhardu created https://github.com/llvm/llvm-project/pull/116948

Was first part of PR #113085.

>From 47328b1848e34a7477e892af77fe5221eb92ac26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Thu, 7 Nov 2024 15:00:52 +0100
Subject: [PATCH] [win/asan] Add a test skeleton for function
 GetInstructionSize.

---
 .../lib/interception/interception_win.cpp     | 10 ++++++
 .../lib/interception/interception_win.h       |  3 ++
 .../tests/interception_win_test.cpp           | 32 +++++++++++++++++++
 3 files changed, 45 insertions(+)

diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index cfd92619a1e15d..ac5c5f7da85be4 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -544,6 +544,11 @@ 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;
@@ -907,6 +912,11 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
   return 0;
 }
 
+// Unfortunately size_t is not known when compiling asan_allocator.cpp
+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;
diff --git a/compiler-rt/lib/interception/interception_win.h b/compiler-rt/lib/interception/interception_win.h
index f6eca82191cba5..1c669977302cef 100644
--- a/compiler-rt/lib/interception/interception_win.h
+++ b/compiler-rt/lib/interception/interception_win.h
@@ -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)
diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cpp b/compiler-rt/lib/interception/tests/interception_win_test.cpp
index c004d187768de6..29141438f88ffd 100644
--- a/compiler-rt/lib/interception/tests/interception_win_test.cpp
+++ b/compiler-rt/lib/interception/tests/interception_win_test.cpp
@@ -793,6 +793,38 @@ TEST(Interception, EmptyExportTable) {
   EXPECT_EQ(0U, FunPtr);
 }
 
+const struct InstructionSizeData_t {
+  size_t size;       // hold instruction size or 0 for failure, e.g. on control instructions
+  u8 instr[16];
+  size_t rel_offset;
+} data[] = {
+  /* sorted list */
+  {  1, { 0x50 }, 0 },  // 50 : push eax / rax
+};
+
+std::string dumpInstruction(unsigned int arrayIndex, const InstructionSizeData_t& data) {
+    std::stringstream ret;
+    ret << "  with arrayIndex=" << arrayIndex << " ( ";
+    for (size_t byteIndex = 0; byteIndex < data.size; byteIndex++) {
+        ret << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)data.instr[byteIndex] << " ";
+    }
+    ret << ")";
+    return ret.str();
+}
+
+TEST(Interception, GetInstructionSize) {
+
+  size_t size;
+  size_t rel_offset;
+
+  for (unsigned int arrayIndex = 0; arrayIndex < sizeof(data)/sizeof(*data); arrayIndex++) {
+    rel_offset = ~0L;
+    size = __interception::TestOnlyGetInstructionSize((uptr)data[arrayIndex].instr, &rel_offset);
+    EXPECT_EQ(data[arrayIndex].size, size) << dumpInstruction(arrayIndex, data[arrayIndex]);
+    EXPECT_EQ(data[arrayIndex].rel_offset, rel_offset) << dumpInstruction(arrayIndex, data[arrayIndex]);
+  }
+}
+
 }  // namespace __interception
 
 #    endif  // !SANITIZER_WINDOWS_ARM64



More information about the llvm-commits mailing list