| Index: src/IceTargetLoweringX8664.cpp
|
| diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
|
| index c023949476080c5e6c75bad4a001fd1fb4d4886e..ca92c171a8c34553e9653ff3d472902cf3fe4cd3 100644
|
| --- a/src/IceTargetLoweringX8664.cpp
|
| +++ b/src/IceTargetLoweringX8664.cpp
|
| @@ -297,33 +297,48 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
|
| // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.)
|
| // NaCl sandboxing also requires that any registers that are not %rsp and
|
| // %rbp to be 'truncated' to 32-bit before memory access.
|
| - assert(NeedSandboxing);
|
| + if (SandboxingType == ST_None) {
|
| + return Mem;
|
| + }
|
| +
|
| + if (SandboxingType == ST_Nonsfi) {
|
| + llvm::report_fatal_error(
|
| + "_sandbox_mem_reference not implemented for nonsfi");
|
| + }
|
| +
|
| Variable *Base = Mem->getBase();
|
| Variable *Index = Mem->getIndex();
|
| uint16_t Shift = 0;
|
| - Variable *r15 =
|
| + Variable *ZeroReg =
|
| getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
|
| Constant *Offset = Mem->getOffset();
|
| Variable *T = nullptr;
|
|
|
| if (Mem->getIsRebased()) {
|
| // If Mem.IsRebased, then we don't need to update Mem to contain a reference
|
| - // to %r15, but we still need to truncate Mem.Index (if any) to 32-bit.
|
| - assert(r15 == Base);
|
| - T = Index;
|
| - Shift = Mem->getShift();
|
| - } else if (Base != nullptr && Index != nullptr) {
|
| - // Another approach could be to emit an
|
| - //
|
| - // lea Mem, %T
|
| - //
|
| - // And then update Mem.Base = r15, Mem.Index = T, Mem.Shift = 0
|
| - llvm::report_fatal_error("memory reference contains base and index.");
|
| - } else if (Base != nullptr) {
|
| - T = Base;
|
| - } else if (Index != nullptr) {
|
| - T = Index;
|
| + // to a valid base register (%r15, %rsp, or %rbp), but we still need to
|
| + // truncate Mem.Index (if any) to 32-bit.
|
| + assert(ZeroReg == Base || Base->isRematerializable());
|
| + T = makeReg(IceType_i32);
|
| + _mov(T, Index);
|
| Shift = Mem->getShift();
|
| + } else {
|
| + if (Base != nullptr) {
|
| + if (Base->isRematerializable()) {
|
| + ZeroReg = Base;
|
| + } else {
|
| + T = Base;
|
| + }
|
| + }
|
| +
|
| + if (Index != nullptr) {
|
| + assert(!Index->isRematerializable());
|
| + if (T != nullptr) {
|
| + llvm::report_fatal_error("memory reference contains base and index.");
|
| + }
|
| + T = Index;
|
| + Shift = Mem->getShift();
|
| + }
|
| }
|
|
|
| // NeedsLea is a flags indicating whether Mem needs to be materialized to a
|
| @@ -398,7 +413,7 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
|
|
|
| static constexpr bool IsRebased = true;
|
| return Traits::X86OperandMem::create(
|
| - Func, Mem->getType(), r15, Offset, T, Shift,
|
| + Func, Mem->getType(), ZeroReg, Offset, T, Shift,
|
| Traits::X86OperandMem::DefaultSegment, IsRebased);
|
| }
|
|
|
| @@ -426,8 +441,23 @@ void TargetX8664::_sub_sp(Operand *Adjustment) {
|
| _add(rsp, r15);
|
| }
|
|
|
| +void TargetX8664::initRebasePtr() {
|
| + switch (SandboxingType) {
|
| + case ST_Nonsfi:
|
| + // Probably no implementation is needed, but error to be safe for now.
|
| + llvm::report_fatal_error(
|
| + "initRebasePtr() is not yet implemented on x32-nonsfi.");
|
| + case ST_NaCl:
|
| + RebasePtr = getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
|
| + break;
|
| + case ST_None:
|
| + // nothing.
|
| + break;
|
| + }
|
| +}
|
| +
|
| void TargetX8664::initSandbox() {
|
| - assert(NeedSandboxing);
|
| + assert(SandboxingType == ST_NaCl);
|
| Context.init(Func->getEntryNode());
|
| Context.setInsertPoint(Context.getCur());
|
| Variable *r15 =
|
| @@ -436,6 +466,45 @@ void TargetX8664::initSandbox() {
|
| Context.insert<InstFakeUse>(r15);
|
| }
|
|
|
| +namespace {
|
| +bool isRematerializable(const Variable *Var) {
|
| + return Var != nullptr && Var->isRematerializable();
|
| +}
|
| +} // end of anonymous namespace
|
| +
|
| +bool TargetX8664::legalizeOptAddrForSandbox(OptAddr *Addr) {
|
| + if (SandboxingType == ST_Nonsfi) {
|
| + llvm::report_fatal_error("Nonsfi not yet implemented for x8664.");
|
| + }
|
| +
|
| + if (isRematerializable(Addr->Base)) {
|
| + if (Addr->Index == RebasePtr) {
|
| + Addr->Index = nullptr;
|
| + Addr->Shift = 0;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + if (isRematerializable(Addr->Index)) {
|
| + if (Addr->Base == RebasePtr) {
|
| + Addr->Base = nullptr;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + assert(Addr->Base != RebasePtr && Addr->Index != RebasePtr);
|
| +
|
| + if (Addr->Base == nullptr) {
|
| + return true;
|
| + }
|
| +
|
| + if (Addr->Index == nullptr) {
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| void TargetX8664::lowerIndirectJump(Variable *JumpTarget) {
|
| std::unique_ptr<AutoBundle> Bundler;
|
|
|
|
|