[llvm] [JITLink][AArch32] Draft fixture class for fixup tests and out-of-range errors in particular (PR #73397)

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 25 08:22:39 PST 2023


https://github.com/weliveindetail created https://github.com/llvm/llvm-project/pull/73397

Design draft for testing out-of-range errors and packing helper functions into a gtest fixture:
https://github.com/google/googletest/blob/main/docs/primer.md#test-fixtures-using-the-same-data-configuration-for-multiple-tests-same-data-multiple-tests

>From 2994148f81eb155bb5c8b15c23cf74cf781bb268 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Sat, 25 Nov 2023 14:58:32 +0100
Subject: [PATCH 1/2] [JITLink][AArch32] Split out error test for invalid edge
 fixup as well

---
 .../JITLink/AArch32ErrorTests.cpp             | 44 ++++++++++++++-----
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
index c3bf45e03398c28..662731c378a06ab 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
@@ -39,7 +39,8 @@ class AArch32Errors_ELF : public testing::Test {
   std::unique_ptr<LinkGraph> G;
   Section *S = nullptr;
 
-  const uint8_t Zeros[4]{0x00, 0x00, 0x00, 0x00};
+  const uint8_t Zeros[4] {0x00, 0x00, 0x00, 0x00};
+  uint8_t MutableZeros[4] {0x00, 0x00, 0x00, 0x00};
 
 public:
   static void SetUpTestCase() {}
@@ -62,6 +63,21 @@ class AArch32Errors_ELF : public testing::Test {
     return G->createContentBlock(*S, CharContent, orc::ExecutorAddr(Addr),
                                  Alignment, AlignmentOffset);
   }
+
+  template <size_t Size>
+  Block &createMutableBlock(uint8_t (&Content)[Size], uint64_t Addr,
+                            uint64_t Alignment = 4) {
+    MutableArrayRef<char> CharContent{reinterpret_cast<char *>(&Content),
+                                      sizeof(Content)};
+    return G->createMutableContentBlock(
+        *S, CharContent, orc::ExecutorAddr(Addr), Alignment, AlignmentOffset);
+  }
+
+  template <endianness Endian>
+  void writeHalfWords(uint8_t *Mem, HalfWords Data) {
+    write16<Endian>(Mem, Data.Hi);
+    write16<Endian>(Mem + 2, Data.Lo);
+  }
 };
 
 TEST_F(AArch32Errors_ELF, readAddendDataErrors) {
@@ -121,6 +137,23 @@ TEST(AArch32_ELF, readAddendThumbErrors) {
   }
 }
 
+TEST_F(AArch32Errors_ELF, applyFixupDataErrors) {
+  Block &OriginBlock = createMutableBlock(MutableZeros, 0x1000);
+  Block &TargetBlock = createBlock(Zeros, 0x2000);
+
+  constexpr uint64_t OffsetInTarget = 0;
+  Symbol &TargetSymbol = G->addAnonymousSymbol(TargetBlock, OffsetInTarget,
+                                               PointerSize, false, false);
+
+  constexpr uint64_t OffsetInOrigin = 0;
+  Edge::Kind Invalid = Edge::GenericEdgeKind::Invalid;
+  Edge InvalidEdge(Invalid, OffsetInOrigin, TargetSymbol, 0 /*Addend*/);
+  EXPECT_THAT_ERROR(
+      applyFixup(*G, OriginBlock, InvalidEdge, ArmCfg),
+      FailedWithMessage(testing::HasSubstr(
+          "encountered unfixable aarch32 edge kind INVALID RELOCATION")));
+}
+
 TEST(AArch32_ELF, applyFixupArmErrors) {
 
   constexpr orc::ExecutorAddr B3DummyAddr(0x5000);
@@ -134,13 +167,6 @@ TEST(AArch32_ELF, applyFixupArmErrors) {
 
   Symbol &TargetSymbol =
       G->addAnonymousSymbol(BArm, SymbolOffset, SymbolSize, false, false);
-  Edge InvalidEdge(Edge::GenericEdgeKind::Invalid, 0 /*Offset*/, TargetSymbol,
-                   0 /*Addend*/);
-
-  EXPECT_THAT_ERROR(
-      applyFixup(*G, BArm, InvalidEdge, ArmCfg),
-      FailedWithMessage(testing::HasSubstr(
-          "encountered unfixable aarch32 edge kind INVALID RELOCATION")));
 
   for (Edge::Kind K = FirstArmRelocation; K < LastArmRelocation; K += 1) {
     Edge E(K, 0, TargetSymbol, 0);
@@ -180,8 +206,6 @@ TEST(AArch32_ELF, applyFixupThumbErrors) {
       Sec, MutableThumbContent, B4DummyAddr, ThumbAlignment, AlignmentOffset);
   Symbol &TargetSymbol =
       G->addAnonymousSymbol(BThumb, SymbolOffset, SymbolSize, false, false);
-  Edge InvalidEdge(Edge::GenericEdgeKind::Invalid, 0 /*Offset*/, TargetSymbol,
-                   0 /*Addend*/);
 
   for (Edge::Kind K = FirstThumbRelocation; K < LastThumbRelocation; K += 1) {
     Edge E(K, 0, TargetSymbol, 0);

>From 9129999853059b10429199461e7c0357ff6b6e23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Sat, 25 Nov 2023 17:05:46 +0100
Subject: [PATCH 2/2] [JITLink][AArch32] Prototype out-of-range error test for
 Thumb_Call fixup

---
 .../JITLink/AArch32ErrorTests.cpp             | 29 ++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
index 662731c378a06ab..4461d6573933203 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
@@ -177,7 +177,7 @@ TEST(AArch32_ELF, applyFixupArmErrors) {
   }
 }
 
-TEST(AArch32_ELF, applyFixupThumbErrors) {
+TEST_F(AArch32Errors_ELF, applyFixupThumbErrors) {
 
   struct MutableHalfWords {
     constexpr MutableHalfWords(HalfWords Preset)
@@ -214,4 +214,31 @@ TEST(AArch32_ELF, applyFixupThumbErrors) {
                           testing::StartsWith("Invalid opcode"),
                           testing::EndsWith(aarch32::getEdgeKindName(K)))));
   }
+
+  {
+    uint8_t TwoCallsMem[8];
+    using CallInfo = FixupInfo<Thumb_Call>;
+    writeHalfWords<endianness::little>(TwoCallsMem, CallInfo::Opcode);
+    writeHalfWords<endianness::little>(TwoCallsMem + 4, CallInfo::Opcode);
+
+    Block &CallSiteBlock = createMutableBlock(TwoCallsMem, 0x1000);
+
+    uint64_t CallAddr = CallSiteBlock.getAddress().getValue() + (0x01ull << 24);
+    Block &TargetBlock = createBlock(Zeros, CallAddr);
+
+    constexpr uint64_t OffsetInTarget = 0;
+    Symbol &TargetSymbol = G->addAnonymousSymbol(TargetBlock, OffsetInTarget,
+                                                PointerSize, false, false);
+
+    // The second call site has the last in-range distance
+    constexpr uint64_t OffsetInOriginSecondCall = 4;
+    Edge InRangeEdge(Thumb_Call, OffsetInOriginSecondCall, TargetSymbol, 0);
+    EXPECT_THAT_ERROR(applyFixup(*G, CallSiteBlock, InRangeEdge, ArmCfg), Succeeded());
+
+    // The first call site has the first out-of-range distance
+    constexpr uint64_t OffsetInOriginFirstCall = 0;
+    Edge OutOfRangeEdge(Thumb_Call, OffsetInOriginFirstCall, TargetSymbol, 0);
+    EXPECT_THAT_ERROR(applyFixup(*G, CallSiteBlock, OutOfRangeEdge, ArmCfg),
+                      FailedWithMessage(testing::HasSubstr("out of range of Thumb_Call fixup")));
+  }
 }



More information about the llvm-commits mailing list