llvm.org GIT mirror llvm / b18a506
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360547 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 1 year, 6 months ago
7 changed file(s) with 132 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
7272 ///
7373 class RuntimeDyldChecker {
7474 public:
75 struct MemoryRegionInfo {
76 StringRef Content;
77 JITTargetAddress TargetAddress;
75 class MemoryRegionInfo {
76 public:
77 MemoryRegionInfo() = default;
78
79 /// Constructor for symbols/sections with content.
80 MemoryRegionInfo(StringRef Content, JITTargetAddress TargetAddress)
81 : ContentPtr(Content.data()), Size(Content.size()),
82 TargetAddress(TargetAddress) {}
83
84 /// Constructor for zero-fill symbols/sections.
85 MemoryRegionInfo(uint64_t Size, JITTargetAddress TargetAddress)
86 : Size(Size), TargetAddress(TargetAddress) {}
87
88 /// Returns true if this is a zero-fill symbol/section.
89 bool isZeroFill() const {
90 assert(Size && "setContent/setZeroFill must be called first");
91 return !ContentPtr;
92 }
93
94 /// Set the content for this memory region.
95 void setContent(StringRef Content) {
96 assert(!ContentPtr && !Size && "Content/zero-fill already set");
97 ContentPtr = Content.data();
98 Size = Content.size();
99 }
100
101 /// Set a zero-fill length for this memory region.
102 void setZeroFill(uint64_t Size) {
103 assert(!ContentPtr && !this->Size && "Content/zero-fill already set");
104 this->Size = Size;
105 }
106
107 /// Returns the content for this section if there is any.
108 StringRef getContent() const {
109 assert(!isZeroFill() && "Can't get content for a zero-fill section");
110 return StringRef(ContentPtr, static_cast(Size));
111 }
112
113 /// Returns the zero-fill length for this section.
114 uint64_t getZeroFillLength() const {
115 assert(isZeroFill() && "Can't get zero-fill length for content section");
116 return Size;
117 }
118
119 /// Set the target address for this region.
120 void setTargetAddress(JITTargetAddress TargetAddress) {
121 assert(!this->TargetAddress && "TargetAddress already set");
122 this->TargetAddress = TargetAddress;
123 }
124
125 /// Return the target address for this region.
126 JITTargetAddress getTargetAddress() const { return TargetAddress; }
127
128 private:
129 const char *ContentPtr = 0;
130 uint64_t Size = 0;
131 JITTargetAddress TargetAddress = 0;
78132 };
79133
80134 using IsSymbolValidFunction = std::function;
6161 }
6262
6363 MachOSection &setZeroFill(uint64_t Size) {
64 assert(!ContentPtr && !Size && "Content/zeroFill already set");
64 assert(!ContentPtr && !this->Size && "Content/zeroFill already set");
6565 this->Size = Size;
6666 return *this;
6767 }
525525
526526 uint64_t LoadAddr = LoadAddrExprResult.getValue();
527527
528 // If there is no error but the content pointer is null then this is a
529 // zero-fill symbol/section.
530 if (LoadAddr == 0)
531 return std::make_pair(0, RemainingExpr);
532
528533 return std::make_pair(
529534 EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
530535 RemainingExpr);
734739 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
735740 return 0;
736741 }
742
743 if (SymInfo->isZeroFill())
744 return 0;
745
737746 return static_cast(
738 reinterpret_cast(SymInfo->Content.data()));
747 reinterpret_cast(SymInfo->getContent().data()));
739748 }
740749
741750 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
745754 return 0;
746755 }
747756
748 return SymInfo->TargetAddress;
757 return SymInfo->getTargetAddress();
749758 }
750759
751760 uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
773782 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
774783 return StringRef();
775784 }
776 return SymInfo->Content;
785 return SymInfo->getContent();
777786 }
778787
779788 std::pair RuntimeDyldCheckerImpl::getSectionAddr(
795804
796805 uint64_t Addr = 0;
797806
798 if (IsInsideLoad)
799 Addr = pointerToJITTargetAddress(SecInfo->Content.data());
800 else
801 Addr = SecInfo->TargetAddress;
807 if (IsInsideLoad) {
808 if (SecInfo->isZeroFill())
809 Addr = 0;
810 else
811 Addr = pointerToJITTargetAddress(SecInfo->getContent().data());
812 } else
813 Addr = SecInfo->getTargetAddress();
802814
803815 return std::make_pair(Addr, "");
804816 }
822834
823835 uint64_t Addr = 0;
824836
825 if (IsInsideLoad)
826 Addr = pointerToJITTargetAddress(StubInfo->Content.data());
827 else
828 Addr = StubInfo->TargetAddress;
837 if (IsInsideLoad) {
838 if (StubInfo->isZeroFill())
839 return std::make_pair((uint64_t)0, "Detected zero-filled stub/GOT entry");
840 Addr = pointerToJITTargetAddress(StubInfo->getContent().data());
841 } else
842 Addr = StubInfo->getTargetAddress();
829843
830844 return std::make_pair(Addr, "");
831845 }
271271 .section __DATA,__nds_test_sect,regular,no_dead_strip
272272 .quad 0
273273
274 # Check that explicit zero-fill symbols are supported
275 # jitlink-check: *{8}zero_fill_test = 0
276 .globl zero_fill_test
277 .zerofill __DATA,__zero_fill_test,zero_fill_test,8,3
278
274279 .subsections_via_symbols
55 //
66 //===----------------------------------------------------------------------===//
77 //
8 // .
8 // MachO parsing support for llvm-jitlink.
99 //
1010 //===----------------------------------------------------------------------===//
1111
104104 bool isGOTSection = isMachOGOTSection(Sec);
105105 bool isStubsSection = isMachOStubsSection(Sec);
106106
107 auto &SectionInfo = FileInfo.SectionInfos[Sec.getName()];
108
109107 auto *FirstAtom = *Sec.atoms().begin();
110108 auto *LastAtom = FirstAtom;
111109 for (auto *DA : Sec.atoms()) {
114112 if (DA->getAddress() > LastAtom->getAddress())
115113 LastAtom = DA;
116114 if (isGOTSection) {
115 if (Sec.isZeroFill())
116 return make_error("Content atom in zero-fill section",
117 inconvertibleErrorCode());
118
117119 if (auto TA = getMachOGOTTarget(G, *DA)) {
118120 FileInfo.GOTEntryInfos[TA->getName()] = {DA->getContent(),
119121 DA->getAddress()};
120122 } else
121123 return TA.takeError();
122124 } else if (isStubsSection) {
125 if (Sec.isZeroFill())
126 return make_error("Content atom in zero-fill section",
127 inconvertibleErrorCode());
128
123129 if (auto TA = getMachOStubTarget(G, *DA))
124130 FileInfo.StubInfos[TA->getName()] = {DA->getContent(),
125131 DA->getAddress()};
126132 else
127133 return TA.takeError();
128 } else if (DA->hasName() && DA->isGlobal())
129 S.SymbolInfos[DA->getName()] = {DA->getContent(), DA->getAddress()};
134 } else if (DA->hasName() && DA->isGlobal()) {
135 if (DA->isZeroFill())
136 S.SymbolInfos[DA->getName()] = {DA->getSize(), DA->getAddress()};
137 else {
138 if (Sec.isZeroFill())
139 return make_error("Content atom in zero-fill section",
140 inconvertibleErrorCode());
141 S.SymbolInfos[DA->getName()] = {DA->getContent(), DA->getAddress()};
142 }
143 }
130144 }
131 const char *StartAddr = FirstAtom->getContent().data();
132 const char *EndAddr =
133 LastAtom->getContent().data() + LastAtom->getContent().size();
134 SectionInfo.TargetAddress = FirstAtom->getAddress();
135 SectionInfo.Content = StringRef(StartAddr, EndAddr - StartAddr);
145
146 JITTargetAddress SecAddr = FirstAtom->getAddress();
147 uint64_t SecSize = (LastAtom->getAddress() + LastAtom->getSize()) -
148 FirstAtom->getAddress();
149
150 if (Sec.isZeroFill())
151 FileInfo.SectionInfos[Sec.getName()] = {SecSize, SecAddr};
152 else
153 FileInfo.SectionInfos[Sec.getName()] = {
154 StringRef(FirstAtom->getContent().data(), SecSize), SecAddr};
136155 }
137156
138157 return Error::success();
103103
104104 static raw_ostream &
105105 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
106 return OS << "target addr = " << format("0x%016" PRIx64, MRI.TargetAddress)
107 << ", content: " << (const void *)MRI.Content.data() << " -- "
108 << (const void *)(MRI.Content.data() + MRI.Content.size()) << " ("
109 << MRI.Content.size() << " bytes)";
106 return OS << "target addr = "
107 << format("0x%016" PRIx64, MRI.getTargetAddress())
108 << ", content: " << (const void *)MRI.getContent().data() << " -- "
109 << (const void *)(MRI.getContent().data() + MRI.getContent().size())
110 << " (" << MRI.getContent().size() << " bytes)";
110111 }
111112
112113 static raw_ostream &
773773
774774 // First get the target address.
775775 if (auto InternalSymbol = Dyld.getSymbol(Symbol))
776 SymInfo.TargetAddress = InternalSymbol.getAddress();
776 SymInfo.setTargetAddress(InternalSymbol.getAddress());
777777 else {
778778 // Symbol not found in RuntimeDyld. Fall back to external lookup.
779779 #ifdef _MSC_VER
798798 auto I = Result->find(Symbol);
799799 assert(I != Result->end() &&
800800 "Expected symbol address if no error occurred");
801 SymInfo.TargetAddress = I->second.getAddress();
801 SymInfo.setTargetAddress(I->second.getAddress());
802802 }
803803
804804 // Now find the symbol content if possible (otherwise leave content as a
809809 char *CSymAddr = static_cast(SymAddr);
810810 StringRef SecContent = Dyld.getSectionContent(SectionID);
811811 uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
812 SymInfo.Content = StringRef(CSymAddr, SymSize);
812 SymInfo.setContent(StringRef(CSymAddr, SymSize));
813813 }
814814 }
815815 return SymInfo;
823823 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
824824 return false;
825825 }
826 return SymInfo->TargetAddress != 0;
826 return SymInfo->getTargetAddress() != 0;
827827 };
828828
829829 FileToSectionIDMap FileToSecIDMap;
835835 if (!SectionID)
836836 return SectionID.takeError();
837837 RuntimeDyldChecker::MemoryRegionInfo SecInfo;
838 SecInfo.TargetAddress = Dyld.getSectionLoadAddress(*SectionID);
839 SecInfo.Content = Dyld.getSectionContent(*SectionID);
838 SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID));
839 SecInfo.setContent(Dyld.getSectionContent(*SectionID));
840840 return SecInfo;
841841 };
842842
853853 inconvertibleErrorCode());
854854 auto &SI = StubMap[StubContainer][SymbolName];
855855 RuntimeDyldChecker::MemoryRegionInfo StubMemInfo;
856 StubMemInfo.TargetAddress =
857 Dyld.getSectionLoadAddress(SI.SectionID) + SI.Offset;
858 StubMemInfo.Content =
859 Dyld.getSectionContent(SI.SectionID).substr(SI.Offset);
856 StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) +
857 SI.Offset);
858 StubMemInfo.setContent(
859 Dyld.getSectionContent(SI.SectionID).substr(SI.Offset));
860860 return StubMemInfo;
861861 };
862862