[JITLink] Switch from StringRef to ArrayRef<char>, add some generic x86-64 utils
authorLang Hames <lhames@gmail.com>
Wed, 31 Mar 2021 03:56:03 +0000 (20:56 -0700)
committerLang Hames <lhames@gmail.com>
Wed, 31 Mar 2021 04:07:24 +0000 (21:07 -0700)
Adds utilities for creating anonymous pointers and jump stubs to x86_64.h. These
are used by the GOT and Stubs builder, but may also be used by pass writers who
want to create pointer stubs for indirection.

This patch also switches the underlying type for LinkGraph content from
StringRef to ArrayRef<char>. This avoids any confusion when working with buffers
that contain null bytes in the middle like, for example, a newly added null
pointer content array. ;)

17 files changed:
llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
llvm/tools/llvm-jitlink/llvm-jitlink.cpp
llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp

index c145c99..646cc4c 100644 (file)
@@ -158,7 +158,7 @@ private:
   }
 
   /// Create a defined addressable for the given content.
-  Block(Section &Parent, StringRef Content, JITTargetAddress Address,
+  Block(Section &Parent, ArrayRef<char> Content, JITTargetAddress Address,
         uint64_t Alignment, uint64_t AlignmentOffset)
       : Addressable(Address, true), Parent(Parent), Data(Content.data()),
         Size(Content.size()) {
@@ -194,15 +194,15 @@ public:
   size_t getSize() const { return Size; }
 
   /// Get the content for this block. Block must not be a zero-fill block.
-  StringRef getContent() const {
+  ArrayRef<char> getContent() const {
     assert(Data && "Section does not contain content");
-    return StringRef(Data, Size);
+    return ArrayRef<char>(Data, Size);
   }
 
   /// Set the content for this block.
   /// Caller is responsible for ensuring the underlying bytes are not
   /// deallocated while pointed to by this block.
-  void setContent(StringRef Content) {
+  void setContent(ArrayRef<char> Content) {
     Data = Content.data();
     Size = Content.size();
   }
@@ -500,8 +500,8 @@ public:
 
   /// Returns the content in the underlying block covered by this symbol.
   /// This method may only be called on defined non-zero-fill symbols.
-  StringRef getSymbolContent() const {
-    return getBlock().getContent().substr(Offset, Size);
+  ArrayRef<char> getSymbolContent() const {
+    return getBlock().getContent().slice(Offset, Size);
   }
 
   /// Get the linkage for this Symbol.
@@ -849,10 +849,10 @@ public:
   /// Allocate a copy of the given string using the LinkGraph's allocator.
   /// This can be useful when renaming symbols or adding new content to the
   /// graph.
-  StringRef allocateString(StringRef Source) {
+  ArrayRef<char> allocateString(ArrayRef<char> Source) {
     auto *AllocatedBuffer = Allocator.Allocate<char>(Source.size());
     llvm::copy(Source, AllocatedBuffer);
-    return StringRef(AllocatedBuffer, Source.size());
+    return ArrayRef<char>(AllocatedBuffer, Source.size());
   }
 
   /// Allocate a copy of the given string using the LinkGraph's allocator.
@@ -860,14 +860,14 @@ public:
   /// graph.
   ///
   /// Note: This Twine-based overload requires an extra string copy and an
-  /// extra heap allocation for large strings. The StringRef overload should
-  /// be preferred where possible.
-  StringRef allocateString(Twine Source) {
+  /// extra heap allocation for large strings. The ArrayRef<char> overload
+  /// should be preferred where possible.
+  ArrayRef<char> allocateString(Twine Source) {
     SmallString<256> TmpBuffer;
     auto SourceStr = Source.toStringRef(TmpBuffer);
     auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size());
     llvm::copy(SourceStr, AllocatedBuffer);
-    return StringRef(AllocatedBuffer, SourceStr.size());
+    return ArrayRef<char>(AllocatedBuffer, SourceStr.size());
   }
 
   /// Create a section with the given name, protection flags, and alignment.
@@ -883,7 +883,7 @@ public:
   }
 
   /// Create a content block.
-  Block &createContentBlock(Section &Parent, StringRef Content,
+  Block &createContentBlock(Section &Parent, ArrayRef<char> Content,
                             uint64_t Address, uint64_t Alignment,
                             uint64_t AlignmentOffset) {
     return createBlock(Parent, Content, Address, Alignment, AlignmentOffset);
index 868a535..7d5c82e 100644 (file)
@@ -336,6 +336,52 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
   return Error::success();
 }
 
+/// x86-64 null pointer content.
+extern const char NullPointerContent[8];
+
+/// x86-64 pointer jump stub content.
+///
+/// Contains the instruction sequence for an indirect jump via an in-memory
+/// pointer:
+///   jmpq *ptr(%rip)
+extern const char PointerJumpStubContent[6];
+
+/// Creates a new pointer block in the given section and returns an anonymous
+/// symbol pointing to it.
+///
+/// If InitialTarget is given then an Pointer64 relocation will be added to the
+/// block pointing at InitialTarget.
+///
+/// The pointer block will have the following default values:
+///   alignment: 64-bit
+///   alignment-offset: 0
+///   address: highest allowable (~7U)
+inline Symbol &createAnonymousPointer(LinkGraph &G, Section &PointerSection,
+                                      Symbol *InitialTarget = nullptr,
+                                      uint64_t InitialAddend = 0) {
+  auto &B =
+      G.createContentBlock(PointerSection, NullPointerContent, ~7ULL, 8, 0);
+  if (InitialTarget)
+    B.addEdge(Pointer64, 0, *InitialTarget, InitialAddend);
+  return G.addAnonymousSymbol(B, 0, 8, false, false);
+}
+
+/// Create a jump stub that jumps via the pointer at the given symbol, returns
+/// an anonymous symbol pointing to it.
+///
+/// The stub block will have the following default values:
+///   alignment: 8-bit
+///   alignment-offset: 0
+///   address: highest allowable: (~5U)
+inline Symbol &createAnonymousPointerJumpStub(LinkGraph &G,
+                                              Section &StubSection,
+                                              Symbol &PointerSymbol) {
+  auto &B =
+      G.createContentBlock(StubSection, PointerJumpStubContent, ~5ULL, 1, 0);
+  B.addEdge(Delta32, 2, PointerSymbol, -4);
+  return G.addAnonymousSymbol(B, 0, 6, true, false);
+}
+
 } // namespace x86_64
 } // end namespace jitlink
 } // end namespace llvm
index 93ea091..153ffef 100644 (file)
@@ -78,7 +78,7 @@ public:
     MemoryRegionInfo() = default;
 
     /// Constructor for symbols/sections with content.
-    MemoryRegionInfo(StringRef Content, JITTargetAddress TargetAddress)
+    MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress)
         : ContentPtr(Content.data()), Size(Content.size()),
           TargetAddress(TargetAddress) {}
 
@@ -93,7 +93,7 @@ public:
     }
 
     /// Set the content for this memory region.
-    void setContent(StringRef Content) {
+    void setContent(ArrayRef<char> Content) {
       assert(!ContentPtr && !Size && "Content/zero-fill already set");
       ContentPtr = Content.data();
       Size = Content.size();
@@ -106,9 +106,9 @@ public:
     }
 
     /// Returns the content for this section if there is any.
-    StringRef getContent() const {
+    ArrayRef<char> getContent() const {
       assert(!isZeroFill() && "Can't get content for a zero-fill section");
-      return StringRef(ContentPtr, static_cast<size_t>(Size));
+      return {ContentPtr, static_cast<size_t>(Size)};
     }
 
     /// Returns the zero-fill length for this section.
index 1cf84b6..c85e80b 100644 (file)
@@ -81,7 +81,9 @@ Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B,
     return Error::success();
   }
 
-  BinaryStreamReader BlockReader(B.getContent(), G.getEndianness());
+  BinaryStreamReader BlockReader(
+      StringRef(B.getContent().data(), B.getContent().size()),
+      G.getEndianness());
 
   while (true) {
     uint64_t RecordStartOffset = BlockReader.getOffset();
@@ -203,7 +205,9 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
     }
 
   CIEInfosMap CIEInfos;
-  BinaryStreamReader BlockReader(B.getContent(), PC.G.getEndianness());
+  BinaryStreamReader BlockReader(
+      StringRef(B.getContent().data(), B.getContent().size()),
+      PC.G.getEndianness());
   while (!BlockReader.empty()) {
     size_t RecordStartOffset = BlockReader.getOffset();
 
@@ -267,8 +271,10 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
 
   LLVM_DEBUG(dbgs() << "      Record is CIE\n");
 
-  auto RecordContent = B.getContent().substr(RecordOffset, RecordLength);
-  BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness());
+  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
+  BinaryStreamReader RecordReader(
+      StringRef(RecordContent.data(), RecordContent.size()),
+      PC.G.getEndianness());
 
   // Skip past the CIE delta field: we've already processed this far.
   RecordReader.setOffset(CIEDeltaFieldOffset + 4);
@@ -397,8 +403,10 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
 
   JITTargetAddress RecordAddress = B.getAddress() + RecordOffset;
 
-  auto RecordContent = B.getContent().substr(RecordOffset, RecordLength);
-  BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness());
+  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
+  BinaryStreamReader RecordReader(
+      StringRef(RecordContent.data(), RecordContent.size()),
+      PC.G.getEndianness());
 
   // Skip past the CIE delta field: we've already read this far.
   RecordReader.setOffset(CIEDeltaFieldOffset + 4);
@@ -730,7 +738,7 @@ Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
   return PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
 }
 
-char EHFrameNullTerminator::NullTerminatorBlockContent[] = {0, 0, 0, 0};
+char EHFrameNullTerminator::NullTerminatorBlockContent[4] = {0, 0, 0, 0};
 
 EHFrameNullTerminator::EHFrameNullTerminator(StringRef EHFrameSectionName)
     : EHFrameSectionName(EHFrameSectionName) {}
@@ -746,9 +754,8 @@ Error EHFrameNullTerminator::operator()(LinkGraph &G) {
            << EHFrameSectionName << "\n";
   });
 
-  auto &NullTerminatorBlock =
-      G.createContentBlock(*EHFrame, StringRef(NullTerminatorBlockContent, 4),
-                           0xfffffffffffffffc, 1, 0);
+  auto &NullTerminatorBlock = G.createContentBlock(
+      *EHFrame, NullTerminatorBlockContent, 0xfffffffffffffffc, 1, 0);
   G.addAnonymousSymbol(NullTerminatorBlock, 0, 4, false, true);
   return Error::success();
 }
index 17c537e..cc47d7a 100644 (file)
@@ -125,14 +125,13 @@ private:
     return *StubsSection;
   }
 
-  StringRef getGOTEntryBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(NullGOTEntryContent),
-                     sizeof(NullGOTEntryContent));
+  ArrayRef<char> getGOTEntryBlockContent() {
+    return {reinterpret_cast<const char *>(NullGOTEntryContent),
+            sizeof(NullGOTEntryContent)};
   }
 
-  StringRef getStubBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(StubContent),
-                     sizeof(StubContent));
+  ArrayRef<char> getStubBlockContent() {
+    return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
   }
 
   mutable Section *GOTSection = nullptr;
@@ -406,7 +405,7 @@ private:
         // for now everything is
         auto &section = G->createSection(*Name, Prot);
         // Do this here because we have it, but move it into graphify later
-        G->createContentBlock(section, StringRef(Data, Size), Address,
+        G->createContentBlock(section, ArrayRef<char>(Data, Size), Address,
                               Alignment, 0);
         if (SecRef.sh_type == ELF::SHT_SYMTAB)
           // TODO: Dynamic?
index 954423b..ad4346d 100644 (file)
@@ -193,12 +193,12 @@ Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex,
           ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(),
                                 B.getAlignment(), B.getAlignmentOffset())
           : createContentBlock(
-                B.getSection(), B.getContent().substr(0, SplitIndex),
+                B.getSection(), B.getContent().slice(0, SplitIndex),
                 B.getAddress(), B.getAlignment(), B.getAlignmentOffset());
 
   // Modify B to cover [ SplitIndex, B.size() ).
   B.setAddress(B.getAddress() + SplitIndex);
-  B.setContent(B.getContent().substr(SplitIndex));
+  B.setContent(B.getContent().slice(SplitIndex));
   B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) %
                        B.getAlignment());
 
index 63f862b..5e0f56e 100644 (file)
@@ -404,7 +404,7 @@ void JITLinkerBase::copyBlockContentToWorkingMemory(
       memcpy(BlockDataPtr, B->getContent().data(), B->getContent().size());
 
       // Point the block's content to the fixed up buffer.
-      B->setContent(StringRef(BlockDataPtr, B->getContent().size()));
+      B->setContent({BlockDataPtr, B->getContent().size()});
 
       // Update block end pointer.
       LastBlockEnd = BlockDataPtr + B->getContent().size();
index ccf286d..59db2ad 100644 (file)
@@ -178,11 +178,13 @@ Error MachOLinkGraphBuilder::createNormalizedSections() {
       Prot = static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
                                                        sys::Memory::MF_WRITE);
 
-    if (!isDebugSection(NSec))
+    if (!isDebugSection(NSec)) {
+      auto FullyQualifiedName =
+          G->allocateString(StringRef(NSec.SegName) + "," + NSec.SectName);
       NSec.GraphSection = &G->createSection(
-          G->allocateString(StringRef(NSec.SegName) + "," + NSec.SectName),
+          StringRef(FullyQualifiedName.data(), FullyQualifiedName.size()),
           Prot);
-    else
+    else
       LLVM_DEBUG({
         dbgs() << "    " << NSec.SegName << "," << NSec.SectName
                << " is a debug section: No graph section will be created.\n";
@@ -316,8 +318,8 @@ void MachOLinkGraphBuilder::addSectionStartSymAndBlock(
     Section &GraphSec, uint64_t Address, const char *Data, uint64_t Size,
     uint32_t Alignment, bool IsLive) {
   Block &B =
-      Data ? G->createContentBlock(GraphSec, StringRef(Data, Size), Address,
-                                   Alignment, 0)
+      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()) &&
@@ -508,8 +510,8 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
           NSec.Data
               ? G->createContentBlock(
                     *NSec.GraphSection,
-                    StringRef(NSec.Data + BlockOffset, BlockSize), BlockStart,
-                    NSec.Alignment, BlockStart % NSec.Alignment)
+                    ArrayRef<char>(NSec.Data + BlockOffset, BlockSize),
+                    BlockStart, NSec.Alignment, BlockStart % NSec.Alignment)
               : G->createZeroFillBlock(*NSec.GraphSection, BlockSize,
                                        BlockStart, NSec.Alignment,
                                        BlockStart % NSec.Alignment);
index 344334a..f71f6e2 100644 (file)
@@ -471,14 +471,13 @@ private:
     return *StubsSection;
   }
 
-  StringRef getGOTEntryBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(NullGOTEntryContent),
-                     sizeof(NullGOTEntryContent));
+  ArrayRef<char> getGOTEntryBlockContent() {
+    return {reinterpret_cast<const char *>(NullGOTEntryContent),
+            sizeof(NullGOTEntryContent)};
   }
 
-  StringRef getStubBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(StubContent),
-                     sizeof(StubContent));
+  ArrayRef<char> getStubBlockContent() {
+    return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
   }
 
   static const uint8_t NullGOTEntryContent[8];
index bd35f2d..7d7c0fd 100644 (file)
@@ -416,8 +416,6 @@ class PerGraphGOTAndPLTStubsBuilder_MachO_x86_64
     : public PerGraphGOTAndPLTStubsBuilder<
           PerGraphGOTAndPLTStubsBuilder_MachO_x86_64> {
 public:
-  static const uint8_t NullGOTEntryContent[8];
-  static const uint8_t StubContent[6];
 
   using PerGraphGOTAndPLTStubsBuilder<
       PerGraphGOTAndPLTStubsBuilder_MachO_x86_64>::
@@ -430,10 +428,7 @@ public:
   }
 
   Symbol &createGOTEntry(Symbol &Target) {
-    auto &GOTEntryBlock = G.createContentBlock(
-        getGOTSection(), getGOTEntryBlockContent(), 0, 8, 0);
-    GOTEntryBlock.addEdge(x86_64::Pointer64, 0, Target, 0);
-    return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
+    return x86_64::createAnonymousPointer(G, getGOTSection(), &Target);
   }
 
   void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
@@ -457,12 +452,8 @@ public:
   }
 
   Symbol &createPLTStub(Symbol &Target) {
-    auto &StubContentBlock =
-        G.createContentBlock(getStubsSection(), getStubBlockContent(), 0, 1, 0);
-    // Re-use GOT entries for stub targets.
-    auto &GOTEntrySymbol = getGOTEntry(Target);
-    StubContentBlock.addEdge(x86_64::Delta32, 2, GOTEntrySymbol, -4);
-    return G.addAnonymousSymbol(StubContentBlock, 0, 6, true, false);
+    return x86_64::createAnonymousPointerJumpStub(G, getStubsSection(),
+                                                  getGOTEntry(Target));
   }
 
   void fixPLTEdge(Edge &E, Symbol &Stub) {
@@ -493,25 +484,10 @@ private:
     return *StubsSection;
   }
 
-  StringRef getGOTEntryBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(NullGOTEntryContent),
-                     sizeof(NullGOTEntryContent));
-  }
-
-  StringRef getStubBlockContent() {
-    return StringRef(reinterpret_cast<const char *>(StubContent),
-                     sizeof(StubContent));
-  }
-
   Section *GOTSection = nullptr;
   Section *StubsSection = nullptr;
 };
 
-const uint8_t
-    PerGraphGOTAndPLTStubsBuilder_MachO_x86_64::NullGOTEntryContent[8] = {
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-const uint8_t PerGraphGOTAndPLTStubsBuilder_MachO_x86_64::StubContent[6] = {
-    0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
 } // namespace
 
 static Error optimizeMachO_x86_64_GOTAndStubs(LinkGraph &G) {
@@ -557,11 +533,8 @@ static Error optimizeMachO_x86_64_GOTAndStubs(LinkGraph &G) {
         }
       } else if (E.getKind() == x86_64::BranchPCRel32ToPtrJumpStubRelaxable) {
         auto &StubBlock = E.getTarget().getBlock();
-        assert(
-            StubBlock.getSize() ==
-                sizeof(
-                    PerGraphGOTAndPLTStubsBuilder_MachO_x86_64::StubContent) &&
-            "Stub block should be stub sized");
+        assert(StubBlock.getSize() == sizeof(x86_64::PointerJumpStubContent) &&
+               "Stub block should be stub sized");
         assert(StubBlock.edges_size() == 1 &&
                "Stub block should only have one outgoing edge");
 
index 261a956..c26ec3f 100644 (file)
@@ -53,6 +53,12 @@ const char *getEdgeKindName(Edge::Kind K) {
   }
 }
 
+const char NullPointerContent[8] = {0x00, 0x00, 0x00, 0x00,
+                                    0x00, 0x00, 0x00, 0x00};
+
+const char PointerJumpStubContent[6] = {
+    static_cast<char>(0xFF), 0x25, 0x00, 0x00, 0x00, 0x00};
+
 } // end namespace x86_64
 } // end namespace jitlink
 } // end namespace llvm
index a884863..a3005f7 100644 (file)
@@ -796,7 +796,7 @@ StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const {
     logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
     return StringRef();
   }
-  return SymInfo->getContent();
+  return {SymInfo->getContent().data(), SymInfo->getContent().size()};
 }
 
 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
index 3f222af..5efdff6 100644 (file)
@@ -164,7 +164,7 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
       FileInfo.SectionInfos[Sec.getName()] = {SecSize, SecAddr};
     else
       FileInfo.SectionInfos[Sec.getName()] = {
-          StringRef(FirstSym->getBlock().getContent().data(), SecSize),
+          ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
           SecAddr};
   }
 
index fc70934..7bd6bde 100644 (file)
@@ -159,7 +159,7 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
       FileInfo.SectionInfos[Sec.getName()] = {SecSize, SecAddr};
     else
       FileInfo.SectionInfos[Sec.getName()] = {
-          StringRef(FirstSym->getBlock().getContent().data(), SecSize),
+          ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
           SecAddr};
   }
 
index fb5fe42..739083d 100644 (file)
@@ -301,8 +301,9 @@ static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) {
       JITTargetAddress SymStart = Sym->getAddress();
       JITTargetAddress SymSize = Sym->getSize();
       JITTargetAddress SymEnd = SymStart + SymSize;
-      const uint8_t *SymData =
-          IsZeroFill ? nullptr : Sym->getSymbolContent().bytes_begin();
+      const uint8_t *SymData = IsZeroFill ? nullptr
+                                          : reinterpret_cast<const uint8_t *>(
+                                                Sym->getSymbolContent().data());
 
       // Pad any space before the symbol starts.
       while (NextAddr != SymStart) {
@@ -1214,7 +1215,7 @@ static Error loadObjects(Session &S) {
       return Err;
 
     // Register the absolute symbol with the session symbol infos.
-    S.SymbolInfos[Name] = { StringRef(), Addr };
+    S.SymbolInfos[Name] = {ArrayRef<char>(), Addr};
   }
 
   LLVM_DEBUG({
index 9199431..1d08b1f 100644 (file)
@@ -840,7 +840,7 @@ static int linkAndVerify() {
         char *CSymAddr = static_cast<char *>(SymAddr);
         StringRef SecContent = Dyld.getSectionContent(SectionID);
         uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
-        SymInfo.setContent(StringRef(CSymAddr, SymSize));
+        SymInfo.setContent(ArrayRef<char>(CSymAddr, SymSize));
       }
     }
     return SymInfo;
@@ -867,7 +867,8 @@ static int linkAndVerify() {
       return SectionID.takeError();
     RuntimeDyldChecker::MemoryRegionInfo SecInfo;
     SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID));
-    SecInfo.setContent(Dyld.getSectionContent(*SectionID));
+    StringRef SecContent = Dyld.getSectionContent(*SectionID);
+    SecInfo.setContent(ArrayRef<char>(SecContent.data(), SecContent.size()));
     return SecInfo;
   };
 
@@ -886,8 +887,10 @@ static int linkAndVerify() {
     RuntimeDyldChecker::MemoryRegionInfo StubMemInfo;
     StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) +
                                  SI.Offset);
+    StringRef SecContent =
+        Dyld.getSectionContent(SI.SectionID).substr(SI.Offset);
     StubMemInfo.setContent(
-        Dyld.getSectionContent(SI.SectionID).substr(SI.Offset));
+        ArrayRef<char>(SecContent.data(), SecContent.size()));
     return StubMemInfo;
   };
 
index 6e00550..a60a04e 100644 (file)
@@ -21,7 +21,7 @@ static auto RWFlags =
 static const char BlockContentBytes[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
                                          0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
                                          0x1C, 0x1D, 0x1E, 0x1F, 0x00};
-static StringRef BlockContent(BlockContentBytes);
+ArrayRef<char> BlockContent(BlockContentBytes);
 
 TEST(LinkGraphTest, Construction) {
   // Check that LinkGraph construction works as expected.
@@ -232,10 +232,10 @@ TEST(LinkGraphTest, SplitBlock) {
 
   // Check that the block addresses and content matches what we would expect.
   EXPECT_EQ(B1.getAddress(), 0x1008U);
-  EXPECT_EQ(B1.getContent(), BlockContent.substr(8));
+  EXPECT_EQ(B1.getContent(), BlockContent.slice(8));
 
   EXPECT_EQ(B2.getAddress(), 0x1000U);
-  EXPECT_EQ(B2.getContent(), BlockContent.substr(0, 8));
+  EXPECT_EQ(B2.getContent(), BlockContent.slice(0, 8));
 
   // Check that symbols in B1 were transferred as expected:
   // We expect S1 and S2 to have been transferred to B2, and S3 and S4 to have