[llvm] 2272ec1 - [JITLink][MachO] Fix "find-symbol-by-address" logic.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 12 21:28:49 PST 2021


Author: Lang Hames
Date: 2021-11-12T21:28:32-08:00
New Revision: 2272ec1c63893e370e7dea8b946843d8d433d458

URL: https://github.com/llvm/llvm-project/commit/2272ec1c63893e370e7dea8b946843d8d433d458
DIFF: https://github.com/llvm/llvm-project/commit/2272ec1c63893e370e7dea8b946843d8d433d458.diff

LOG: [JITLink][MachO] Fix "find-symbol-by-address" logic.

Only search within the requested section, and allow one-past-then-end addresses.

This is needed to support section-end-address references to sections with no
symbols in them.

Added: 
    llvm/test/ExecutionEngine/JITLink/X86/MachO_lookup_section_end_by_address.s

Modified: 
    llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
    llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
    llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
    llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index a54f2a3abf59d..438a23830efd8 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -318,16 +318,19 @@ Error MachOLinkGraphBuilder::createNormalizedSymbols() {
 }
 
 void MachOLinkGraphBuilder::addSectionStartSymAndBlock(
-    Section &GraphSec, uint64_t Address, const char *Data, uint64_t Size,
-    uint32_t Alignment, bool IsLive) {
+    unsigned SecIndex, Section &GraphSec, uint64_t Address, const char *Data,
+    uint64_t Size, uint32_t Alignment, bool IsLive) {
   Block &B =
       Data ? G->createContentBlock(GraphSec, ArrayRef<char>(Data, Size),
                                    Address, Alignment, 0)
            : G->createZeroFillBlock(GraphSec, Size, Address, Alignment, 0);
   auto &Sym = G->addAnonymousSymbol(B, 0, Size, false, IsLive);
-  assert(!AddrToCanonicalSymbol.count(Sym.getAddress()) &&
+  auto SecI = IndexToSection.find(SecIndex);
+  assert(SecI != IndexToSection.end() && "SecIndex invalid");
+  auto &NSec = SecI->second;
+  assert(!NSec.CanonicalSymbols.count(Sym.getAddress()) &&
          "Anonymous block start symbol clashes with existing symbol address");
-  AddrToCanonicalSymbol[Sym.getAddress()] = &Sym;
+  NSec.CanonicalSymbols[Sym.getAddress()] = &Sym;
 }
 
 Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
@@ -441,8 +444,8 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
                  << formatv("{0:x16}", NSec.Address) << " -- "
                  << formatv("{0:x16}", NSec.Address + NSec.Size) << "\n";
         });
-        addSectionStartSymAndBlock(*NSec.GraphSection, NSec.Address, NSec.Data,
-                                   NSec.Size, NSec.Alignment,
+        addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
+                                   NSec.Data, NSec.Size, NSec.Alignment,
                                    SectionIsNoDeadStrip);
       } else
         LLVM_DEBUG({
@@ -480,8 +483,8 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
                << formatv("{0:x16}", NSec.Address) << " -- "
                << formatv("{0:x16}", NSec.Address + AnonBlockSize) << " ]\n";
       });
-      addSectionStartSymAndBlock(*NSec.GraphSection, NSec.Address, NSec.Data,
-                                 AnonBlockSize, NSec.Alignment,
+      addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
+                                 NSec.Data, AnonBlockSize, NSec.Alignment,
                                  SectionIsNoDeadStrip);
     }
 
@@ -580,7 +583,7 @@ Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,
   NSym.GraphSymbol = &Sym;
 
   if (IsCanonical)
-    setCanonicalSymbol(Sym);
+    setCanonicalSymbol(getSectionByIndex(NSym.Sect - 1), Sym);
 
   return Sym;
 }
@@ -607,7 +610,6 @@ Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers() {
 
 Error MachOLinkGraphBuilder::graphifyCStringSection(
     NormalizedSection &NSec, std::vector<NormalizedSymbol *> NSyms) {
-
   assert(NSec.GraphSection && "C string literal section missing graph section");
   assert(NSec.Data && "C string literal section has no data");
 
@@ -661,7 +663,7 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
       // If there's no symbol at the start of this block then create one.
       if (NSyms.empty() || NSyms.back()->Value != B.getAddress()) {
         auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
-        setCanonicalSymbol(S);
+        setCanonicalSymbol(NSec, S);
         LLVM_DEBUG({
           dbgs() << "      Adding anonymous symbol for c-string block "
                  << formatv("{0:x16} -- {1:x16}", S.getAddress(),

diff  --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
index d6ea4e2c244cf..d29732ebdba82 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
@@ -77,6 +77,7 @@ class MachOLinkGraphBuilder {
     uint32_t Flags = 0;
     const char *Data = nullptr;
     Section *GraphSection = nullptr;
+    std::map<JITTargetAddress, Symbol *> CanonicalSymbols;
   };
 
   using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
@@ -135,19 +136,21 @@ class MachOLinkGraphBuilder {
 
   /// Returns the symbol with the highest address not greater than the search
   /// address, or null if no such symbol exists.
-  Symbol *getSymbolByAddress(JITTargetAddress Address) {
-    auto I = AddrToCanonicalSymbol.upper_bound(Address);
-    if (I == AddrToCanonicalSymbol.begin())
+  Symbol *getSymbolByAddress(NormalizedSection &NSec,
+                             JITTargetAddress Address) {
+    auto I = NSec.CanonicalSymbols.upper_bound(Address);
+    if (I == NSec.CanonicalSymbols.begin())
       return nullptr;
     return std::prev(I)->second;
   }
 
   /// Returns the symbol with the highest address not greater than the search
   /// address, or an error if no such symbol exists.
-  Expected<Symbol &> findSymbolByAddress(JITTargetAddress Address) {
-    auto *Sym = getSymbolByAddress(Address);
+  Expected<Symbol &> findSymbolByAddress(NormalizedSection &NSec,
+                                         JITTargetAddress Address) {
+    auto *Sym = getSymbolByAddress(NSec, Address);
     if (Sym)
-      if (Address < Sym->getAddress() + Sym->getSize())
+      if (Address <= Sym->getAddress() + Sym->getSize())
         return *Sym;
     return make_error<JITLinkError>("No symbol covering address " +
                                     formatv("{0:x16}", Address));
@@ -178,8 +181,8 @@ class MachOLinkGraphBuilder {
   static unsigned getPointerSize(const object::MachOObjectFile &Obj);
   static support::endianness getEndianness(const object::MachOObjectFile &Obj);
 
-  void setCanonicalSymbol(Symbol &Sym) {
-    auto *&CanonicalSymEntry = AddrToCanonicalSymbol[Sym.getAddress()];
+  void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
+    auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
     // There should be no symbol at this address, or, if there is,
     // it should be a zero-sized symbol from an empty section (which
     // we can safely override).
@@ -189,9 +192,10 @@ class MachOLinkGraphBuilder {
   }
 
   Section &getCommonSection();
-  void addSectionStartSymAndBlock(Section &GraphSec, uint64_t Address,
-                                  const char *Data, uint64_t Size,
-                                  uint32_t Alignment, bool IsLive);
+  void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
+                                  uint64_t Address, const char *Data,
+                                  uint64_t Size, uint32_t Alignment,
+                                  bool IsLive);
 
   Error createNormalizedSections();
   Error createNormalizedSymbols();
@@ -226,7 +230,6 @@ class MachOLinkGraphBuilder {
   Section *CommonSection = nullptr;
 
   DenseMap<uint32_t, NormalizedSymbol *> IndexToSymbol;
-  std::map<JITTargetAddress, Symbol *> AddrToCanonicalSymbol;
   StringMap<SectionParserFunction> CustomSectionParserFunctions;
 };
 

diff  --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
index 9d1eb9468f819..c20fae5957274 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
@@ -160,7 +160,7 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
       auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);
       if (!ToSymbolSec)
         return ToSymbolSec.takeError();
-      ToSymbol = getSymbolByAddress(ToSymbolSec->Address);
+      ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);
       assert(ToSymbol && "No symbol for section");
       FixupValue -= ToSymbol->getAddress();
     }
@@ -205,14 +205,18 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
         continue;
       }
 
-      // Skip relocations for debug symbols.
+      auto NSec =
+          findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
+      if (!NSec)
+        return NSec.takeError();
+
+      // Skip relocations for MachO sections without corresponding graph
+      // sections.
       {
-        auto &NSec =
-            getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
-        if (!NSec.GraphSection) {
+        if (!NSec->GraphSection) {
           LLVM_DEBUG({
             dbgs() << "  Skipping relocations for MachO section "
-                   << NSec.SegName << "/" << NSec.SectName
+                   << NSec->SegName << "/" << NSec->SectName
                    << " which has no associated graph section\n";
           });
           continue;
@@ -231,18 +235,15 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
 
         // Find the address of the value to fix up.
         JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
-
         LLVM_DEBUG({
-          auto &NSec =
-              getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
-          dbgs() << "  " << NSec.SectName << " + "
+          dbgs() << "  " << NSec->SectName << " + "
                  << formatv("{0:x8}", RI.r_address) << ":\n";
         });
 
         // Find the block that the fixup points to.
         Block *BlockToFix = nullptr;
         {
-          auto SymbolToFixOrErr = findSymbolByAddress(FixupAddress);
+          auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);
           if (!SymbolToFixOrErr)
             return SymbolToFixOrErr.takeError();
           BlockToFix = &SymbolToFixOrErr->getBlock();
@@ -324,7 +325,11 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
           break;
         case Pointer64Anon: {
           JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
-          if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
+          auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
+          if (!TargetNSec)
+            return TargetNSec.takeError();
+          if (auto TargetSymbolOrErr =
+                  findSymbolByAddress(*TargetNSec, TargetAddress))
             TargetSymbol = &*TargetSymbolOrErr;
           else
             return TargetSymbolOrErr.takeError();

diff  --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
index 18f92c8e47e45..0c5d1adaf6d49 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
@@ -170,7 +170,7 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
       auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);
       if (!ToSymbolSec)
         return ToSymbolSec.takeError();
-      ToSymbol = getSymbolByAddress(ToSymbolSec->Address);
+      ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);
       assert(ToSymbol && "No symbol for section");
       FixupValue -= ToSymbol->getAddress();
     }
@@ -216,14 +216,18 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
         continue;
       }
 
-      // Skip relocations for debug symbols.
+      auto NSec =
+          findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
+      if (!NSec)
+        return NSec.takeError();
+
+      // Skip relocations for MachO sections without corresponding graph
+      // sections.
       {
-        auto &NSec =
-            getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
-        if (!NSec.GraphSection) {
+        if (!NSec->GraphSection) {
           LLVM_DEBUG({
             dbgs() << "  Skipping relocations for MachO section "
-                   << NSec.SegName << "/" << NSec.SectName
+                   << NSec->SegName << "/" << NSec->SectName
                    << " which has no associated graph section\n";
           });
           continue;
@@ -240,16 +244,14 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
         JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
 
         LLVM_DEBUG({
-          auto &NSec =
-              getSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));
-          dbgs() << "  " << NSec.SectName << " + "
+          dbgs() << "  " << NSec->SectName << " + "
                  << formatv("{0:x8}", RI.r_address) << ":\n";
         });
 
         // Find the block that the fixup points to.
         Block *BlockToFix = nullptr;
         {
-          auto SymbolToFixOrErr = findSymbolByAddress(FixupAddress);
+          auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);
           if (!SymbolToFixOrErr)
             return SymbolToFixOrErr.takeError();
           BlockToFix = &SymbolToFixOrErr->getBlock();
@@ -342,7 +344,11 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
           break;
         case MachOPointer64Anon: {
           JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
-          if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
+          auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
+          if (!TargetNSec)
+            return TargetNSec.takeError();
+          if (auto TargetSymbolOrErr =
+                  findSymbolByAddress(*TargetNSec, TargetAddress))
             TargetSymbol = &*TargetSymbolOrErr;
           else
             return TargetSymbolOrErr.takeError();
@@ -363,7 +369,11 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
         case MachOPCRel32Anon: {
           JITTargetAddress TargetAddress =
               FixupAddress + 4 + *(const little32_t *)FixupContent;
-          if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
+          auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
+          if (!TargetNSec)
+            return TargetNSec.takeError();
+          if (auto TargetSymbolOrErr =
+                  findSymbolByAddress(*TargetNSec, TargetAddress))
             TargetSymbol = &*TargetSymbolOrErr;
           else
             return TargetSymbolOrErr.takeError();
@@ -379,7 +389,11 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
                       1ULL << (*MachORelocKind - MachOPCRel32Minus1Anon));
           JITTargetAddress TargetAddress =
               FixupAddress + Delta + *(const little32_t *)FixupContent;
-          if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
+          auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
+          if (!TargetNSec)
+            return TargetNSec.takeError();
+          if (auto TargetSymbolOrErr =
+                  findSymbolByAddress(*TargetNSec, TargetAddress))
             TargetSymbol = &*TargetSymbolOrErr;
           else
             return TargetSymbolOrErr.takeError();

diff  --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_lookup_section_end_by_address.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_lookup_section_end_by_address.s
new file mode 100644
index 0000000000000..92e40ea07af04
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_lookup_section_end_by_address.s
@@ -0,0 +1,27 @@
+# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t %s
+# RUN: llvm-jitlink -noexec %t
+#
+# Check that JITLink handles anonymous relocations to the end of MachO sections.
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 11, 0	sdk_version 11, 1
+	.globl	_main
+	.p2align	4, 0x90
+_main:
+
+	movq	_R(%rip), %rax
+	retq
+
+	.section	__TEXT,__anon,regular
+L__anon_start:
+        .byte 7
+L__anon_end:
+
+	.private_extern	_R
+	.section	__DATA,__data
+	.globl	_R
+	.p2align	3
+_R:
+	.quad L__anon_end
+
+.subsections_via_symbols


        


More information about the llvm-commits mailing list