Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bolt/include/bolt/Core/BinaryContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ class BinaryContext {
///
/// As we fold identical functions, multiple symbols can point
/// to the same BinaryFunction.
std::unordered_map<const MCSymbol *, BinaryFunction *> SymbolToFunctionMap;
DenseMap<const MCSymbol *, BinaryFunction *> SymbolToFunctionMap;

/// A mutex that is used to control parallel accesses to SymbolToFunctionMap
mutable llvm::sys::RWMutex SymbolToFunctionMapMutex;
Expand Down
28 changes: 28 additions & 0 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ class BinaryFunction {
/// goto labels.
std::set<uint64_t> ExternallyReferencedOffsets;

/// Relocations from data sections targeting internals of this function, i.e.
/// some code not at an entry point. These include, but are not limited to,
/// jump table relocations and computed goto tables.
///
/// Since relocations can be removed/deallocated, we store relocation offsets
/// instead of pointers.
DenseSet<uint64_t> InternalRefDataRelocations;

/// Offsets of indirect branches with unknown destinations.
std::set<uint64_t> UnknownIndirectBranchOffsets;

Expand Down Expand Up @@ -640,6 +648,20 @@ class BinaryFunction {
Islands->CodeOffsets.emplace(Offset);
}

/// Register a relocation from data section referencing code at a non-zero
/// offset in this function.
void registerInternalRefDataRelocation(uint64_t FuncOffset,
uint64_t RelOffset) {
assert(FuncOffset != 0 && "Relocation should reference function internals");
registerReferencedOffset(FuncOffset);
InternalRefDataRelocations.insert(RelOffset);
const MCSymbol *ReferencedSymbol =
getOrCreateLocalLabel(getAddress() + FuncOffset);

// Track the symbol mapping since it's used in relocation handling.
BC.setSymbolToFunctionMap(ReferencedSymbol, this);
}

/// Register an internal offset in a function referenced from outside.
void registerReferencedOffset(uint64_t Offset) {
ExternallyReferencedOffsets.emplace(Offset);
Expand Down Expand Up @@ -1299,6 +1321,12 @@ class BinaryFunction {
void addRelocation(uint64_t Address, MCSymbol *Symbol, uint32_t RelType,
uint64_t Addend, uint64_t Value);

/// Return locations (offsets) of data section relocations targeting internals
/// of this functions.
const DenseSet<uint64_t> &getInternalRefDataRelocations() const {
return InternalRefDataRelocations;
}

/// Return the name of the section this function originated from.
std::optional<StringRef> getOriginSectionName() const {
if (!OriginSection)
Expand Down
11 changes: 11 additions & 0 deletions bolt/lib/Core/BinaryContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,17 @@ void BinaryContext::foldFunction(BinaryFunction &ChildBF,
}
ChildBF.getSymbols().clear();

// Reset function mapping for local symbols.
for (uint64_t RelOffset : ChildBF.getInternalRefDataRelocations()) {
const Relocation *Rel = getRelocationAt(RelOffset);
if (!Rel || !Rel->Symbol)
continue;

WriteSymbolMapLock.lock();
SymbolToFunctionMap[Rel->Symbol] = nullptr;
WriteSymbolMapLock.unlock();
}

// Move other names the child function is known under.
llvm::move(ChildBF.Aliases, std::back_inserter(ParentBF.Aliases));
ChildBF.Aliases.clear();
Expand Down
6 changes: 4 additions & 2 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2954,8 +2954,10 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
// if-condition above) so we're handling a relocation from a function
// to itself. RISC-V uses such relocations for branches, for example.
// These should not be registered as externally references offsets.
if (!ContainingBF)
ReferencedBF->registerReferencedOffset(RefFunctionOffset);
if (!ContainingBF && !ReferencedBF->isInConstantIsland(Address)) {
ReferencedBF->registerInternalRefDataRelocation(RefFunctionOffset,
Rel.getOffset());
}
}
if (opts::Verbosity > 1 &&
BinarySection(*BC, RelocatedSection).isWritable())
Expand Down
Loading