[llvm] MC: Centralize X86 PC-relative fixup adjustment in MCAssembler (PR #147113)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 8 00:42:43 PDT 2025
================
@@ -683,6 +683,35 @@ static unsigned getFixupKindSize(unsigned Kind) {
}
}
+// Adjust PC-relative fixup offsets, which are calculated from the start of the
+// next instruction.
+std::optional<bool> X86AsmBackend::evaluateFixup(const MCFragment &,
+ MCFixup &Fixup,
+ MCValue &Target, uint64_t &) {
+ if (Fixup.isPCRel()) {
+ switch (Fixup.getTargetKind()) {
+ case FK_Data_1:
+ Target.setConstant(Target.getConstant() - 1);
+ break;
+ case FK_Data_2:
+ Target.setConstant(Target.getConstant() - 2);
+ break;
+ default: {
+ Target.setConstant(Target.getConstant() - 4);
+ auto *Add = Target.getAddSym();
+ // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
+ // leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
+ // this needs to be a GOTPC32 relocation.
+ if (Add && Add->getName() == "_GLOBAL_OFFSET_TABLE_")
----------------
MaskRay wrote:
In 2020, I implemented this code path for all PC-relative fixups in https://reviews.llvm.org/D47507 (I overlooked adding corresponding mov tests).
The current implementation is guarded by `if (Fixup.isPCRel()) {`, reflecting the original intention. I think testing the magic symbol during the relocation decision phase (https://maskray.me/blog/2025-03-16-relocation-generation-in-assemblers#relocation-decision-phase) is the correct approach. Transitioning another `startsWithGlobalOffsetTable` caller in X86MCCodeEmitter.cpp to use X86MCAsmBackend.cpp would be ideal, but that falls outside this change’s scope. X86MCCodeEmitter.cpp has quite a lot of tech debt.
https://github.com/llvm/llvm-project/pull/147113
More information about the llvm-commits
mailing list