[JITLink] Add a test for zero-filled content.

Also updates RuntimeDyldChecker and llvm-rtdyld to support zero-fill tests by
returning a content address of zero (but no error) for zero-fill atoms, and
treating loads from zero as returning zero.

llvm-svn: 360547
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
index c3a1242..067c38a 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// .
+// MachO parsing support for llvm-jitlink.
 //
 //===----------------------------------------------------------------------===//
 
@@ -105,8 +105,6 @@
     bool isGOTSection = isMachOGOTSection(Sec);
     bool isStubsSection = isMachOStubsSection(Sec);
 
-    auto &SectionInfo = FileInfo.SectionInfos[Sec.getName()];
-
     auto *FirstAtom = *Sec.atoms().begin();
     auto *LastAtom = FirstAtom;
     for (auto *DA : Sec.atoms()) {
@@ -115,25 +113,46 @@
       if (DA->getAddress() > LastAtom->getAddress())
         LastAtom = DA;
       if (isGOTSection) {
+        if (Sec.isZeroFill())
+          return make_error<StringError>("Content atom in zero-fill section",
+                                         inconvertibleErrorCode());
+
         if (auto TA = getMachOGOTTarget(G, *DA)) {
           FileInfo.GOTEntryInfos[TA->getName()] = {DA->getContent(),
                                                    DA->getAddress()};
         } else
           return TA.takeError();
       } else if (isStubsSection) {
+        if (Sec.isZeroFill())
+          return make_error<StringError>("Content atom in zero-fill section",
+                                         inconvertibleErrorCode());
+
         if (auto TA = getMachOStubTarget(G, *DA))
           FileInfo.StubInfos[TA->getName()] = {DA->getContent(),
                                                DA->getAddress()};
         else
           return TA.takeError();
-      } else if (DA->hasName() && DA->isGlobal())
-        S.SymbolInfos[DA->getName()] = {DA->getContent(), DA->getAddress()};
+      } else if (DA->hasName() && DA->isGlobal()) {
+        if (DA->isZeroFill())
+          S.SymbolInfos[DA->getName()] = {DA->getSize(), DA->getAddress()};
+        else {
+          if (Sec.isZeroFill())
+            return make_error<StringError>("Content atom in zero-fill section",
+                                           inconvertibleErrorCode());
+          S.SymbolInfos[DA->getName()] = {DA->getContent(), DA->getAddress()};
+        }
+      }
     }
-    const char *StartAddr = FirstAtom->getContent().data();
-    const char *EndAddr =
-        LastAtom->getContent().data() + LastAtom->getContent().size();
-    SectionInfo.TargetAddress = FirstAtom->getAddress();
-    SectionInfo.Content = StringRef(StartAddr, EndAddr - StartAddr);
+
+    JITTargetAddress SecAddr = FirstAtom->getAddress();
+    uint64_t SecSize = (LastAtom->getAddress() + LastAtom->getSize()) -
+                       FirstAtom->getAddress();
+
+    if (Sec.isZeroFill())
+      FileInfo.SectionInfos[Sec.getName()] = {SecSize, SecAddr};
+    else
+      FileInfo.SectionInfos[Sec.getName()] = {
+          StringRef(FirstAtom->getContent().data(), SecSize), SecAddr};
   }
 
   return Error::success();
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 5ecf66a..97956f6 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -104,10 +104,11 @@
 
 static raw_ostream &
 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
-  return OS << "target addr = " << format("0x%016" PRIx64, MRI.TargetAddress)
-            << ", content: " << (const void *)MRI.Content.data() << " -- "
-            << (const void *)(MRI.Content.data() + MRI.Content.size()) << " ("
-            << MRI.Content.size() << " bytes)";
+  return OS << "target addr = "
+            << format("0x%016" PRIx64, MRI.getTargetAddress())
+            << ", content: " << (const void *)MRI.getContent().data() << " -- "
+            << (const void *)(MRI.getContent().data() + MRI.getContent().size())
+            << " (" << MRI.getContent().size() << " bytes)";
 }
 
 static raw_ostream &