Index: src/IceInstX8664.cpp |
diff --git a/src/IceInstX8664.cpp b/src/IceInstX8664.cpp |
index a7236a3f67cd6f9de5992f8692927db97e7b81e3..6746b695730f7db1fc5a2af265fb90a9931f3c80 100644 |
--- a/src/IceInstX8664.cpp |
+++ b/src/IceInstX8664.cpp |
@@ -135,7 +135,14 @@ void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { |
// TODO(sehr): ConstantRelocatable still needs updating for |
// rematerializable base/index and Disp. |
assert(Disp == 0); |
+ if (Base == nullptr && Index == nullptr && NeedSandboxing) { |
+ llvm::report_fatal_error( |
+ "llvm-mc encodes rip-relative instructions incorrectly. Why?"); |
+ // Native code should be fine. The relocatable will be emitted with a |
+ // regular, absolute relocation. |
+ } |
const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
+ assert(!UseNonsfi); |
CR->emitWithoutPrefix(Func->getTarget(), UseNonsfi ? "@GOTOFF" : ""); |
} else { |
llvm_unreachable("Invalid offset type for x86 mem operand"); |
@@ -256,10 +263,12 @@ TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( |
if (getOffset() != nullptr) { |
if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
Disp += static_cast<int32_t>(CI->getValue()); |
- } else if (const auto CR = |
+ } else if (const auto *CR = |
llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
- Disp = CR->getOffset(); |
- Fixup = Asm->createFixup(FK_Abs, CR); |
+ const auto FixupKind = |
+ (getBase() != nullptr || getIndex() != nullptr) ? FK_Abs : FK_PcRel; |
+ Disp = CR->getOffset() - (FixupKind == FK_PcRel ? 4 : 0); |
+ Fixup = Asm->createFixup(FixupKind, CR); |
} else { |
llvm_unreachable("Unexpected offset type"); |
} |
@@ -290,7 +299,7 @@ TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( |
Fixup); |
} |
- return X8664::Traits::Address(Disp, Fixup); |
+ return X8664::Traits::Address::RipRelative(Disp, Fixup); |
} |
TargetX8664Traits::Address |