Skip to content

Commit e9b0066

Browse files
[BOLT] Skip out-of-range pending relocations
When there are not enough bits to encode a pending relocation value, then skip it instead of asserting.
1 parent dcd6207 commit e9b0066

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

bolt/include/bolt/Core/Relocation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ struct Relocation {
6767
// Adjust value depending on relocation type (make it PC relative or not)
6868
static uint64_t encodeValue(uint64_t Type, uint64_t Value, uint64_t PC);
6969

70+
// Return true if there are enough bits to encode the relocation value.
71+
static bool canEncodeValue(uint64_t Type, uint64_t Value, uint64_t PC);
72+
7073
/// Extract current relocated value from binary contents. This is used for
7174
/// RISC architectures where values are encoded in specific bits depending
7275
/// on the relocation value. For X86, we limit to sign extending the value

bolt/lib/Core/BinarySection.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,17 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
165165
OS.pwrite(Patch.Bytes.data(), Patch.Bytes.size(),
166166
SectionFileOffset + Patch.Offset);
167167

168+
uint64_t SkippedPendingRelocations = 0;
168169
for (Relocation &Reloc : PendingRelocations) {
169170
uint64_t Value = Reloc.Addend;
170171
if (Reloc.Symbol)
171172
Value += Resolver(Reloc.Symbol);
172173

174+
if (!Relocation::canEncodeValue(Reloc.Type, Value,
175+
SectionAddress + Reloc.Offset)) {
176+
++SkippedPendingRelocations;
177+
continue;
178+
}
173179
Value = Relocation::encodeValue(Reloc.Type, Value,
174180
SectionAddress + Reloc.Offset);
175181

@@ -188,6 +194,10 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
188194
}
189195

190196
clearList(PendingRelocations);
197+
198+
if (SkippedPendingRelocations > 0)
199+
outs() << "BOLT-INFO: Skipped " << SkippedPendingRelocations
200+
<< " pending relocations as they were out of range\n";
191201
}
192202

193203
BinarySection::~BinarySection() { updateContents(nullptr, 0); }

bolt/lib/Core/Relocation.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,16 @@ static uint64_t encodeValueX86(uint64_t Type, uint64_t Value, uint64_t PC) {
361361
return Value;
362362
}
363363

364+
static bool canEncodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
365+
// TODO: support more cases.
366+
switch (Type) {
367+
default:
368+
llvm_unreachable("unsupported relocation");
369+
case ELF::R_AARCH64_CALL26:
370+
return isInt<28>(Value - PC);
371+
}
372+
}
373+
364374
static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
365375
switch (Type) {
366376
default:
@@ -838,6 +848,12 @@ uint64_t Relocation::encodeValue(uint64_t Type, uint64_t Value, uint64_t PC) {
838848
}
839849
}
840850

851+
bool Relocation::canEncodeValue(uint64_t Type, uint64_t Value, uint64_t PC) {
852+
// TODO: support more architectures.
853+
assert(Arch == Triple::aarch64);
854+
return canEncodeValueAArch64(Type, Value, PC);
855+
}
856+
841857
uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents,
842858
uint64_t PC) {
843859
switch (Arch) {

0 commit comments

Comments
 (0)