diff options
author | Lang Hames <lhames@gmail.com> | 2019-04-12 18:07:28 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2019-04-12 18:07:28 +0000 |
commit | c7c1f21525f88d8efd13a01ece50504d10d012fa (patch) | |
tree | 473ddd29ee4bcf989024e40101cd1775a1769f73 | |
parent | e4d6ac5d19401fdd34642df5c015b4ab07f6beb0 (diff) | |
download | bcm5719-llvm-c7c1f21525f88d8efd13a01ece50504d10d012fa.tar.gz bcm5719-llvm-c7c1f21525f88d8efd13a01ece50504d10d012fa.zip |
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
23 files changed, 242 insertions, 271 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index 2d5420f194a..b2b4eba4707 100644 --- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -61,10 +61,9 @@ protected: void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: - - using NotifyStubEmittedFunction = - std::function<void(StringRef FileName, StringRef SectionName, - StringRef SymbolName, uint32_t StubOffset)>; + using NotifyStubEmittedFunction = std::function<void( + StringRef FileName, StringRef SectionName, StringRef SymbolName, + unsigned SectionID, uint32_t StubOffset)>; /// Information about the loaded object. class LoadedObjectInfo : public llvm::LoadedObjectInfo { diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index 57193fb45c8..2897c8ebca8 100644 --- a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -60,7 +60,8 @@ class raw_ostream; /// /// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')' /// | 'next_pc' '(' symbol ')' -/// | 'stub_addr' '(' file-name ',' section-name ',' symbol ')' +/// | 'stub_addr' '(' stub-container-name ',' symbol ')' +/// | 'got_addr' '(' stub-container-name ',' symbol ')' /// | symbol /// /// binary_expr = expr '+' expr @@ -72,32 +73,29 @@ class raw_ostream; /// class RuntimeDyldChecker { public: + struct MemoryRegionInfo { + StringRef Content; + JITTargetAddress TargetAddress; + }; using IsSymbolValidFunction = std::function<bool(StringRef Symbol)>; - using GetSymbolAddressFunction = - std::function<Expected<JITTargetAddress>(StringRef Symbol)>; - using GetSymbolContentFunction = - std::function<Expected<StringRef>(StringRef Symbol)>; - using GetSectionLoadAddressFunction = - std::function<Optional<JITTargetAddress>(StringRef FileName, - StringRef SectionName)>; - using GetSectionContentFunction = - std::function<Expected<StringRef>(StringRef FileName, - StringRef SectionName)>; - using GetStubOffsetInSectionFunction = - std::function<Expected<uint32_t>(StringRef FileName, - StringRef SectionName, - StringRef SymbolName)>; + using GetSymbolInfoFunction = + std::function<Expected<MemoryRegionInfo>(StringRef SymbolName)>; + using GetSectionInfoFunction = std::function<Expected<MemoryRegionInfo>( + StringRef FileName, StringRef SectionName)>; + using GetStubInfoFunction = std::function<Expected<MemoryRegionInfo>( + StringRef StubContainer, StringRef TargetName)>; + using GetGOTInfoFunction = std::function<Expected<MemoryRegionInfo>( + StringRef GOTContainer, StringRef TargetName)>; RuntimeDyldChecker(IsSymbolValidFunction IsSymbolValid, - GetSymbolAddressFunction GetSymbolAddress, - GetSymbolContentFunction GetSymbolContent, - GetSectionLoadAddressFunction GetSectionLoadAddresss, - GetSectionContentFunction GetSectionContent, - GetStubOffsetInSectionFunction GetStubOffsetInSection, + GetSymbolInfoFunction GetSymbolInfo, + GetSectionInfoFunction GetSectionInfo, + GetStubInfoFunction GetStubInfo, + GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, - MCDisassembler *Disassembler, - MCInstPrinter *InstPrinter, raw_ostream &ErrStream); + MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, + raw_ostream &ErrStream); ~RuntimeDyldChecker(); /// Check a single expression against the attached RuntimeDyld diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index dee8ecda13a..2fd677ab13a 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -386,7 +386,8 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // If this is a named stub, just call NotifyStubEmitted. if (VR.SymbolName) { - NotifyStubEmitted(FileName, SectionName, VR.SymbolName, StubAddr); + NotifyStubEmitted(FileName, SectionName, VR.SymbolName, SectionID, + StubAddr); continue; } @@ -396,7 +397,8 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { auto &GSTEntry = GSTMapEntry.second; if (GSTEntry.getSectionID() == VR.SectionID && GSTEntry.getOffset() == VR.Offset) { - NotifyStubEmitted(FileName, SectionName, SymbolName, StubAddr); + NotifyStubEmitted(FileName, SectionName, SymbolName, SectionID, + StubAddr); break; } } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 3a293c0cda4..e801ebd1cde 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -319,22 +319,22 @@ private: return std::make_pair(EvalResult(NextPC), RemainingExpr); } - // Evaluate a call to stub_addr. + // Evaluate a call to stub_addr/got_addr. // Look up and return the address of the stub for the given // (<file name>, <section name>, <symbol name>) tuple. // On success, returns a pair containing the stub address, plus the expression // remaining to be evaluated. - std::pair<EvalResult, StringRef> evalStubAddr(StringRef Expr, - ParseContext PCtx) const { + std::pair<EvalResult, StringRef> + evalStubOrGOTAddr(StringRef Expr, ParseContext PCtx, bool IsStubAddr) const { if (!Expr.startswith("(")) return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), ""); StringRef RemainingExpr = Expr.substr(1).ltrim(); // Handle file-name specially, as it may contain characters that aren't // legal for symbols. - StringRef FileName; + StringRef StubContainerName; size_t ComaIdx = RemainingExpr.find(','); - FileName = RemainingExpr.substr(0, ComaIdx).rtrim(); + StubContainerName = RemainingExpr.substr(0, ComaIdx).rtrim(); RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim(); if (!RemainingExpr.startswith(",")) @@ -342,14 +342,6 @@ private: unexpectedToken(RemainingExpr, Expr, "expected ','"), ""); RemainingExpr = RemainingExpr.substr(1).ltrim(); - StringRef SectionName; - std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr); - - if (!RemainingExpr.startswith(",")) - return std::make_pair( - unexpectedToken(RemainingExpr, Expr, "expected ','"), ""); - RemainingExpr = RemainingExpr.substr(1).ltrim(); - StringRef Symbol; std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr); @@ -360,8 +352,8 @@ private: uint64_t StubAddr; std::string ErrorMsg = ""; - std::tie(StubAddr, ErrorMsg) = Checker.getStubAddrFor( - FileName, SectionName, Symbol, PCtx.IsInsideLoad); + std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor( + StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr); if (ErrorMsg != "") return std::make_pair(EvalResult(ErrorMsg), ""); @@ -421,7 +413,9 @@ private: else if (Symbol == "next_pc") return evalNextPC(RemainingExpr, PCtx); else if (Symbol == "stub_addr") - return evalStubAddr(RemainingExpr, PCtx); + return evalStubOrGOTAddr(RemainingExpr, PCtx, true); + else if (Symbol == "got_addr") + return evalStubOrGOTAddr(RemainingExpr, PCtx, false); else if (Symbol == "section_addr") return evalSectionAddr(RemainingExpr, PCtx); @@ -676,22 +670,15 @@ private: } RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl( - IsSymbolValidFunction IsSymbolValid, - GetSymbolAddressFunction GetSymbolAddress, - GetSymbolContentFunction GetSymbolContent, - GetSectionLoadAddressFunction GetSectionLoadAddress, - GetSectionContentFunction GetSectionContent, - GetStubOffsetInSectionFunction GetStubOffsetInSection, - support::endianness Endianness, - MCDisassembler *Disassembler, - MCInstPrinter *InstPrinter, - raw_ostream &ErrStream) + IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, + GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, + GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, + MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, + raw_ostream &ErrStream) : IsSymbolValid(std::move(IsSymbolValid)), - GetSymbolAddress(std::move(GetSymbolAddress)), - GetSymbolContent(std::move(GetSymbolContent)), - GetSectionLoadAddress(std::move(GetSectionLoadAddress)), - GetSectionContent(std::move(GetSectionContent)), - GetStubOffsetInSection(std::move(GetStubOffsetInSection)), + GetSymbolInfo(std::move(GetSymbolInfo)), + GetSectionInfo(std::move(GetSectionInfo)), + GetStubInfo(std::move(GetStubInfo)), GetGOTInfo(std::move(GetGOTInfo)), Endianness(Endianness), Disassembler(Disassembler), InstPrinter(InstPrinter), ErrStream(ErrStream) {} @@ -743,22 +730,23 @@ bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const { } uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const { - auto Contents = GetSymbolContent(Symbol); - if (!Contents) { - logAllUnhandledErrors(Contents.takeError(), errs(), "RTDyldChecker: "); + auto SymInfo = GetSymbolInfo(Symbol); + if (!SymInfo) { + logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); return 0; } - return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Contents->data())); + return static_cast<uint64_t>( + reinterpret_cast<uintptr_t>(SymInfo->Content.data())); } uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const { - auto Addr = GetSymbolAddress(Symbol); - if (!Addr) { - logAllUnhandledErrors(Addr.takeError(), errs(), "RTDyldChecker: "); + auto SymInfo = GetSymbolInfo(Symbol); + if (!SymInfo) { + logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); return 0; } - return *Addr; + return SymInfo->TargetAddress; } uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr, @@ -781,87 +769,79 @@ uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr, } StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const { - auto Content = GetSymbolContent(Symbol); - if (!Content) { - logAllUnhandledErrors(Content.takeError(), errs(), "RTDyldChecker: "); + auto SymInfo = GetSymbolInfo(Symbol); + if (!SymInfo) { + logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); return StringRef(); } - return *Content; + return SymInfo->Content; } std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr( StringRef FileName, StringRef SectionName, bool IsInsideLoad) const { - uint64_t Addr = 0; - std::string ErrMsg; - - // If this address is being looked up in "load" mode, return the content - // pointer. - if (IsInsideLoad) { - if (auto Content = GetSectionContent(FileName, SectionName)) - Addr = pointerToJITTargetAddress(Content->data()); - else { + auto SecInfo = GetSectionInfo(FileName, SectionName); + if (!SecInfo) { + std::string ErrMsg; + { raw_string_ostream ErrMsgStream(ErrMsg); - logAllUnhandledErrors(Content.takeError(), ErrMsgStream, + logAllUnhandledErrors(SecInfo.takeError(), ErrMsgStream, "RTDyldChecker: "); } - return std::make_pair(Addr, std::move(ErrMsg)); + return std::make_pair(0, std::move(ErrMsg)); } - // ... otherwise return the target pointer. - if (auto LoadAddr = GetSectionLoadAddress(FileName, SectionName)) - Addr = *LoadAddr; - else - return std::make_pair(Addr, ("Section (" + FileName + ", " + - SectionName + ") does not exist").str()); + // If this address is being looked up in "load" mode, return the content + // pointer, otherwise return the target address. - return std::make_pair(Addr, std::move(ErrMsg)); -} + uint64_t Addr = 0; -std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor( - StringRef FileName, StringRef SectionName, StringRef SymbolName, - bool IsInsideLoad) const { + if (IsInsideLoad) + Addr = pointerToJITTargetAddress(SecInfo->Content.data()); + else + Addr = SecInfo->TargetAddress; - auto SectionAddr = getSectionAddr(FileName, SectionName, IsInsideLoad); + return std::make_pair(Addr, ""); +} - if (!SectionAddr.second.empty()) - return SectionAddr; +std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor( + StringRef StubContainerName, StringRef SymbolName, bool IsInsideLoad, + bool IsStubAddr) const { - auto StubOffset = GetStubOffsetInSection(FileName, SectionName, SymbolName); + auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName) + : GetGOTInfo(StubContainerName, SymbolName); - if (!StubOffset) { + if (!StubInfo) { std::string ErrMsg; { raw_string_ostream ErrMsgStream(ErrMsg); - logAllUnhandledErrors(StubOffset.takeError(), ErrMsgStream, + logAllUnhandledErrors(StubInfo.takeError(), ErrMsgStream, "RTDyldChecker: "); } return std::make_pair((uint64_t)0, std::move(ErrMsg)); } - return std::make_pair(SectionAddr.first + *StubOffset, ""); + uint64_t Addr = 0; + + if (IsInsideLoad) + Addr = pointerToJITTargetAddress(StubInfo->Content.data()); + else + Addr = StubInfo->TargetAddress; + + return std::make_pair(Addr, ""); } RuntimeDyldChecker::RuntimeDyldChecker( - IsSymbolValidFunction IsSymbolValid, - GetSymbolAddressFunction GetSymbolAddress, - GetSymbolContentFunction GetSymbolContent, - GetSectionLoadAddressFunction GetSectionLoadAddress, - GetSectionContentFunction GetSectionContent, - GetStubOffsetInSectionFunction GetStubOffsetInSection, - support::endianness Endianness, - MCDisassembler *Disassembler, - MCInstPrinter *InstPrinter, - raw_ostream &ErrStream) + IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, + GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, + GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, + MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, + raw_ostream &ErrStream) : Impl(::llvm::make_unique<RuntimeDyldCheckerImpl>( - std::move(IsSymbolValid), - std::move(GetSymbolAddress), - std::move(GetSymbolContent), - std::move(GetSectionLoadAddress), - std::move(GetSectionContent), - std::move(GetStubOffsetInSection), - Endianness, Disassembler, - InstPrinter, ErrStream)) {} + std::move(IsSymbolValid), std::move(GetSymbolInfo), + std::move(GetSectionInfo), std::move(GetStubInfo), + std::move(GetGOTInfo), Endianness, Disassembler, InstPrinter, + ErrStream)) {} RuntimeDyldChecker::~RuntimeDyldChecker() {} diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h index 0debd29cfd3..ac9d4d46021 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h @@ -19,31 +19,18 @@ class RuntimeDyldCheckerImpl { using IsSymbolValidFunction = RuntimeDyldChecker::IsSymbolValidFunction; - using GetSymbolAddressFunction = - RuntimeDyldChecker::GetSymbolAddressFunction; - using GetSymbolContentFunction = - RuntimeDyldChecker::GetSymbolContentFunction; - - using GetSectionLoadAddressFunction = - RuntimeDyldChecker::GetSectionLoadAddressFunction; - using GetSectionContentFunction = - RuntimeDyldChecker::GetSectionContentFunction; - - using GetStubOffsetInSectionFunction = - RuntimeDyldChecker::GetStubOffsetInSectionFunction; + using GetSymbolInfoFunction = RuntimeDyldChecker::GetSymbolInfoFunction; + using GetSectionInfoFunction = RuntimeDyldChecker::GetSectionInfoFunction; + using GetStubInfoFunction = RuntimeDyldChecker::GetStubInfoFunction; + using GetGOTInfoFunction = RuntimeDyldChecker::GetGOTInfoFunction; public: RuntimeDyldCheckerImpl( - IsSymbolValidFunction IsSymbolValid, - GetSymbolAddressFunction GetSymbolAddress, - GetSymbolContentFunction GetSymbolContent, - GetSectionLoadAddressFunction GetSectionLoadAddress, - GetSectionContentFunction GetSectionContent, - GetStubOffsetInSectionFunction GetStubOffsetInSection, - support::endianness Endianness, - MCDisassembler *Disassembler, - MCInstPrinter *InstPrinter, - llvm::raw_ostream &ErrStream); + IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, + GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo, + GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, + MCDisassembler *Disassembler, MCInstPrinter *InstPrinter, + llvm::raw_ostream &ErrStream); bool check(StringRef CheckExpr) const; bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const; @@ -66,19 +53,17 @@ private: StringRef SectionName, bool IsInsideLoad) const; - std::pair<uint64_t, std::string> getStubAddrFor(StringRef FileName, - StringRef SectionName, - StringRef Symbol, - bool IsInsideLoad) const; + std::pair<uint64_t, std::string> + getStubOrGOTAddrFor(StringRef StubContainerName, StringRef Symbol, + bool IsInsideLoad, bool IsStubAddr) const; Optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const; IsSymbolValidFunction IsSymbolValid; - GetSymbolAddressFunction GetSymbolAddress; - GetSymbolContentFunction GetSymbolContent; - GetSectionLoadAddressFunction GetSectionLoadAddress; - GetSectionContentFunction GetSectionContent; - GetStubOffsetInSectionFunction GetStubOffsetInSection; + GetSymbolInfoFunction GetSymbolInfo; + GetSectionInfoFunction GetSectionInfo; + GetStubInfoFunction GetStubInfo; + GetGOTInfoFunction GetGOTInfo; support::endianness Endianness; MCDisassembler *Disassembler; MCInstPrinter *InstPrinter; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index ec4809fd93b..ef0784e2273 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -60,7 +60,7 @@ class RuntimeDyldELF : public RuntimeDyldImpl { void resolveBPFRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); - unsigned getMaxStubSize() override { + unsigned getMaxStubSize() const override { if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) return 20; // movz; movk; movk; movk; br if (Arch == Triple::arm || Arch == Triple::thumb) diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 615a7280a3a..68b3468fbc9 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -312,7 +312,7 @@ protected: RuntimeDyld::NotifyStubEmittedFunction; NotifyStubEmittedFunction NotifyStubEmitted; - virtual unsigned getMaxStubSize() = 0; + virtual unsigned getMaxStubSize() const = 0; virtual unsigned getStubAlignment() = 0; bool HasError; @@ -485,8 +485,8 @@ public: } StringRef getSectionContent(unsigned SectionID) const { - return StringRef(reinterpret_cast<char*>(Sections[SectionID].getAddress()), - Sections[SectionID].getSize()); + return StringRef(reinterpret_cast<char *>(Sections[SectionID].getAddress()), + Sections[SectionID].getStubOffset() + getMaxStubSize()); } uint8_t* getSymbolLocalAddress(StringRef Name) const { diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h index d43aec68861..40910bea0c3 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -27,7 +27,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldCOFF(MM, Resolver) {} - unsigned getMaxStubSize() override { + unsigned getMaxStubSize() const override { return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h index 24b77d50569..bb2e9626e0b 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h @@ -50,7 +50,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldCOFF(MM, Resolver) {} - unsigned getMaxStubSize() override { + unsigned getMaxStubSize() const override { return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h index 07a3e7bd981..d2d74534cf9 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -61,7 +61,7 @@ public: unsigned getStubAlignment() override { return 1; } // 2-byte jmp instruction + 32-bit relative address + 64-bit absolute jump - unsigned getMaxStubSize() override { return 14; } + unsigned getMaxStubSize() const override { return 14; } // The target location for the relocation is described by RE.SectionID and // RE.Offset. RE.SectionID can be used to find the SectionEntry. Each diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index c994e3032f0..f2ee1b06d49 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -26,7 +26,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} - unsigned getMaxStubSize() override { return 8; } + unsigned getMaxStubSize() const override { return 8; } unsigned getStubAlignment() override { return 8; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index acc347a4762..b7649e921c2 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -29,7 +29,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} - unsigned getMaxStubSize() override { return 8; } + unsigned getMaxStubSize() const override { return 8; } unsigned getStubAlignment() override { return 4; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 4d216e8e0ca..f0de27ba14b 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -26,7 +26,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} - unsigned getMaxStubSize() override { return 0; } + unsigned getMaxStubSize() const override { return 0; } unsigned getStubAlignment() override { return 1; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 0700f9af0d6..249f8dc0f29 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -26,7 +26,7 @@ public: JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} - unsigned getMaxStubSize() override { return 8; } + unsigned getMaxStubSize() const override { return 8; } unsigned getStubAlignment() override { return 1; } diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/AArch64/MachO_ARM64_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/AArch64/MachO_ARM64_relocations.s index e9f915ece26..ba823fb2d44 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/AArch64/MachO_ARM64_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/AArch64/MachO_ARM64_relocations.s @@ -51,9 +51,9 @@ ldr1: # adrp instruction and the GOT entry for ptr. ldr encodes the offset of the GOT # entry within the page. The ldr instruction perfroms an implicit shift on the # encoded immediate (imm<<3). -# rtdyld-check: *{8}(stub_addr(foo.o, __text, _ptr)) = _ptr -# rtdyld-check: decode_operand(adrp2, 1) = (stub_addr(foo.o, __text, _ptr)[32:12] - adrp2[32:12]) -# rtdyld-check: decode_operand(ldr2, 2) = stub_addr(foo.o, __text, _ptr)[11:3] +# rtdyld-check: *{8}(stub_addr(foo.o/__text, _ptr)) = _ptr +# rtdyld-check: decode_operand(adrp2, 1) = (stub_addr(foo.o/__text, _ptr)[32:12] - adrp2[32:12]) +# rtdyld-check: decode_operand(ldr2, 2) = stub_addr(foo.o/__text, _ptr)[11:3] .globl _test_adrp_ldr .align 2 _test_got_adrp_ldr: @@ -92,12 +92,12 @@ _subtractor_result: .quad _test_branch_reloc - _foo # Test 32-bit relative ARM64_RELOC_POINTER_TO_GOT -# rtdyld-check: *{4}_pointer_to_got_32_rel = (stub_addr(foo.o, __data, _dummy1) - _pointer_to_got_32_rel) +# rtdyld-check: *{4}_pointer_to_got_32_rel = (stub_addr(foo.o/__data, _dummy1) - _pointer_to_got_32_rel) _pointer_to_got_32_rel: .long _dummy1@got - . # Test 64-bit absolute ARM64_RELOC_POINTER_TO_GOT -# rtdyld-check: *{8}_pointer_to_got_64_abs = stub_addr(foo.o, __data, _dummy1) +# rtdyld-check: *{8}_pointer_to_got_64_abs = stub_addr(foo.o/__data, _dummy1) _pointer_to_got_64_abs: .quad _dummy1@got diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_ARM_PIC_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_ARM_PIC_relocations.s index d3fa5fbed80..d826b37b6b0 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_ARM_PIC_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_ARM_PIC_relocations.s @@ -22,15 +22,15 @@ nextPC: # Check both the content of the stub, and the reference to the stub. # Stub should contain '0xe51ff004' (ldr pc, [pc, #-4]), followed by the target. # -# rtdyld-check: *{4}(stub_addr(foo.o, __text, baz)) = 0xe51ff004 -# rtdyld-check: *{4}(stub_addr(foo.o, __text, baz) + 4) = baz +# rtdyld-check: *{4}(stub_addr(foo.o/__text, baz)) = 0xe51ff004 +# rtdyld-check: *{4}(stub_addr(foo.o/__text, baz) + 4) = baz # -# rtdyld-check: decode_operand(insn3, 0) = stub_addr(foo.o, __text, baz) - (insn3 + 8) +# rtdyld-check: decode_operand(insn3, 0) = stub_addr(foo.o/__text, baz) - (insn3 + 8) insn3: bl baz # Check stub generation for internal symbols by referencing 'bar'. -# rtdyld-check: *{4}(stub_addr(foo.o, __text, bar) + 4) = bar +# rtdyld-check: *{4}(stub_addr(foo.o/__text, bar) + 4) = bar insn4: bl bar bx lr diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_Thumb_Relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_Thumb_Relocations.s index e2e6e11e7d9..4931b4165f8 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_Thumb_Relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/MachO_Thumb_Relocations.s @@ -35,14 +35,14 @@ thumb_caller: # Check that stubs for thumb callers use thumb code (not arm), and that thumb # callees have the low bit set on their addresses. # -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_thumb_callee)) = 0xf000f8df -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_thumb_callee) + 4) = (thumb_caller_thumb_callee | 0x1) +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, thumb_caller_thumb_callee)) = 0xf000f8df +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, thumb_caller_thumb_callee) + 4) = (thumb_caller_thumb_callee | 0x1) bl thumb_caller_thumb_callee # Check that arm callees do not have the low bit set on their addresses. # -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_arm_callee)) = 0xf000f8df -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_arm_callee) + 4) = thumb_caller_arm_callee +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, thumb_caller_arm_callee)) = 0xf000f8df +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, thumb_caller_arm_callee) + 4) = thumb_caller_arm_callee bl thumb_caller_arm_callee .globl arm_caller @@ -53,8 +53,8 @@ arm_caller: # Check that stubs for arm callers use arm code (not thumb), and that thumb # callees have the low bit set on their addresses. -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, arm_caller_thumb_callee)) = 0xe51ff004 -# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, arm_caller_thumb_callee) + 4) = (arm_caller_thumb_callee | 0x1) +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, arm_caller_thumb_callee)) = 0xe51ff004 +# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o/__text, arm_caller_thumb_callee) + 4) = (arm_caller_thumb_callee | 0x1) bl arm_caller_thumb_callee nop diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s index fc2a277c3d2..18e686706db 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s @@ -44,7 +44,7 @@ bar: sd $4, 8($fp) # Test R_MIPS_26 relocation. -# rtdyld-check: decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_Mips64N64.o, .text, foo)[27:0] +# rtdyld-check: decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_Mips64N64.o/.text, foo)[27:0] insn1: .option pic0 jal foo diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s index 942979d645c..46e764477ba 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s @@ -44,7 +44,7 @@ bar: sd $4, 8($fp) # Test R_MIPS_26 relocation. -# rtdyld-check: decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_N32.o, .text, foo)[27:0] +# rtdyld-check: decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_N32.o/.text, foo)[27:0] insn1: .option pic0 jal foo diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s index 2a8ddff43dd..40002d44a10 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s @@ -34,7 +34,7 @@ tmp1: .globl bar .type bar,@function bar: -# rtdyld-check: decode_operand(R_MIPS_26, 0)[27:0] = stub_addr(test_ELF_O32.o, .text, foo)[27:0] +# rtdyld-check: decode_operand(R_MIPS_26, 0)[27:0] = stub_addr(test_ELF_O32.o/.text, foo)[27:0] # rtdyld-check: decode_operand(R_MIPS_26, 0)[1:0] = 0 R_MIPS_26: j foo diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_elf.s b/llvm/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_elf.s index b43c84caf56..852e75bb0ee 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_elf.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_elf.s @@ -25,11 +25,11 @@ bar: stdu 1, -32(1) .cfi_def_cfa_offset 32 .cfi_offset lr, 16 -# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o, .text, foo) + 0)) [15:0] = foo_gep [63:48] -# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o, .text, foo) + 4)) [15:0] = foo_gep [47:32] -# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o, .text, foo) + 12)) [15:0] = foo_gep [31:16] -# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o, .text, foo) + 16)) [15:0] = foo_gep [15:0] -# rtdyld-check: decode_operand(foo_call, 0) = (stub_addr(ppc64_elf.o, .text, foo) - foo_call) >> 2 +# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o/.text, foo) + 0)) [15:0] = foo_gep [63:48] +# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o/.text, foo) + 4)) [15:0] = foo_gep [47:32] +# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o/.text, foo) + 12)) [15:0] = foo_gep [31:16] +# rtdyld-check: (*{4}(stub_addr(ppc64_elf.o/.text, foo) + 16)) [15:0] = foo_gep [15:0] +# rtdyld-check: decode_operand(foo_call, 0) = (stub_addr(ppc64_elf.o/.text, foo) - foo_call) >> 2 foo_call: bl foo nop diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s index f5539fcb367..dc69a150725 100644 --- a/llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s @@ -24,8 +24,8 @@ insn2: # Test PC-rel GOT relocation. # Verify both the contents of the GOT entry for y, and that the movq instruction # references the correct GOT entry address: -# rtdyld-check: *{8}(stub_addr(test_x86-64.o, __text, y)) = y -# rtdyld-check: decode_operand(insn3, 4) = stub_addr(test_x86-64.o, __text, y) - next_pc(insn3) +# rtdyld-check: *{8}(stub_addr(test_x86-64.o/__text, y)) = y +# rtdyld-check: decode_operand(insn3, 4) = stub_addr(test_x86-64.o/__text, y) - next_pc(insn3) insn3: movq y@GOTPCREL(%rip), %rax diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp index b866ca7e0ad..fde61eafac9 100644 --- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -270,7 +270,6 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " << Alignment << ", SectionName = " << SectionName << ")\n"; - dbgs() << " Registering code section \"" << SectionName << "\"\n"; if (SecIDMap) (*SecIDMap)[SectionName] = SectionID; @@ -299,7 +298,6 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, outs() << "allocateDataSection(Size = " << Size << ", Alignment = " << Alignment << ", SectionName = " << SectionName << ")\n"; - dbgs() << " Registering code section \"" << SectionName << "\"\n"; if (SecIDMap) (*SecIDMap)[SectionName] = SectionID; @@ -742,28 +740,39 @@ static int linkAndVerify() { 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; - }); - - auto GetSymbolAddress = - [&Dyld, &MemMgr](StringRef Symbol) -> Expected<JITTargetAddress> { - if (auto InternalSymbol = Dyld.getSymbol(Symbol)) - return InternalSymbol.getAddress(); - + 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 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 @@ static int linkAndVerify() { 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 @@ static int linkAndVerify() { auto I = Result->find(Symbol); assert(I != Result->end() && "Expected symbol address if no error occurred"); - return 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; + SymInfo.TargetAddress = I->second.getAddress(); + } + + // 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 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 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 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 @@ static int linkAndVerify() { 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 |