-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BOLT] Change Relocation Type to 32-bit NFCI #130792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BOLT] Change Relocation Type to 32-bit NFCI #130792
Conversation
Change the Relocation Type from uint64_t to uint32_t. Add an Optional flag to relocations to indicate that they may be skipped.
@llvm/pr-subscribers-bolt Author: Paschalis Mpeis (paschalis-mpeis) ChangesChange the Relocation Type from uint64_t to uint32_t. Add an Optional flag to relocations to indicate that they may be skipped. Patch is 33.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130792.diff 15 Files Affected:
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 485979f1a55a1..9a0485989201f 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -1295,7 +1295,7 @@ class BinaryContext {
void foldFunction(BinaryFunction &ChildBF, BinaryFunction &ParentBF);
/// Add a Section relocation at a given \p Address.
- void addRelocation(uint64_t Address, MCSymbol *Symbol, uint64_t Type,
+ void addRelocation(uint64_t Address, MCSymbol *Symbol, uint32_t Type,
uint64_t Addend = 0, uint64_t Value = 0);
/// Return a relocation registered at a given \p Address, or nullptr if there
@@ -1308,7 +1308,7 @@ class BinaryContext {
}
/// Register dynamic relocation at \p Address.
- void addDynamicRelocation(uint64_t Address, MCSymbol *Symbol, uint64_t Type,
+ void addDynamicRelocation(uint64_t Address, MCSymbol *Symbol, uint32_t Type,
uint64_t Addend, uint64_t Value = 0);
/// Return a dynamic relocation registered at a given \p Address, or nullptr
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index c9ccb69ab52c1..a92cb466c5992 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -1260,7 +1260,7 @@ class BinaryFunction {
/// Register relocation type \p RelType at a given \p Address in the function
/// against \p Symbol.
/// Assert if the \p Address is not inside this function.
- void addRelocation(uint64_t Address, MCSymbol *Symbol, uint64_t RelType,
+ void addRelocation(uint64_t Address, MCSymbol *Symbol, uint32_t RelType,
uint64_t Addend, uint64_t Value);
/// Return the name of the section this function originated from.
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index 9c252c3675951..ad2fed2cf27eb 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -358,14 +358,14 @@ class BinarySection {
void clearRelocations();
/// Add a new relocation at the given /p Offset.
- void addRelocation(uint64_t Offset, MCSymbol *Symbol, uint64_t Type,
+ void addRelocation(uint64_t Offset, MCSymbol *Symbol, uint32_t Type,
uint64_t Addend, uint64_t Value = 0) {
assert(Offset < getSize() && "offset not within section bounds");
Relocations.emplace(Relocation{Offset, Symbol, Type, Addend, Value});
}
/// Add a dynamic relocation at the given /p Offset.
- void addDynamicRelocation(uint64_t Offset, MCSymbol *Symbol, uint64_t Type,
+ void addDynamicRelocation(uint64_t Offset, MCSymbol *Symbol, uint32_t Type,
uint64_t Addend, uint64_t Value = 0) {
addDynamicRelocation(Relocation{Offset, Symbol, Type, Addend, Value});
}
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index 1d45a314a17b6..0927b01cd421d 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -473,7 +473,7 @@ class MCPlusBuilder {
///
/// For X86, they might be used in scanExternalRefs when we want to skip
/// a function but still patch references inside it.
- virtual bool shouldRecordCodeRelocation(uint64_t RelType) const {
+ virtual bool shouldRecordCodeRelocation(uint32_t RelType) const {
llvm_unreachable("not implemented");
return false;
}
@@ -1074,7 +1074,7 @@ class MCPlusBuilder {
/// MCExpr referencing \p Symbol + \p Addend.
virtual bool setOperandToSymbolRef(MCInst &Inst, int OpNum,
const MCSymbol *Symbol, int64_t Addend,
- MCContext *Ctx, uint64_t RelType) const;
+ MCContext *Ctx, uint32_t RelType) const;
/// Replace an immediate operand in the instruction \p Inst with a reference
/// of the passed \p Symbol plus \p Addend. If the instruction does not have
@@ -1082,7 +1082,7 @@ class MCPlusBuilder {
/// return true.
virtual bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol,
int64_t Addend, MCContext *Ctx,
- int64_t &Value, uint64_t RelType) const {
+ int64_t &Value, uint32_t RelType) const {
llvm_unreachable("not implemented");
return false;
}
@@ -1287,7 +1287,7 @@ class MCPlusBuilder {
/// Return the MCExpr used for absolute references in this target
virtual const MCExpr *getTargetExprFor(MCInst &Inst, const MCExpr *Expr,
MCContext &Ctx,
- uint64_t RelType) const {
+ uint32_t RelType) const {
return Expr;
}
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 933f62a31f8fd..e8484e149160b 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -20,6 +20,11 @@
namespace llvm {
class MCSymbol;
+
+namespace object {
+class RelocationRef;
+} // namespace object
+
class raw_ostream;
namespace ELF {
@@ -40,7 +45,7 @@ struct Relocation {
MCSymbol *Symbol;
/// Relocation type.
- uint64_t Type;
+ uint32_t Type;
/// The offset from the \p Symbol base used to compute the final
/// value of this relocation.
@@ -50,72 +55,79 @@ struct Relocation {
/// Used to validate relocation correctness.
uint64_t Value;
+ /// Relocations added by optimizations can be optional.
+ bool Optional = false;
+
/// Return size in bytes of the given relocation \p Type.
- static size_t getSizeForType(uint64_t Type);
+ static size_t getSizeForType(uint32_t Type);
/// Return size of this relocation.
size_t getSize() const { return getSizeForType(Type); }
/// Skip relocations that we don't want to handle in BOLT
- static bool skipRelocationType(uint64_t Type);
+ static bool skipRelocationType(uint32_t Type);
/// Handle special cases when relocation should not be processed by BOLT or
/// change relocation \p Type to proper one before continuing if \p Contents
/// and \P Type mismatch occurred.
- static bool skipRelocationProcess(uint64_t &Type, uint64_t Contents);
+ static bool skipRelocationProcess(uint32_t &Type, uint64_t Contents);
- // 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);
+ /// Adjust value depending on relocation type (make it PC relative or not).
+ static uint64_t encodeValue(uint32_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
/// if necessary.
- static uint64_t extractValue(uint64_t Type, uint64_t Contents, uint64_t PC);
+ static uint64_t extractValue(uint32_t Type, uint64_t Contents, uint64_t PC);
/// Return true if relocation type is PC-relative. Return false otherwise.
- static bool isPCRelative(uint64_t Type);
+ static bool isPCRelative(uint32_t Type);
/// Check if \p Type is a supported relocation type.
- static bool isSupported(uint64_t Type);
+ static bool isSupported(uint32_t Type);
/// Return true if relocation type implies the creation of a GOT entry
- static bool isGOT(uint64_t Type);
+ static bool isGOT(uint32_t Type);
/// Special relocation type that allows the linker to modify the instruction.
- static bool isX86GOTPCRELX(uint64_t Type);
- static bool isX86GOTPC64(uint64_t Type);
+ static bool isX86GOTPCRELX(uint32_t Type);
+ static bool isX86GOTPC64(uint32_t Type);
/// Return true if relocation type is NONE
- static bool isNone(uint64_t Type);
+ static bool isNone(uint32_t Type);
/// Return true if relocation type is RELATIVE
- static bool isRelative(uint64_t Type);
+ static bool isRelative(uint32_t Type);
/// Return true if relocation type is IRELATIVE
- static bool isIRelative(uint64_t Type);
+ static bool isIRelative(uint32_t Type);
/// Return true if relocation type is for thread local storage.
- static bool isTLS(uint64_t Type);
+ static bool isTLS(uint32_t Type);
/// Return true of relocation type is for referencing a specific instruction
/// (as opposed to a function, basic block, etc).
- static bool isInstructionReference(uint64_t Type);
+ static bool isInstructionReference(uint32_t Type);
+
+ /// Return the relocation type of \p Rel from llvm::object. It checks for
+ /// overflows as BOLT uses 32 bits for the type.
+ static uint32_t getType(const object::RelocationRef &Rel);
/// Return code for a NONE relocation
- static uint64_t getNone();
+ static uint32_t getNone();
/// Return code for a PC-relative 4-byte relocation
- static uint64_t getPC32();
+ static uint32_t getPC32();
/// Return code for a PC-relative 8-byte relocation
- static uint64_t getPC64();
+ static uint32_t getPC64();
/// Return code for a ABS 8-byte relocation
- static uint64_t getAbs64();
+ static uint32_t getAbs64();
/// Return code for a RELATIVE relocation
- static uint64_t getRelative();
+ static uint32_t getRelative();
/// Return true if this relocation is PC-relative. Return false otherwise.
bool isPCRelative() const { return isPCRelative(Type); }
@@ -161,7 +173,7 @@ struct Relocation {
const MCExpr *createExpr(MCStreamer *Streamer) const;
const MCExpr *createExpr(MCStreamer *Streamer,
const MCExpr *RetainedValue) const;
- static MCBinaryExpr::Opcode getComposeOpcodeFor(uint64_t Type);
+ static MCBinaryExpr::Opcode getComposeOpcodeFor(uint32_t Type);
};
/// Relocation ordering by offset.
diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h
index fdd65bbd535f7..94dd06e91d6b1 100644
--- a/bolt/include/bolt/Rewrite/RewriteInstance.h
+++ b/bolt/include/bolt/Rewrite/RewriteInstance.h
@@ -248,7 +248,7 @@ class RewriteInstance {
/// The \p SymbolName, \p SymbolAddress, \p Addend and \p ExtractedValue
/// parameters will be set on success. The \p Skip argument indicates
/// that the relocation was analyzed, but it must not be processed.
- bool analyzeRelocation(const object::RelocationRef &Rel, uint64_t &RType,
+ bool analyzeRelocation(const object::RelocationRef &Rel, uint32_t &RType,
std::string &SymbolName, bool &IsSectionRelocation,
uint64_t &SymbolAddress, int64_t &Addend,
uint64_t &ExtractedValue, bool &Skip) const;
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 2045b9bd5d8a5..7466d2f8c91eb 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -2284,7 +2284,7 @@ ErrorOr<int64_t> BinaryContext::getSignedValueAtAddress(uint64_t Address,
}
void BinaryContext::addRelocation(uint64_t Address, MCSymbol *Symbol,
- uint64_t Type, uint64_t Addend,
+ uint32_t Type, uint64_t Addend,
uint64_t Value) {
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
assert(Section && "cannot find section for address");
@@ -2293,7 +2293,7 @@ void BinaryContext::addRelocation(uint64_t Address, MCSymbol *Symbol,
}
void BinaryContext::addDynamicRelocation(uint64_t Address, MCSymbol *Symbol,
- uint64_t Type, uint64_t Addend,
+ uint32_t Type, uint64_t Addend,
uint64_t Value) {
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
assert(Section && "cannot find section for address");
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 35617a92c1b2a..a5dc188c98601 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -4614,7 +4614,7 @@ bool BinaryFunction::isAArch64Veneer() const {
}
void BinaryFunction::addRelocation(uint64_t Address, MCSymbol *Symbol,
- uint64_t RelType, uint64_t Addend,
+ uint32_t RelType, uint64_t Addend,
uint64_t Value) {
assert(Address >= getAddress() && Address < getAddress() + getMaxSize() &&
"address is outside of the function");
diff --git a/bolt/lib/Core/JumpTable.cpp b/bolt/lib/Core/JumpTable.cpp
index 65e1032c579b5..6f588d2b95fd6 100644
--- a/bolt/lib/Core/JumpTable.cpp
+++ b/bolt/lib/Core/JumpTable.cpp
@@ -84,7 +84,7 @@ void bolt::JumpTable::updateOriginal() {
const uint64_t BaseOffset = getAddress() - getSection().getAddress();
uint64_t EntryOffset = BaseOffset;
for (MCSymbol *Entry : Entries) {
- const uint64_t RelType =
+ const uint32_t RelType =
Type == JTT_NORMAL ? ELF::R_X86_64_64 : ELF::R_X86_64_PC32;
const uint64_t RelAddend =
Type == JTT_NORMAL ? 0 : EntryOffset - BaseOffset;
diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp
index 7ff7a2288451c..a3be147a09066 100644
--- a/bolt/lib/Core/MCPlusBuilder.cpp
+++ b/bolt/lib/Core/MCPlusBuilder.cpp
@@ -551,7 +551,7 @@ void MCPlusBuilder::initSizeMap() {
bool MCPlusBuilder::setOperandToSymbolRef(MCInst &Inst, int OpNum,
const MCSymbol *Symbol,
int64_t Addend, MCContext *Ctx,
- uint64_t RelType) const {
+ uint32_t RelType) const {
MCOperand Operand;
if (!Addend) {
Operand = MCOperand::createExpr(getTargetExprFor(
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index 523ab8480cc90..e91b6702c8d6c 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Object/ELF.h"
+#include "llvm/Object/ObjectFile.h"
using namespace llvm;
using namespace bolt;
@@ -29,7 +30,7 @@ enum {
Triple::ArchType Relocation::Arch;
-static bool isSupportedX86(uint64_t Type) {
+static bool isSupportedX86(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -52,7 +53,7 @@ static bool isSupportedX86(uint64_t Type) {
}
}
-static bool isSupportedAArch64(uint64_t Type) {
+static bool isSupportedAArch64(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -99,7 +100,7 @@ static bool isSupportedAArch64(uint64_t Type) {
}
}
-static bool isSupportedRISCV(uint64_t Type) {
+static bool isSupportedRISCV(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -131,7 +132,7 @@ static bool isSupportedRISCV(uint64_t Type) {
}
}
-static size_t getSizeForTypeX86(uint64_t Type) {
+static size_t getSizeForTypeX86(uint32_t Type) {
switch (Type) {
default:
errs() << object::getELFRelocationTypeName(ELF::EM_X86_64, Type) << '\n';
@@ -158,7 +159,7 @@ static size_t getSizeForTypeX86(uint64_t Type) {
}
}
-static size_t getSizeForTypeAArch64(uint64_t Type) {
+static size_t getSizeForTypeAArch64(uint32_t Type) {
switch (Type) {
default:
errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n';
@@ -208,7 +209,7 @@ static size_t getSizeForTypeAArch64(uint64_t Type) {
}
}
-static size_t getSizeForTypeRISCV(uint64_t Type) {
+static size_t getSizeForTypeRISCV(uint32_t Type) {
switch (Type) {
default:
errs() << object::getELFRelocationTypeName(ELF::EM_RISCV, Type) << '\n';
@@ -238,15 +239,15 @@ static size_t getSizeForTypeRISCV(uint64_t Type) {
}
}
-static bool skipRelocationTypeX86(uint64_t Type) {
+static bool skipRelocationTypeX86(uint32_t Type) {
return Type == ELF::R_X86_64_NONE;
}
-static bool skipRelocationTypeAArch64(uint64_t Type) {
+static bool skipRelocationTypeAArch64(uint32_t Type) {
return Type == ELF::R_AARCH64_NONE || Type == ELF::R_AARCH64_LD_PREL_LO19;
}
-static bool skipRelocationTypeRISCV(uint64_t Type) {
+static bool skipRelocationTypeRISCV(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -256,11 +257,11 @@ static bool skipRelocationTypeRISCV(uint64_t Type) {
}
}
-static bool skipRelocationProcessX86(uint64_t &Type, uint64_t Contents) {
+static bool skipRelocationProcessX86(uint32_t &Type, uint64_t Contents) {
return false;
}
-static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) {
+static bool skipRelocationProcessAArch64(uint32_t &Type, uint64_t Contents) {
auto IsMov = [](uint64_t Contents) -> bool {
// The bits 28-23 are 0b100101
return (Contents & 0x1f800000) == 0x12800000;
@@ -324,11 +325,11 @@ static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) {
return false;
}
-static bool skipRelocationProcessRISCV(uint64_t &Type, uint64_t Contents) {
+static bool skipRelocationProcessRISCV(uint32_t &Type, uint64_t Contents) {
return false;
}
-static uint64_t encodeValueX86(uint64_t Type, uint64_t Value, uint64_t PC) {
+static uint64_t encodeValueX86(uint32_t Type, uint64_t Value, uint64_t PC) {
switch (Type) {
default:
llvm_unreachable("unsupported relocation");
@@ -342,7 +343,7 @@ static uint64_t encodeValueX86(uint64_t Type, uint64_t Value, uint64_t PC) {
return Value;
}
-static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
+static uint64_t encodeValueAArch64(uint32_t Type, uint64_t Value, uint64_t PC) {
switch (Type) {
default:
llvm_unreachable("unsupported relocation");
@@ -374,7 +375,7 @@ static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
return Value;
}
-static uint64_t encodeValueRISCV(uint64_t Type, uint64_t Value, uint64_t PC) {
+static uint64_t encodeValueRISCV(uint32_t Type, uint64_t Value, uint64_t PC) {
switch (Type) {
default:
llvm_unreachable("unsupported relocation");
@@ -384,7 +385,7 @@ static uint64_t encodeValueRISCV(uint64_t Type, uint64_t Value, uint64_t PC) {
return Value;
}
-static uint64_t extractValueX86(uint64_t Type, uint64_t Contents, uint64_t PC) {
+static uint64_t extractValueX86(uint32_t Type, uint64_t Contents, uint64_t PC) {
if (Type == ELF::R_X86_64_32S)
return SignExtend64<32>(Contents);
if (Relocation::isPCRelative(Type))
@@ -392,7 +393,7 @@ static uint64_t extractValueX86(uint64_t Type, uint64_t Contents, uint64_t PC) {
return Contents;
}
-static uint64_t extractValueAArch64(uint64_t Type, uint64_t Contents,
+static uint64_t extractValueAArch64(uint32_t Type, uint64_t Contents,
uint64_t PC) {
switch (Type) {
default:
@@ -524,7 +525,7 @@ static uint64_t extractBImmRISCV(uint32_t Contents) {
(((Contents >> 7) & 0x1) << 11) | (((Contents >> 31) & 0x1) << 12));
}
-static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents,
+static uint64_t extractValueRISCV(uint32_t Type, uint64_t Contents,
uint64_t PC) {
switch (Type) {
default:
@@ -565,7 +566,7 @@ static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents,
}
}
-static bool isGOTX86(uint64_t Type) {
+static bool isGOTX86(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -585,7 +586,7 @@ static bool isGOTX86(uint64_t Type) {
}
}
-static bool isGOTAArch64(uint64_t Type) {
+static bool isGOTAArch64(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -602,7 +603,7 @@ static bool isGOTAArch64(uint64_t Type) {
}
}
-static bool isGOTRISCV(uint64_t Type) {
+static bool isGOTRISCV(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -612,7 +613,7 @@ static bool isGOTRISCV(uint64_t Type) {
}
}
-static bool isTLSX86(uint64_t Type) {
+static bool isTLSX86(uint32_t Type) {
switch (Type) {
default:
return false;
@@ -623,7 +624,7 @@ static bool isTLSX86(uint64_t Type) {
}
}
-static bool isTLSAArch64(uint64_t Type) {
+static bool isTLSAArch64(uint32_t Type) {
switch (Type) {
default:
...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks good, but please change the struct layout. Better yet, introduce Optional
in a new PR where it's being used.
It will be introduced in a separate PR.
Done, thanks Maksim. Removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
If no further comments I can merge by the EOD. |
Change the Relocation Type from uint64_t to uint32_t.
Add an Optional flag to relocations to indicate that they may be skipped.