[llvm] [bolt] Refactor relocation arch selection (PR #87829)
Nathan Sidwell via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 5 14:11:55 PDT 2024
https://github.com/urnathan created https://github.com/llvm/llvm-project/pull/87829
Having these routines default to x86_64 and just process reloc numbers as if they are for that arch is fragile when porting BOLT. This converts these routines to use switches with an explicitly marked unreachable default case.
I considered the alternative of having x86_64 being the default, with an assert on Arch there, but thought this way is clearer.
>From 915300d1824d36c9663bb9057310ab36597aa348 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell <nathan at acm.org>
Date: Fri, 5 Apr 2024 13:34:29 -0400
Subject: [PATCH] [bolt] Refactor relocation arch selection
---
bolt/lib/Core/Relocation.cpp | 195 ++++++++++++++++++++++++++---------
1 file changed, 144 insertions(+), 51 deletions(-)
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index cbf95a7db08b52..d16b7a94787c65 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -774,60 +774,95 @@ static bool isPCRelativeRISCV(uint64_t Type) {
}
bool Relocation::isSupported(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ return false;
+ case Triple::aarch64:
return isSupportedAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return isSupportedRISCV(Type);
- return isSupportedX86(Type);
+ case Triple::x86_64:
+ return isSupportedX86(Type);
+ }
}
size_t Relocation::getSizeForType(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return getSizeForTypeAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return getSizeForTypeRISCV(Type);
- return getSizeForTypeX86(Type);
+ case Triple::x86_64:
+ return getSizeForTypeX86(Type);
+ }
}
bool Relocation::skipRelocationType(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return skipRelocationTypeAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return skipRelocationTypeRISCV(Type);
- return skipRelocationTypeX86(Type);
+ case Triple::x86_64:
+ return skipRelocationTypeX86(Type);
+ }
}
bool Relocation::skipRelocationProcess(uint64_t &Type, uint64_t Contents) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return skipRelocationProcessAArch64(Type, Contents);
- if (Arch == Triple::riscv64)
- skipRelocationProcessRISCV(Type, Contents);
- return skipRelocationProcessX86(Type, Contents);
+ case Triple::riscv64:
+ return skipRelocationProcessRISCV(Type, Contents);
+ case Triple::x86_64:
+ return skipRelocationProcessX86(Type, Contents);
+ }
}
uint64_t Relocation::encodeValue(uint64_t Type, uint64_t Value, uint64_t PC) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return encodeValueAArch64(Type, Value, PC);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return encodeValueRISCV(Type, Value, PC);
- return encodeValueX86(Type, Value, PC);
+ case Triple::x86_64:
+ return encodeValueX86(Type, Value, PC);
+ }
}
uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents,
uint64_t PC) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return extractValueAArch64(Type, Contents, PC);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return extractValueRISCV(Type, Contents, PC);
- return extractValueX86(Type, Contents, PC);
+ case Triple::x86_64:
+ return extractValueX86(Type, Contents, PC);
+ }
}
bool Relocation::isGOT(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return isGOTAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return isGOTRISCV(Type);
- return isGOTX86(Type);
+ case Triple::x86_64:
+ return isGOTX86(Type);
+ }
}
bool Relocation::isX86GOTPCRELX(uint64_t Type) {
@@ -845,27 +880,42 @@ bool Relocation::isX86GOTPC64(uint64_t Type) {
bool Relocation::isNone(uint64_t Type) { return Type == getNone(); }
bool Relocation::isRelative(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return Type == ELF::R_AARCH64_RELATIVE;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return Type == ELF::R_RISCV_RELATIVE;
- return Type == ELF::R_X86_64_RELATIVE;
+ case Triple::x86_64:
+ return Type == ELF::R_X86_64_RELATIVE;
+ }
}
bool Relocation::isIRelative(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return Type == ELF::R_AARCH64_IRELATIVE;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
llvm_unreachable("not implemented");
- return Type == ELF::R_X86_64_IRELATIVE;
+ case Triple::x86_64:
+ return Type == ELF::R_X86_64_IRELATIVE;
+ }
}
bool Relocation::isTLS(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return isTLSAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return isTLSRISCV(Type);
- return isTLSX86(Type);
+ case Triple::x86_64:
+ return isTLSX86(Type);
+ }
}
bool Relocation::isInstructionReference(uint64_t Type) {
@@ -882,49 +932,81 @@ bool Relocation::isInstructionReference(uint64_t Type) {
}
uint64_t Relocation::getNone() {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return ELF::R_AARCH64_NONE;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return ELF::R_RISCV_NONE;
- return ELF::R_X86_64_NONE;
+ case Triple::x86_64:
+ return ELF::R_X86_64_NONE;
+ }
}
uint64_t Relocation::getPC32() {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return ELF::R_AARCH64_PREL32;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return ELF::R_RISCV_32_PCREL;
- return ELF::R_X86_64_PC32;
+ case Triple::x86_64:
+ return ELF::R_X86_64_PC32;
+ }
}
uint64_t Relocation::getPC64() {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return ELF::R_AARCH64_PREL64;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
llvm_unreachable("not implemented");
- return ELF::R_X86_64_PC64;
+ case Triple::x86_64:
+ return ELF::R_X86_64_PC64;
+ }
}
bool Relocation::isPCRelative(uint64_t Type) {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return isPCRelativeAArch64(Type);
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return isPCRelativeRISCV(Type);
- return isPCRelativeX86(Type);
+ case Triple::x86_64:
+ return isPCRelativeX86(Type);
+ }
}
uint64_t Relocation::getAbs64() {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return ELF::R_AARCH64_ABS64;
- if (Arch == Triple::riscv64)
+ case Triple::riscv64:
return ELF::R_RISCV_64;
- return ELF::R_X86_64_64;
+ case Triple::x86_64:
+ return ELF::R_X86_64_64;
+ }
}
uint64_t Relocation::getRelative() {
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
return ELF::R_AARCH64_RELATIVE;
- return ELF::R_X86_64_RELATIVE;
+ case Triple::riscv64:
+ llvm_unreachable("not implemented");
+ case Triple::x86_64:
+ return ELF::R_X86_64_RELATIVE;
+ }
}
size_t Relocation::emit(MCStreamer *Streamer) const {
@@ -991,9 +1073,16 @@ void Relocation::print(raw_ostream &OS) const {
static const char *AArch64RelocNames[] = {
#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
};
- if (Arch == Triple::aarch64)
+ switch (Arch) {
+ default:
+ OS << "RType:" << Twine::utohexstr(Type);
+ break;
+
+ case Triple::aarch64:
OS << AArch64RelocNames[Type];
- else if (Arch == Triple::riscv64) {
+ break;
+
+ case Triple::riscv64:
// RISC-V relocations are not sequentially numbered so we cannot use an
// array
switch (Type) {
@@ -1006,8 +1095,12 @@ void Relocation::print(raw_ostream &OS) const {
break;
#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
}
- } else
+ break;
+
+ case Triple::x86_64:
OS << X86RelocNames[Type];
+ break;
+ }
OS << ", 0x" << Twine::utohexstr(Offset);
if (Symbol) {
OS << ", " << Symbol->getName();
More information about the llvm-commits
mailing list