Skip to content

Commit 729d29e

Browse files
committed
[BOLT] Update dynamic relocations from section relocations
This patch changes patchELFAllocatableRelaSections from going through old relocations sections and update the relocation offsets to emitting the relocations stored in binary sections. This is needed in case we would like to remove and add dynamic relocations during BOLT work and it is used by golang support pass. Note: Currently we emit relocations in the old sections, so the total number of them should be equal or less of old number. Testing: No special tests are neeeded, since this patch does not fix anything or add new functionality (it only prepares to add). Every PIC-compiled test binary will use this code and thus become a test. But just in case the aarch64 dynamic relocations tests were added. Vladislav Khmelevsky, Advanced Software Technology Lab, Huawei Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D117612
1 parent c9032f1 commit 729d29e

File tree

9 files changed

+619
-40
lines changed

9 files changed

+619
-40
lines changed

bolt/include/bolt/Core/BinarySection.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ class BinarySection {
296296
return make_range(Relocations.begin(), Relocations.end());
297297
}
298298

299+
/// Iterate over all dynamic relocations for this section.
300+
iterator_range<RelocationSetType::iterator> dynamicRelocations() {
301+
return make_range(DynamicRelocations.begin(), DynamicRelocations.end());
302+
}
303+
304+
/// Iterate over all dynamic relocations for this section.
305+
iterator_range<RelocationSetType::const_iterator> dynamicRelocations() const {
306+
return make_range(DynamicRelocations.begin(), DynamicRelocations.end());
307+
}
308+
299309
/// Does this section have any non-pending relocations?
300310
bool hasRelocations() const { return !Relocations.empty(); }
301311

bolt/include/bolt/Core/Relocation.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ struct Relocation {
8989
/// Return true if relocation type is for thread local storage.
9090
static bool isTLS(uint64_t Type);
9191

92+
/// Return code for a NONE relocation
93+
static uint64_t getNone();
94+
9295
/// Return code for a PC-relative 4-byte relocation
9396
static uint64_t getPC32();
9497

@@ -98,6 +101,10 @@ struct Relocation {
98101
/// Return true if this relocation is PC-relative. Return false otherwise.
99102
bool isPCRelative() const { return isPCRelative(Type); }
100103

104+
/// Return true if this relocation is R_*_RELATIVE type. Return false
105+
/// otherwise.
106+
bool isRelative() const { return isRelative(Type); }
107+
101108
/// Emit relocation at a current \p Streamer' position. The caller is
102109
/// responsible for setting the position correctly.
103110
size_t emit(MCStreamer *Streamer) const;

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Support/Error.h"
2323
#include <map>
2424
#include <set>
25+
#include <unordered_map>
2526

2627
namespace llvm {
2728

@@ -124,7 +125,7 @@ class RewriteInstance {
124125
void processLKSMPLocks();
125126

126127
/// Read relocations from a given section.
127-
void readDynamicRelocations(const object::SectionRef &Section);
128+
void readDynamicRelocations(const object::SectionRef &Section, bool IsJmpRel);
128129

129130
/// Read relocations from a given section.
130131
void readRelocations(const object::SectionRef &Section);
@@ -201,6 +202,10 @@ class RewriteInstance {
201202
/// \p OldAddress address in the original binary.
202203
uint64_t getNewFunctionAddress(uint64_t OldAddress);
203204

205+
/// Return address of a function or moved data in the new binary
206+
/// corresponding to \p OldAddress address in the original binary.
207+
uint64_t getNewFunctionOrDataAddress(uint64_t OldAddress);
208+
204209
/// Return value for the symbol \p Name in the output.
205210
uint64_t getNewValueForSymbol(const StringRef Name);
206211

@@ -299,6 +304,14 @@ class RewriteInstance {
299304
const std::vector<uint32_t> &NewSectionIndex, WriteFuncTy Write,
300305
StrTabFuncTy AddToStrTab);
301306

307+
/// Get output index in dynamic symbol table.
308+
uint32_t getOutputDynamicSymbolIndex(const MCSymbol *Symbol) {
309+
auto It = SymbolIndex.find(Symbol);
310+
if (It != SymbolIndex.end())
311+
return It->second;
312+
return 0;
313+
}
314+
302315
/// Add a notes section containing the BOLT revision and command line options.
303316
void addBoltInfoSection();
304317

@@ -426,11 +439,19 @@ class RewriteInstance {
426439
/// Location and size of dynamic relocations.
427440
Optional<uint64_t> DynamicRelocationsAddress;
428441
uint64_t DynamicRelocationsSize{0};
442+
uint64_t DynamicRelativeRelocationsCount{0};
429443

430444
/// PLT relocations are special kind of dynamic relocations stored separately.
431445
Optional<uint64_t> PLTRelocationsAddress;
432446
uint64_t PLTRelocationsSize{0};
433447

448+
/// True if relocation of specified type came from .rela.plt
449+
DenseMap<uint64_t, bool> IsJmpRelocation;
450+
451+
/// Index of specified symbol in the dynamic symbol table. NOTE Currently it
452+
/// is filled and used only with the relocations-related symbols.
453+
std::unordered_map<const MCSymbol *, uint32_t> SymbolIndex;
454+
434455
/// Store all non-zero symbols in this map for a quick address lookup.
435456
std::map<uint64_t, llvm::object::SymbolRef> FileSymRefs;
436457

bolt/lib/Core/Relocation.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,7 @@ bool Relocation::isGOT(uint64_t Type) {
533533
return isGOTX86(Type);
534534
}
535535

536-
bool Relocation::isNone(uint64_t Type) {
537-
if (Arch == Triple::aarch64)
538-
return Type == ELF::R_AARCH64_NONE;
539-
return Type == ELF::R_X86_64_NONE;
540-
}
536+
bool Relocation::isNone(uint64_t Type) { return Type == getNone(); }
541537

542538
bool Relocation::isRelative(uint64_t Type) {
543539
if (Arch == Triple::aarch64)
@@ -557,10 +553,10 @@ bool Relocation::isTLS(uint64_t Type) {
557553
return isTLSX86(Type);
558554
}
559555

560-
bool Relocation::isPCRelative(uint64_t Type) {
556+
uint64_t Relocation::getNone() {
561557
if (Arch == Triple::aarch64)
562-
return isPCRelativeAArch64(Type);
563-
return isPCRelativeX86(Type);
558+
return ELF::R_AARCH64_NONE;
559+
return ELF::R_X86_64_NONE;
564560
}
565561

566562
uint64_t Relocation::getPC32() {
@@ -575,6 +571,12 @@ uint64_t Relocation::getPC64() {
575571
return ELF::R_X86_64_PC64;
576572
}
577573

574+
bool Relocation::isPCRelative(uint64_t Type) {
575+
if (Arch == Triple::aarch64)
576+
return isPCRelativeAArch64(Type);
577+
return isPCRelativeX86(Type);
578+
}
579+
578580
size_t Relocation::emit(MCStreamer *Streamer) const {
579581
const size_t Size = getSizeForType(Type);
580582
MCContext &Ctx = Streamer->getContext();

0 commit comments

Comments
 (0)