| Index: src/IceTargetLoweringX8632.cpp | 
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp | 
| index 0467320c68d16a3f32c6bb6a51486c7651bb2d92..1e4d28274ebfa4713f92713966d288e551af73ad 100644 | 
| --- a/src/IceTargetLoweringX8632.cpp | 
| +++ b/src/IceTargetLoweringX8632.cpp | 
| @@ -963,6 +963,29 @@ void TargetX8632::addEpilog(CfgNode *Node) { | 
| _pop(getPhysicalRegister(j)); | 
| } | 
| } | 
| + | 
| +  if (!Ctx->getFlags().getUseSandboxing()) | 
| +    return; | 
| +  // Change the original ret instruction into a sandboxed return sequence. | 
| +  // t:ecx = pop | 
| +  // bundle_lock | 
| +  // and t, ~31 | 
| +  // jmp *t | 
| +  // bundle_unlock | 
| +  // FakeUse <original_ret_operand> | 
| +  const SizeT BundleSize = 1 | 
| +                           << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 
| +  Variable *T_ecx = makeReg(IceType_i32, RegX8632::Reg_ecx); | 
| +  _pop(T_ecx); | 
| +  _bundle_lock(); | 
| +  _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1))); | 
| +  _jmp(T_ecx); | 
| +  _bundle_unlock(); | 
| +  if (RI->getSrcSize()) { | 
| +    Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0)); | 
| +    Context.insert(InstFakeUse::create(Func, RetValue)); | 
| +  } | 
| +  RI->setDeleted(); | 
| } | 
|  | 
| void TargetX8632::split64(Variable *Var) { | 
| @@ -1815,8 +1838,24 @@ void TargetX8632::lowerCall(const InstCall *Instr) { | 
| } | 
| } | 
| Operand *CallTarget = legalize(Instr->getCallTarget()); | 
| +  const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 
| +  if (NeedSandboxing) { | 
| +    if (llvm::isa<Constant>(CallTarget)) { | 
| +      _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 
| +    } else { | 
| +      Variable *CallTargetVar = nullptr; | 
| +      _mov(CallTargetVar, CallTarget); | 
| +      _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 
| +      const SizeT BundleSize = | 
| +          1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 
| +      _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1))); | 
| +      CallTarget = CallTargetVar; | 
| +    } | 
| +  } | 
| Inst *NewCall = InstX8632Call::create(Func, ReturnReg, CallTarget); | 
| Context.insert(NewCall); | 
| +  if (NeedSandboxing) | 
| +    _bundle_unlock(); | 
| if (ReturnRegHi) | 
| Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 
|  | 
| @@ -3829,6 +3868,9 @@ void TargetX8632::lowerRet(const InstRet *Inst) { | 
| _mov(Reg, Src0, RegX8632::Reg_eax); | 
| } | 
| } | 
| +  // Add a ret instruction even if sandboxing is enabled, because | 
| +  // addEpilog explicitly looks for a ret instruction as a marker for | 
| +  // where to insert the frame removal instructions. | 
| _ret(Reg); | 
| // Add a fake use of esp to make sure esp stays alive for the entire | 
| // function.  Otherwise post-call esp adjustments get dead-code | 
|  |