Skip to content

Commit ff41150

Browse files
committed
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
1 parent 252682a commit ff41150

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
1111
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
1212

13+
#include "llvm/ADT/Optional.h"
14+
1315
#include <cstdint>
1416
#include <memory>
1517
#include <string>
@@ -97,6 +99,10 @@ class RuntimeDyldChecker {
9799
StringRef SectionName,
98100
bool LocalAddress);
99101

102+
/// \brief If there is a section at the given local address, return its load
103+
/// address, otherwise return none.
104+
Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
105+
100106
private:
101107
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
102108
};

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,15 @@ RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
861861
SymInfo.getOffset());
862862
}
863863

864+
Optional<uint64_t>
865+
RuntimeDyldCheckerImpl::getSectionLoadAddress(void *LocalAddress) const {
866+
for (auto &S : getRTDyld().Sections) {
867+
if (S.getAddress() == LocalAddress)
868+
return S.getLoadAddress();
869+
}
870+
return Optional<uint64_t>();
871+
}
872+
864873
void RuntimeDyldCheckerImpl::registerSection(
865874
StringRef FilePath, unsigned SectionID) {
866875
StringRef FileName = sys::path::filename(FilePath);
@@ -935,3 +944,8 @@ RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
935944
bool LocalAddress) {
936945
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
937946
}
947+
948+
Optional<uint64_t>
949+
RuntimeDyldChecker::getSectionLoadAddress(void *LocalAddress) const {
950+
return Impl->getSectionLoadAddress(LocalAddress);
951+
}

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class RuntimeDyldCheckerImpl {
6060
bool IsInsideLoad) const;
6161
StringRef getSubsectionStartingAt(StringRef Name) const;
6262

63+
Optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const;
64+
6365
void registerSection(StringRef FilePath, unsigned SectionID);
6466
void registerStubMap(StringRef FilePath, unsigned SectionID,
6567
const RuntimeDyldImpl::StubMap &RTDyldStubs);

llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,7 @@ static int checkAllExpressions(RuntimeDyldChecker &Checker) {
486486
return 0;
487487
}
488488

489-
static std::map<void *, uint64_t>
490-
applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
491-
492-
std::map<void*, uint64_t> SpecificMappings;
489+
void applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
493490

494491
for (StringRef Mapping : SpecificSectionMappings) {
495492

@@ -522,10 +519,7 @@ applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
522519
"'.");
523520

524521
Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
525-
SpecificMappings[OldAddr] = NewAddr;
526522
}
527-
528-
return SpecificMappings;
529523
}
530524

531525
// Scatter sections in all directions!
@@ -554,24 +548,27 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
554548

555549
// Apply any section-specific mappings that were requested on the command
556550
// line.
557-
typedef std::map<void*, uint64_t> AppliedMappingsT;
558-
AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);
551+
applySpecificSectionMappings(Checker);
559552

560553
// Keep an "already allocated" mapping of section target addresses to sizes.
561554
// Sections whose address mappings aren't specified on the command line will
562555
// allocated around the explicitly mapped sections while maintaining the
563556
// minimum separation.
564557
std::map<uint64_t, uint64_t> AlreadyAllocated;
565558

566-
// Move the previously applied mappings into the already-allocated map.
559+
// Move the previously applied mappings (whether explicitly specified on the
560+
// command line, or implicitly set by RuntimeDyld) into the already-allocated
561+
// map.
567562
for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
568563
I != E;) {
569564
WorklistT::iterator Tmp = I;
570565
++I;
571-
AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first);
566+
auto LoadAddr = Checker.getSectionLoadAddress(Tmp->first);
572567

573-
if (AI != AppliedMappings.end()) {
574-
AlreadyAllocated[AI->second] = Tmp->second;
568+
if (LoadAddr &&
569+
*LoadAddr != static_cast<uint64_t>(
570+
reinterpret_cast<uintptr_t>(Tmp->first))) {
571+
AlreadyAllocated[*LoadAddr] = Tmp->second;
575572
Worklist.erase(Tmp);
576573
}
577574
}

0 commit comments

Comments
 (0)