diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -1036,7 +1036,9 @@ /// Return a relocation registered at a given \p Address, or nullptr if there /// is no relocation at such address. - const Relocation *getRelocationAt(uint64_t Address); + const Relocation *getRelocationAt(uint64_t Address) const; + + Relocation *getRelocationAt(uint64_t Address); /// Register a presence of PC-relative relocation at the given \p Address. void addPCRelativeDataRelocation(uint64_t Address) { @@ -1049,7 +1051,9 @@ /// Return a dynamic relocation registered at a given \p Address, or nullptr /// if there is no dynamic relocation at such address. - const Relocation *getDynamicRelocationAt(uint64_t Address); + const Relocation *getDynamicRelocationAt(uint64_t Address) const; + + Relocation *getDynamicRelocationAt(uint64_t Address); /// Remove registered relocation at a given \p Address. bool removeRelocationAt(uint64_t Address); diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h --- a/bolt/include/bolt/Core/BinarySection.h +++ b/bolt/include/bolt/Core/BinarySection.h @@ -56,7 +56,7 @@ // Relocations associated with this section. Relocation offsets are // wrt. to the original section address and size. - using RelocationSetType = std::set>; + using RelocationSetType = std::map; RelocationSetType Relocations; // Dynamic relocations associated with this section. Relocation offsets are @@ -286,7 +286,6 @@ return containsAddress(Address) && Address + Size <= getEndAddress(); } - /// Iterate over all non-pending relocations for this section. iterator_range relocations() { return make_range(Relocations.begin(), Relocations.end()); } @@ -330,7 +329,7 @@ bool Pending = false) { assert(Offset < getSize() && "offset not within section bounds"); if (!Pending) { - Relocations.emplace(Relocation{Offset, Symbol, Type, Addend, Value}); + Relocations[Offset] = Relocation{Offset, Symbol, Type, Addend, Value}; } else { PendingRelocations.emplace_back( Relocation{Offset, Symbol, Type, Addend, Value}); @@ -341,7 +340,8 @@ void addDynamicRelocation(uint64_t Offset, MCSymbol *Symbol, uint64_t Type, uint64_t Addend, uint64_t Value = 0) { assert(Offset < getSize() && "offset not within section bounds"); - DynamicRelocations.emplace(Relocation{Offset, Symbol, Type, Addend, Value}); + DynamicRelocations[Offset] = + Relocation{Offset, Symbol, Type, Addend, Value}; } /// Add relocation against the original contents of this section. @@ -363,16 +363,23 @@ BinaryPatcher *getPatcher() { return Patcher.get(); } /// Lookup the relocation (if any) at the given /p Offset. - const Relocation *getRelocationAt(uint64_t Offset) const { + Relocation *getRelocationAt(uint64_t Offset) { auto Itr = Relocations.find(Offset); - return Itr != Relocations.end() ? &*Itr : nullptr; + return Itr != Relocations.end() ? &Itr->second : nullptr; + } + + const Relocation *getRelocationAt(uint64_t Offset) const { + return const_cast(this)->getRelocationAt(Offset); } /// Lookup the relocation (if any) at the given /p Offset. + Relocation *getDynamicRelocationAt(uint64_t Offset) { + auto Itr = DynamicRelocations.find(Offset); + return Itr != DynamicRelocations.end() ? &Itr->second : nullptr; + } + const Relocation *getDynamicRelocationAt(uint64_t Offset) const { - Relocation Key{Offset, 0, 0, 0, 0}; - auto Itr = DynamicRelocations.find(Key); - return Itr != DynamicRelocations.end() ? &*Itr : nullptr; + return const_cast(this)->getDynamicRelocationAt(Offset); } uint64_t hash(const BinaryData &BD) const { diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -300,7 +300,8 @@ bool BinaryContext::validateHoles() const { bool Valid = true; for (BinarySection &Section : sections()) { - for (const Relocation &Rel : Section.relocations()) { + for (const auto &It : Section.relocations()) { + const Relocation &Rel = It.second; uint64_t RelAddr = Rel.Offset + Section.getAddress(); const BinaryData *BD = getBinaryDataContainingAddress(RelAddr); if (!BD) { @@ -1856,7 +1857,7 @@ return Section->removeRelocationAt(Address - Section->getAddress()); } -const Relocation *BinaryContext::getRelocationAt(uint64_t Address) { +Relocation *BinaryContext::getRelocationAt(uint64_t Address) { ErrorOr Section = getSectionForAddress(Address); if (!Section) return nullptr; @@ -1864,7 +1865,11 @@ return Section->getRelocationAt(Address - Section->getAddress()); } -const Relocation *BinaryContext::getDynamicRelocationAt(uint64_t Address) { +const Relocation *BinaryContext::getRelocationAt(uint64_t Address) const { + return const_cast(this)->getRelocationAt(Address); +} + +Relocation *BinaryContext::getDynamicRelocationAt(uint64_t Address) { ErrorOr Section = getSectionForAddress(Address); if (!Section) return nullptr; @@ -1872,6 +1877,11 @@ return Section->getDynamicRelocationAt(Address - Section->getAddress()); } +const Relocation * +BinaryContext::getDynamicRelocationAt(uint64_t Address) const { + return const_cast(this)->getDynamicRelocationAt(Address); +} + void BinaryContext::markAmbiguousRelocations(BinaryData &BD, const uint64_t Address) { auto setImmovable = [&](BinaryData &BD) { diff --git a/bolt/lib/Core/BinarySection.cpp b/bolt/lib/Core/BinarySection.cpp --- a/bolt/lib/Core/BinarySection.cpp +++ b/bolt/lib/Core/BinarySection.cpp @@ -41,17 +41,18 @@ uint64_t Offset = BD.getAddress() - getAddress(); const uint64_t EndOffset = BD.getEndAddress() - getAddress(); - auto Begin = Relocations.lower_bound(Relocation{Offset, 0, 0, 0, 0}); - auto End = Relocations.upper_bound(Relocation{EndOffset, 0, 0, 0, 0}); + auto Begin = Relocations.lower_bound(Offset); + auto End = Relocations.upper_bound(EndOffset); const StringRef Contents = getContents(); hash_code Hash = hash_combine(hash_value(BD.getSize()), hash_value(BD.getSectionName())); while (Begin != End) { - const Relocation &Rel = *Begin++; - Hash = hash_combine( - Hash, hash_value(Contents.substr(Offset, Begin->Offset - Offset))); + const Relocation &Rel = Begin->second; + Begin = std::next(Begin, 1); + Hash = hash_combine(Hash, hash_value(Contents.substr( + Offset, Begin->second.Offset - Offset))); if (BinaryData *RelBD = BC.getBinaryDataByName(Rel.Symbol->getName())) Hash = hash_combine(Hash, hash(*RelBD, Cache)); Offset = Rel.Offset + Rel.getSize(); @@ -85,7 +86,8 @@ Streamer.emitBytes(SectionContents); } else { uint64_t SectionOffset = 0; - for (const Relocation &Relocation : relocations()) { + for (auto It : relocations()) { + Relocation &Relocation = It.second; assert(Relocation.Offset < SectionContents.size() && "overflow detected"); // Skip undefined symbols. if (BC.UndefinedSymbols.count(Relocation.Symbol)) @@ -191,9 +193,12 @@ if (isTLS()) OS << " (tls)"; - if (opts::PrintRelocations) - for (const Relocation &R : relocations()) - OS << "\n " << R; + if (opts::PrintRelocations) { + for (const auto &It : relocations()) { + const Relocation &Rel = It.second; + OS << "\n " << Rel; + } + } } BinarySection::RelocationSetType @@ -201,7 +206,8 @@ assert(PendingRelocations.empty() && "reodering pending relocations not supported"); RelocationSetType NewRelocations; - for (const Relocation &Rel : relocations()) { + for (const auto &It : relocations()) { + const Relocation &Rel = It.second; uint64_t RelAddr = Rel.Offset + getAddress(); BinaryData *BD = BC.getBinaryDataContainingAddress(RelAddr); BD = BD->getAtomicRoot(); @@ -211,14 +217,13 @@ continue; Relocation NewRel(Rel); - uint64_t RelOffset = RelAddr - BD->getAddress(); - NewRel.Offset = BD->getOutputOffset() + RelOffset; + const uint64_t RelOffset = + BD->getOutputOffset() + (RelAddr - BD->getAddress()); + NewRel.Offset = RelOffset; assert(NewRel.Offset < getSize()); LLVM_DEBUG(dbgs() << "BOLT-DEBUG: moving " << Rel << " -> " << NewRel << "\n"); - auto Res = NewRelocations.emplace(std::move(NewRel)); - (void)Res; - assert(Res.second && "Can't overwrite existing relocation"); + NewRelocations[RelOffset] = std::move(NewRel); } return NewRelocations; } diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -4926,7 +4926,8 @@ auto writeRelocations = [&](bool PatchRelative) { for (BinarySection &Section : BC->allocatableSections()) { - for (const Relocation &Rel : Section.dynamicRelocations()) { + for (const auto &It : Section.dynamicRelocations()) { + const Relocation &Rel = It.second; const bool IsRelative = Rel.isRelative(); if (PatchRelative != IsRelative) continue; @@ -4938,12 +4939,11 @@ uint64_t SectionAddress = Section.getOutputAddress(); SectionAddress = SectionAddress == 0 ? Section.getAddress() : SectionAddress; - MCSymbol *Symbol = Rel.Symbol; uint32_t SymbolIdx = 0; uint64_t Addend = Rel.Addend; if (Rel.Symbol) { - SymbolIdx = getOutputDynamicSymbolIndex(Symbol); + SymbolIdx = getOutputDynamicSymbolIndex(Rel.Symbol); } else { // Usually this case is used for R_*_(I)RELATIVE relocations const uint64_t Address = getNewFunctionOrDataAddress(Addend);