Simplify decoupling between RuntimeDyld/RuntimeDyldChecker, add 'got_addr' util.

This patch reduces the number of functions in the interface between RuntimeDyld
and RuntimeDyldChecker by combining "GetXAddress" and "GetXContent" functions
into "GetXInfo" functions that return a struct describing both the address and
content. The GetStubOffset function is also replaced with a pair of utilities,
GetStubInfo and GetGOTInfo, that fit the new scheme. For RuntimeDyld both of
these functions will return the same result, but for the new JITLink linker
(https://reviews.llvm.org/D58704) these will provide the addresses of PLT stubs
and GOT entries respectively.

For JITLink's use, a 'got_addr' utility has been added to the rtdyld-check
language, and the syntax of 'got_addr' and 'stub_addr' has been changed: both
functions now take two arguments, a 'stub container name' and a target symbol
name. For llvm-rtdyld/RuntimeDyld the stub container name is the object file
name and section name, separated by a slash. E.g.:

rtdyld-check: *{8}(stub_addr(foo.o/__text, y)) = y

For the upcoming llvm-jitlink utility, which creates stubs on a per-file basis
rather than a per-section basis, the container name is just the file name. E.g.:

jitlink-check: *{8}(got_addr(foo.o, y)) = y
llvm-svn: 358295
diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index b866ca7..fde61ea 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -270,7 +270,6 @@
     outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
            << Alignment << ", SectionName = " << SectionName << ")\n";
 
-  dbgs() << "  Registering code section \"" << SectionName << "\"\n";
   if (SecIDMap)
     (*SecIDMap)[SectionName] = SectionID;
 
@@ -299,7 +298,6 @@
     outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
            << Alignment << ", SectionName = " << SectionName << ")\n";
 
-  dbgs() << "  Registering code section \"" << SectionName << "\"\n";
   if (SecIDMap)
     (*SecIDMap)[SectionName] = SectionID;
 
@@ -742,28 +740,39 @@
   TrivialMemoryManager MemMgr;
   doPreallocation(MemMgr);
 
-  using StubOffsets = StringMap<uint32_t>;
-  using SectionStubs = StringMap<StubOffsets>;
-  using FileStubs = StringMap<SectionStubs>;
+  struct StubID {
+    unsigned SectionID;
+    uint32_t Offset;
+  };
+  using StubInfos = StringMap<StubID>;
+  using StubContainers = StringMap<StubInfos>;
 
-  FileStubs StubMap;
+  StubContainers StubMap;
   RuntimeDyld Dyld(MemMgr, MemMgr);
   Dyld.setProcessAllSections(true);
 
-  Dyld.setNotifyStubEmitted(
-      [&StubMap](StringRef FilePath, StringRef SectionName,
-                 StringRef SymbolName, uint32_t StubOffset) {
-        StubMap[sys::path::filename(FilePath)][SectionName][SymbolName] =
-          StubOffset;
-      });
+  Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath,
+                                       StringRef SectionName,
+                                       StringRef SymbolName, unsigned SectionID,
+                                       uint32_t StubOffset) {
+    std::string ContainerName =
+        (sys::path::filename(FilePath) + "/" + SectionName).str();
+    StubMap[ContainerName][SymbolName] = {SectionID, StubOffset};
+  });
 
-  auto GetSymbolAddress =
-    [&Dyld, &MemMgr](StringRef Symbol) -> Expected<JITTargetAddress> {
-      if (auto InternalSymbol = Dyld.getSymbol(Symbol))
-        return InternalSymbol.getAddress();
+  auto GetSymbolInfo =
+      [&Dyld, &MemMgr](
+          StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
+    RuntimeDyldChecker::MemoryRegionInfo SymInfo;
 
+    // First get the target address.
+    if (auto InternalSymbol = Dyld.getSymbol(Symbol))
+      SymInfo.TargetAddress = InternalSymbol.getAddress();
+    else {
+      // Symbol not found in RuntimeDyld. Fall back to external lookup.
 #ifdef _MSC_VER
-      using ExpectedLookupResult = MSVCPExpected<JITSymbolResolver::LookupResult>;
+      using ExpectedLookupResult =
+          MSVCPExpected<JITSymbolResolver::LookupResult>;
 #else
       using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
 #endif
@@ -771,11 +780,10 @@
       auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
       auto ResultF = ResultP->get_future();
 
-      MemMgr.lookup(
-        JITSymbolResolver::LookupSet({Symbol}),
-        [=](Expected<JITSymbolResolver::LookupResult> Result) {
-          ResultP->set_value(std::move(Result));
-        });
+      MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}),
+                    [=](Expected<JITSymbolResolver::LookupResult> Result) {
+                      ResultP->set_value(std::move(Result));
+                    });
 
       auto Result = ResultF.get();
       if (!Result)
@@ -784,61 +792,67 @@
       auto I = Result->find(Symbol);
       assert(I != Result->end() &&
              "Expected symbol address if no error occurred");
-      return I->second.getAddress();
-    };
+      SymInfo.TargetAddress = I->second.getAddress();
+    }
 
-  auto IsSymbolValid =
-    [&Dyld, GetSymbolAddress](StringRef Symbol) {
-      if (Dyld.getSymbol(Symbol))
-        return true;
-      auto Addr = GetSymbolAddress(Symbol);
-      if (!Addr) {
-        logAllUnhandledErrors(Addr.takeError(), errs(), "RTDyldChecker: ");
-        return false;
+    // Now find the symbol content if possible (otherwise leave content as a
+    // default-constructed StringRef).
+    if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) {
+      unsigned SectionID = Dyld.getSymbolSectionID(Symbol);
+      if (SectionID != ~0U) {
+        char *CSymAddr = static_cast<char *>(SymAddr);
+        StringRef SecContent = Dyld.getSectionContent(SectionID);
+        uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
+        SymInfo.Content = StringRef(CSymAddr, SymSize);
       }
-      return *Addr != 0;
-    };
+    }
+    return SymInfo;
+  };
+
+  auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) {
+    if (Dyld.getSymbol(Symbol))
+      return true;
+    auto SymInfo = GetSymbolInfo(Symbol);
+    if (!SymInfo) {
+      logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
+      return false;
+    }
+    return SymInfo->TargetAddress != 0;
+  };
 
   FileToSectionIDMap FileToSecIDMap;
 
-  auto GetSectionAddress =
-    [&Dyld, &FileToSecIDMap](StringRef FileName, StringRef SectionName) {
-      unsigned SectionID =
-        ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
-      return Dyld.getSectionLoadAddress(SectionID);
-    };
+  auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName,
+                                                 StringRef SectionName)
+      -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
+    auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName);
+    if (!SectionID)
+      return SectionID.takeError();
+    RuntimeDyldChecker::MemoryRegionInfo SecInfo;
+    SecInfo.TargetAddress = Dyld.getSectionLoadAddress(*SectionID);
+    SecInfo.Content = Dyld.getSectionContent(*SectionID);
+    return SecInfo;
+  };
 
-  auto GetSectionContent =
-    [&Dyld, &FileToSecIDMap](StringRef FileName, StringRef SectionName) {
-      unsigned SectionID =
-        ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
-      return Dyld.getSectionContent(SectionID);
-    };
-
-
-  auto GetSymbolContents =
-    [&Dyld](StringRef Symbol) {
-      auto *SymAddr = static_cast<char*>(Dyld.getSymbolLocalAddress(Symbol));
-      if (!SymAddr)
-        return StringRef();
-      unsigned SectionID = Dyld.getSymbolSectionID(Symbol);
-      if (SectionID == ~0U)
-        return StringRef();
-      StringRef SecContent = Dyld.getSectionContent(SectionID);
-      uint64_t SymSize = SecContent.size() - (SymAddr - SecContent.data());
-      return StringRef(SymAddr, SymSize);
-    };
-
-  auto GetStubOffset =
-    [&StubMap](StringRef FileName, StringRef SectionName, StringRef SymbolName) -> Expected<uint32_t> {
-      if (!StubMap.count(FileName))
-        return make_error<StringError>("File name not found", inconvertibleErrorCode());
-      if (!StubMap[FileName].count(SectionName))
-        return make_error<StringError>("Section name not found", inconvertibleErrorCode());
-      if (!StubMap[FileName][SectionName].count(SymbolName))
-        return make_error<StringError>("Symbol name not found", inconvertibleErrorCode());
-      return StubMap[FileName][SectionName][SymbolName];
-    };
+  auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer,
+                                       StringRef SymbolName)
+      -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
+    if (!StubMap.count(StubContainer))
+      return make_error<StringError>("Stub container not found: " +
+                                         StubContainer,
+                                     inconvertibleErrorCode());
+    if (!StubMap[StubContainer].count(SymbolName))
+      return make_error<StringError>("Symbol name " + SymbolName +
+                                         " in stub container " + StubContainer,
+                                     inconvertibleErrorCode());
+    auto &SI = StubMap[StubContainer][SymbolName];
+    RuntimeDyldChecker::MemoryRegionInfo StubMemInfo;
+    StubMemInfo.TargetAddress =
+        Dyld.getSectionLoadAddress(SI.SectionID) + SI.Offset;
+    StubMemInfo.Content =
+        Dyld.getSectionContent(SI.SectionID).substr(SI.Offset);
+    return StubMemInfo;
+  };
 
   // We will initialize this below once we have the first object file and can
   // know the endianness.
@@ -869,19 +883,12 @@
     ObjectFile &Obj = **MaybeObj;
 
     if (!Checker)
-      Checker =
-        llvm::make_unique<RuntimeDyldChecker>(IsSymbolValid, GetSymbolAddress,
-                                              GetSymbolContents,
-                                              GetSectionAddress,
-                                              GetSectionContent, GetStubOffset,
-                                              Obj.isLittleEndian()
-                                                ? support::little
-                                                : support::big,
-                                              Disassembler.get(),
-                                              InstPrinter.get(), dbgs());
+      Checker = llvm::make_unique<RuntimeDyldChecker>(
+          IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
+          GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
+          Disassembler.get(), InstPrinter.get(), dbgs());
 
     auto FileName = sys::path::filename(InputFile);
-    dbgs() << "In " << FileName << ":\n";
     MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);
 
     // Load the object file