[PATCH] D152748: [BOLT] Check dynamic relocations in analyzeJumpTable

Amir Ayupov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 13:40:23 PDT 2023


Amir updated this revision to Diff 532282.
Amir added a comment.

Check Section->isRelro


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152748/new/

https://reviews.llvm.org/D152748

Files:
  bolt/lib/Core/BinaryContext.cpp


Index: bolt/lib/Core/BinaryContext.cpp
===================================================================
--- bolt/lib/Core/BinaryContext.cpp
+++ bolt/lib/Core/BinaryContext.cpp
@@ -495,6 +495,7 @@
                                      const uint64_t NextJTAddress,
                                      JumpTable::AddressesType *EntriesAsAddress,
                                      bool *HasEntryInFragment) const {
+  using JTT = JumpTable::JumpTableType;
   // Is one of the targets __builtin_unreachable?
   bool HasUnreachable = false;
 
@@ -506,6 +507,27 @@
       EntriesAsAddress->emplace_back(EntryAddress);
   };
 
+  // Dynamic relocations are only eligible for jump table entries if their
+  // computed value is known to always point to the same location (code target)
+  // at runtime.
+  //
+  // A prerequisite for that is that 1) they are from read-only section (or
+  // write-once, such as in PT_GNU_RELRO case), 2) the value can't point to any
+  // location other than jump table target. The latter only holds for *_RELATIVE
+  // relocations where the value is computed against the base address at which a
+  // shared object has been loaded into memory during execution, hence it can't
+  // arbitrarily change.
+  auto hasEligibleDynamicRelocation = [&](uint64_t EntryAddress) {
+    const Relocation *Relocation = getDynamicRelocationAt(EntryAddress);
+    if (!Relocation || !Relocation->isRelative())
+      return false;
+    if (auto SectionOrErr = getSectionForAddress(EntryAddress)) {
+      const BinarySection &Section = SectionOrErr.get();
+      return !Section.isWritable() || Section.isRelro();
+    }
+    return false;
+  };
+
   ErrorOr<const BinarySection &> Section = getSectionForAddress(Address);
   if (!Section)
     return false;
@@ -523,7 +545,6 @@
     UpperBound = std::min(NextJTAddress, UpperBound);
 
   LLVM_DEBUG({
-    using JTT = JumpTable::JumpTableType;
     dbgs() << formatv("BOLT-DEBUG: analyzeJumpTable @{0:x} in {1}, JTT={2}\n",
                       Address, BF.getPrintName(),
                       Type == JTT::JTT_PIC ? "PIC" : "Normal");
@@ -535,16 +556,13 @@
                       << " -> ");
     // Check if there's a proper relocation against the jump table entry.
     if (HasRelocations) {
-      if (Type == JumpTable::JTT_PIC &&
-          !DataPCRelocations.count(EntryAddress)) {
-        LLVM_DEBUG(
-            dbgs() << "FAIL: JTT_PIC table, no relocation for this address\n");
+      if (Type == JTT::JTT_PIC && !DataPCRelocations.count(EntryAddress)) {
+        LLVM_DEBUG(dbgs() << "FAIL: no relocation for this address\n");
         break;
       }
-      if (Type == JumpTable::JTT_NORMAL && !getRelocationAt(EntryAddress)) {
-        LLVM_DEBUG(
-            dbgs()
-            << "FAIL: JTT_NORMAL table, no relocation for this address\n");
+      if (Type == JTT::JTT_NORMAL && !getRelocationAt(EntryAddress) &&
+          !hasEligibleDynamicRelocation(EntryAddress)) {
+        LLVM_DEBUG(dbgs() << "FAIL: no relocation for this address\n");
         break;
       }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152748.532282.patch
Type: text/x-patch
Size: 3074 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230616/70f31ed5/attachment.bin>


More information about the llvm-commits mailing list