[llvm] [BOLT] Skip out-of-range pending relocations (PR #116964)
Paschalis Mpeis via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 20 04:54:51 PST 2024
https://github.com/paschalis-mpeis created https://github.com/llvm/llvm-project/pull/116964
When there are not enough bits to encode a pending relocation value, then skip it instead of asserting.
---
> [!NOTE]
> This is a **minimal change** to get some quick feedback.
> It suggests a way forward that avoids the assertion without fully disabling the optimization (see (S2) in Issue [#116817](https://github.com/llvm/llvm-project/issues/116817)).
> If this is in the right direction, more code will be added, including tests.
>From e9b0066e7e8f86386cf8eb05002ddad6568d9b78 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Tue, 19 Nov 2024 15:53:45 +0000
Subject: [PATCH] [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.
---
bolt/include/bolt/Core/Relocation.h | 3 +++
bolt/lib/Core/BinarySection.cpp | 10 ++++++++++
bolt/lib/Core/Relocation.cpp | 16 ++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 933f62a31f8fd7..8846369612ae31 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -67,6 +67,9 @@ struct Relocation {
// Adjust value depending on relocation type (make it PC relative or not)
static uint64_t encodeValue(uint64_t Type, uint64_t Value, uint64_t PC);
+ // Return true if there are enough bits to encode the relocation value.
+ static bool canEncodeValue(uint64_t Type, uint64_t Value, uint64_t PC);
+
/// Extract current relocated value from binary contents. This is used for
/// RISC architectures where values are encoded in specific bits depending
/// on the relocation value. For X86, we limit to sign extending the value
diff --git a/bolt/lib/Core/BinarySection.cpp b/bolt/lib/Core/BinarySection.cpp
index 9ad49ca1b3a038..1eb237fbb05acb 100644
--- a/bolt/lib/Core/BinarySection.cpp
+++ b/bolt/lib/Core/BinarySection.cpp
@@ -165,11 +165,17 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
OS.pwrite(Patch.Bytes.data(), Patch.Bytes.size(),
SectionFileOffset + Patch.Offset);
+ uint64_t SkippedPendingRelocations = 0;
for (Relocation &Reloc : PendingRelocations) {
uint64_t Value = Reloc.Addend;
if (Reloc.Symbol)
Value += Resolver(Reloc.Symbol);
+ if (!Relocation::canEncodeValue(Reloc.Type, Value,
+ SectionAddress + Reloc.Offset)) {
+ ++SkippedPendingRelocations;
+ continue;
+ }
Value = Relocation::encodeValue(Reloc.Type, Value,
SectionAddress + Reloc.Offset);
@@ -188,6 +194,10 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
}
clearList(PendingRelocations);
+
+ if (SkippedPendingRelocations > 0)
+ outs() << "BOLT-INFO: Skipped " << SkippedPendingRelocations
+ << " pending relocations as they were out of range\n";
}
BinarySection::~BinarySection() { updateContents(nullptr, 0); }
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index 4e888a5b147aca..a378961981ee37 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -361,6 +361,16 @@ static uint64_t encodeValueX86(uint64_t Type, uint64_t Value, uint64_t PC) {
return Value;
}
+static bool canEncodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
+ // TODO: support more cases.
+ switch (Type) {
+ default:
+ llvm_unreachable("unsupported relocation");
+ case ELF::R_AARCH64_CALL26:
+ return isInt<28>(Value - PC);
+ }
+}
+
static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
switch (Type) {
default:
@@ -838,6 +848,12 @@ uint64_t Relocation::encodeValue(uint64_t Type, uint64_t Value, uint64_t PC) {
}
}
+bool Relocation::canEncodeValue(uint64_t Type, uint64_t Value, uint64_t PC) {
+ // TODO: support more architectures.
+ assert(Arch == Triple::aarch64);
+ return canEncodeValueAArch64(Type, Value, PC);
+}
+
uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents,
uint64_t PC) {
switch (Arch) {
More information about the llvm-commits
mailing list