mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Make llvm-rtdlyd -check preserve automatic address mappings made by RuntimeDyld.
Currently llvm-rtdyld in -check mode will map sections to back-to-back 4k aligned slabs starting at 0x1000. Automatically remapping sections by default is helpful because it quickly exposes relocation bugs due to use of local addresses rather than load addresses (these would silently pass if the load address was not remapped). These mappings can be explicitly overridden on a per-section basis using llvm-rtdlyd's -map-section option. This patch extends this scheme to also preserve any mappings made by RuntimeDyld itself. Preserving RuntimeDyld's automatic mappings allows us to write test cases to verify that these automatic mappings have been applied. This will allow the fix in https://reviews.llvm.org/D32899 to be tested with llvm-rtdyld -check. llvm-svn: 302372
This commit is contained in:
parent
d2d0986b7c
commit
e759a41442
@ -10,6 +10,8 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
|
||||
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -97,6 +99,10 @@ public:
|
||||
StringRef SectionName,
|
||||
bool LocalAddress);
|
||||
|
||||
/// \brief If there is a section at the given local address, return its load
|
||||
/// address, otherwise return none.
|
||||
Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
|
||||
};
|
||||
|
@ -861,6 +861,15 @@ RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
|
||||
SymInfo.getOffset());
|
||||
}
|
||||
|
||||
Optional<uint64_t>
|
||||
RuntimeDyldCheckerImpl::getSectionLoadAddress(void *LocalAddress) const {
|
||||
for (auto &S : getRTDyld().Sections) {
|
||||
if (S.getAddress() == LocalAddress)
|
||||
return S.getLoadAddress();
|
||||
}
|
||||
return Optional<uint64_t>();
|
||||
}
|
||||
|
||||
void RuntimeDyldCheckerImpl::registerSection(
|
||||
StringRef FilePath, unsigned SectionID) {
|
||||
StringRef FileName = sys::path::filename(FilePath);
|
||||
@ -935,3 +944,8 @@ RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
|
||||
bool LocalAddress) {
|
||||
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
|
||||
}
|
||||
|
||||
Optional<uint64_t>
|
||||
RuntimeDyldChecker::getSectionLoadAddress(void *LocalAddress) const {
|
||||
return Impl->getSectionLoadAddress(LocalAddress);
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ private:
|
||||
bool IsInsideLoad) const;
|
||||
StringRef getSubsectionStartingAt(StringRef Name) const;
|
||||
|
||||
Optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const;
|
||||
|
||||
void registerSection(StringRef FilePath, unsigned SectionID);
|
||||
void registerStubMap(StringRef FilePath, unsigned SectionID,
|
||||
const RuntimeDyldImpl::StubMap &RTDyldStubs);
|
||||
|
@ -486,10 +486,7 @@ static int checkAllExpressions(RuntimeDyldChecker &Checker) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::map<void *, uint64_t>
|
||||
applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
|
||||
|
||||
std::map<void*, uint64_t> SpecificMappings;
|
||||
void applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
|
||||
|
||||
for (StringRef Mapping : SpecificSectionMappings) {
|
||||
|
||||
@ -522,10 +519,7 @@ applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
|
||||
"'.");
|
||||
|
||||
Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
|
||||
SpecificMappings[OldAddr] = NewAddr;
|
||||
}
|
||||
|
||||
return SpecificMappings;
|
||||
}
|
||||
|
||||
// Scatter sections in all directions!
|
||||
@ -554,8 +548,7 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
|
||||
|
||||
// Apply any section-specific mappings that were requested on the command
|
||||
// line.
|
||||
typedef std::map<void*, uint64_t> AppliedMappingsT;
|
||||
AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);
|
||||
applySpecificSectionMappings(Checker);
|
||||
|
||||
// Keep an "already allocated" mapping of section target addresses to sizes.
|
||||
// Sections whose address mappings aren't specified on the command line will
|
||||
@ -563,15 +556,19 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
|
||||
// minimum separation.
|
||||
std::map<uint64_t, uint64_t> AlreadyAllocated;
|
||||
|
||||
// Move the previously applied mappings into the already-allocated map.
|
||||
// Move the previously applied mappings (whether explicitly specified on the
|
||||
// command line, or implicitly set by RuntimeDyld) into the already-allocated
|
||||
// map.
|
||||
for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
|
||||
I != E;) {
|
||||
WorklistT::iterator Tmp = I;
|
||||
++I;
|
||||
AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first);
|
||||
auto LoadAddr = Checker.getSectionLoadAddress(Tmp->first);
|
||||
|
||||
if (AI != AppliedMappings.end()) {
|
||||
AlreadyAllocated[AI->second] = Tmp->second;
|
||||
if (LoadAddr &&
|
||||
*LoadAddr != static_cast<uint64_t>(
|
||||
reinterpret_cast<uintptr_t>(Tmp->first))) {
|
||||
AlreadyAllocated[*LoadAddr] = Tmp->second;
|
||||
Worklist.erase(Tmp);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user