Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1491473002: Subzero. ARM32. Initial sandboxing code. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Renames run-pnacl-sz argument. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/assembler/arm32/sandboxing.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index d260db0e690cbeb7ee073421b491fd4dcb0edc5d..5469db1d5a19abc28989f8da1fa9f8b49b6fe926 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -161,7 +161,8 @@ TargetARM32Features::TargetARM32Features(const ClFlags &Flags) {
}
TargetARM32::TargetARM32(Cfg *Func)
- : TargetLowering(Func), CPUFeatures(Func->getContext()->getFlags()) {}
+ : TargetLowering(Func), NeedSandboxing(Ctx->getFlags().getUseSandboxing()),
+ CPUFeatures(Func->getContext()->getFlags()) {}
void TargetARM32::staticInit() {
// Limit this size (or do all bitsets need to be the same width)???
@@ -544,8 +545,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
return;
}
case Intrinsics::NaClReadTP: {
- if (Ctx->getFlags().getUseSandboxing()) {
- UnimplementedError(Func->getContext()->getFlags());
+ if (NeedSandboxing) {
return;
}
static constexpr SizeT MaxArgs = 0;
@@ -1120,6 +1120,10 @@ void TargetARM32::addProlog(CfgNode *Node) {
continue;
}
if (CalleeSaves[i] && RegsUsed[i]) {
+ if (NeedSandboxing && i == RegARM32::Reg_r9) {
+ // r9 is never updated in sandboxed code.
+ continue;
+ }
++NumCallee;
Variable *PhysicalRegister = getPhysicalRegister(i);
PreservedRegsSizeBytes +=
@@ -1173,10 +1177,9 @@ void TargetARM32::addProlog(CfgNode *Node) {
// Use the scratch register if needed to legalize the immediate.
Operand *SubAmount = legalize(Ctx->getConstantInt32(SpillAreaSizeBytes),
Legal_Reg | Legal_Flex, getReservedTmpReg());
- Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
- _sub(SP, SP, SubAmount);
+ AutoSandboxer(this).sub_sp(SubAmount);
if (FixedAllocaAlignBytes > ARM32_STACK_ALIGNMENT_BYTES) {
- alignRegisterPow2(SP, FixedAllocaAlignBytes);
+ AutoSandboxer(this).align_sp(FixedAllocaAlignBytes);
}
}
@@ -1270,7 +1273,7 @@ void TargetARM32::addEpilog(CfgNode *Node) {
// use of SP before the assignment of SP=FP keeps previous SP adjustments
// from being dead-code eliminated.
Context.insert(InstFakeUse::create(Func, SP));
- _mov(SP, FP);
+ AutoSandboxer(this).reset_sp(FP);
} else {
// add SP, SpillAreaSizeBytes
if (SpillAreaSizeBytes) {
@@ -1278,7 +1281,7 @@ void TargetARM32::addEpilog(CfgNode *Node) {
Operand *AddAmount =
legalize(Ctx->getConstantInt32(SpillAreaSizeBytes),
Legal_Reg | Legal_Flex, getReservedTmpReg());
- _add(SP, SP, AddAmount);
+ AutoSandboxer(this).add_sp(AddAmount);
}
}
@@ -1302,6 +1305,9 @@ void TargetARM32::addEpilog(CfgNode *Node) {
}
if (CalleeSaves[i] && RegsUsed[i]) {
+ if (NeedSandboxing && i == RegARM32::Reg_r9) {
+ continue;
+ }
GPRsToRestore.push_back(getPhysicalRegister(i));
}
}
@@ -1318,16 +1324,13 @@ void TargetARM32::addEpilog(CfgNode *Node) {
// bundle_unlock
// This isn't just aligning to the getBundleAlignLog2Bytes(). It needs to
// restrict to the lower 1GB as well.
- Operand *RetMask =
- legalize(Ctx->getConstantInt32(0xc000000f), Legal_Reg | Legal_Flex);
- Variable *LR = makeReg(IceType_i32, RegARM32::Reg_lr);
+ Variable *LR = getPhysicalRegister(RegARM32::Reg_lr);
Variable *RetValue = nullptr;
if (RI->getSrcSize())
RetValue = llvm::cast<Variable>(RI->getSrc(0));
- _bundle_lock();
- _bic(LR, LR, RetMask);
- _ret(LR, RetValue);
- _bundle_unlock();
+
+ AutoSandboxer(this).ret(LR, RetValue);
+
RI->setDeleted();
}
@@ -1378,7 +1381,7 @@ Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister(
OperandARM32Mem *TargetARM32::PostLoweringLegalizer::createMemOperand(
Type Ty, Variable *Base, int32_t Offset, bool AllowOffsets) {
assert(!Base->isRematerializable());
- if (AllowOffsets && Target->isLegalMemOffset(Ty, Offset)) {
+ if (Offset == 0 || (AllowOffsets && Target->isLegalMemOffset(Ty, Offset))) {
return OperandARM32Mem::create(
Target->Func, Ty, Base,
llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)),
@@ -1451,8 +1454,9 @@ void TargetARM32::PostLoweringLegalizer::legalizeMov(InstARM32Mov *MovInstr) {
assert(!SrcR->isRematerializable());
const int32_t Offset = Dest->getStackOffset();
// This is a _mov(Mem(), Variable), i.e., a store.
- Target->_str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset),
- MovInstr->getPredicate());
+ TargetARM32::AutoSandboxer(Target)
+ .str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset),
+ MovInstr->getPredicate());
// _str() does not have a Dest, so we add a fake-def(Dest).
Target->Context.insert(InstFakeDef::create(Target->Func, Dest));
Legalized = true;
@@ -1476,8 +1480,9 @@ void TargetARM32::PostLoweringLegalizer::legalizeMov(InstARM32Mov *MovInstr) {
if (!Var->hasReg()) {
// This is a _mov(Variable, Mem()), i.e., a load.
const int32_t Offset = Var->getStackOffset();
- Target->_ldr(Dest, createMemOperand(DestTy, StackOrFrameReg, Offset),
- MovInstr->getPredicate());
+ TargetARM32::AutoSandboxer(Target)
+ .ldr(Dest, createMemOperand(DestTy, StackOrFrameReg, Offset),
+ MovInstr->getPredicate());
Legalized = true;
}
}
@@ -1542,7 +1547,15 @@ TargetARM32::PostLoweringLegalizer::legalizeMemOperand(OperandARM32Mem *Mem,
Legalized = true;
}
- if (!Legalized) {
+ if (!Legalized && !Target->NeedSandboxing) {
+ return nullptr;
+ }
+
+ if (Target->NeedSandboxing && Base->getRegNum() == RegARM32::Reg_r9) {
+ if (Legalized) {
+ llvm::report_fatal_error("r9-based mem operand should not need to be "
+ "legalized.");
+ }
return nullptr;
}
@@ -1550,6 +1563,7 @@ TargetARM32::PostLoweringLegalizer::legalizeMemOperand(OperandARM32Mem *Mem,
return createMemOperand(Mem->getType(), Base, Offset, AllowOffsets);
}
+ assert(!Target->NeedSandboxing);
assert(MemTraits[Mem->getType()].CanHaveIndex);
if (Offset != 0) {
@@ -1621,7 +1635,8 @@ void TargetARM32::postLowerLegalization() {
} else if (auto *LdrInstr = llvm::dyn_cast<InstARM32Ldr>(CurInstr)) {
if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
llvm::cast<OperandARM32Mem>(LdrInstr->getSrc(0)))) {
- _ldr(CurInstr->getDest(), LegalMem, LdrInstr->getPredicate());
+ AutoSandboxer(this)
+ .ldr(CurInstr->getDest(), LegalMem, LdrInstr->getPredicate());
CurInstr->setDeleted();
}
} else if (auto *LdrexInstr = llvm::dyn_cast<InstARM32Ldrex>(CurInstr)) {
@@ -1629,14 +1644,16 @@ void TargetARM32::postLowerLegalization() {
if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
llvm::cast<OperandARM32Mem>(LdrexInstr->getSrc(0)),
DisallowOffsetsBecauseLdrex)) {
- _ldrex(CurInstr->getDest(), LegalMem, LdrexInstr->getPredicate());
+ AutoSandboxer(this)
+ .ldrex(CurInstr->getDest(), LegalMem, LdrexInstr->getPredicate());
CurInstr->setDeleted();
}
} else if (auto *StrInstr = llvm::dyn_cast<InstARM32Str>(CurInstr)) {
+ AutoSandboxer Bundle(this);
if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
llvm::cast<OperandARM32Mem>(StrInstr->getSrc(1)))) {
- _str(llvm::cast<Variable>(CurInstr->getSrc(0)), LegalMem,
- StrInstr->getPredicate());
+ AutoSandboxer(this).str(llvm::cast<Variable>(CurInstr->getSrc(0)),
+ LegalMem, StrInstr->getPredicate());
CurInstr->setDeleted();
}
} else if (auto *StrexInstr = llvm::dyn_cast<InstARM32Strex>(CurInstr)) {
@@ -1644,8 +1661,9 @@ void TargetARM32::postLowerLegalization() {
if (OperandARM32Mem *LegalMem = Legalizer.legalizeMemOperand(
llvm::cast<OperandARM32Mem>(StrexInstr->getSrc(1)),
DisallowOffsetsBecauseStrex)) {
- _strex(CurInstr->getDest(), llvm::cast<Variable>(CurInstr->getSrc(0)),
- LegalMem, StrexInstr->getPredicate());
+ AutoSandboxer(this).strex(CurInstr->getDest(),
+ llvm::cast<Variable>(CurInstr->getSrc(0)),
+ LegalMem, StrexInstr->getPredicate());
CurInstr->setDeleted();
}
}
@@ -1803,7 +1821,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) {
Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
if (OverAligned) {
- alignRegisterPow2(SP, Alignment);
+ AutoSandboxer(this).align_sp(Alignment);
}
Variable *Dest = Inst->getDest();
@@ -1828,7 +1846,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) {
// in Dest.
Operand *SubAmountRF =
legalize(Ctx->getConstantInt32(Value), Legal_Reg | Legal_Flex);
- _sub(SP, SP, SubAmountRF);
+ AutoSandboxer(this).sub_sp(SubAmountRF);
} else {
// Non-constant sizes need to be adjusted to the next highest multiple of
// the required alignment at runtime.
@@ -1838,7 +1856,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) {
Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1));
_add(T, T, AddAmount);
alignRegisterPow2(T, Alignment);
- _sub(SP, SP, T);
+ AutoSandboxer(this).sub_sp(T);
}
// Adds back a few bytes to SP to account for the out args area.
@@ -3249,8 +3267,6 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
break;
}
}
- // TODO(jvoung): Handle sandboxing. const bool NeedSandboxing =
- // Ctx->getFlags().getUseSandboxing();
// Allow ConstantRelocatable to be left alone as a direct call, but force
// other constants like ConstantInteger32 to be in a register and make it an
@@ -3271,8 +3287,10 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
// the call.
Context.insert(InstFakeUse::create(Func, Reg));
}
- Inst *NewCall = InstARM32Call::create(Func, ReturnReg, CallTarget);
- Context.insert(NewCall);
+
+ InstARM32Call *NewCall = AutoSandboxer(this, InstBundleLock::Opt_AlignToEnd)
+ .bl(ReturnReg, CallTarget);
+
if (ReturnRegHi)
Context.insert(InstFakeDef::create(Func, ReturnRegHi));
@@ -4612,7 +4630,14 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
llvm::report_fatal_error("memmove should have been prelowered.");
}
case Intrinsics::NaClReadTP: {
- llvm::report_fatal_error("nacl-read-tp should have been prelowered.");
+ if (!NeedSandboxing) {
+ llvm::report_fatal_error("nacl-read-tp should have been prelowered.");
+ }
+ Variable *TP = legalizeToReg(OperandARM32Mem::create(
+ Func, getPointerType(), getPhysicalRegister(RegARM32::Reg_r9),
+ llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))));
+ _mov(Dest, TP);
+ return;
}
case Intrinsics::Setjmp: {
llvm::report_fatal_error("setjmp should have been prelowered.");
@@ -4630,9 +4655,8 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Stackrestore: {
- Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
- Operand *Val = legalize(Instr->getArg(0), Legal_Reg | Legal_Flex);
- _mov_redefined(SP, Val);
+ Variable *Val = legalizeToReg(Instr->getArg(0));
+ AutoSandboxer(this).reset_sp(Val);
return;
}
case Intrinsics::Trap:
@@ -4987,8 +5011,9 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func,
(void)MemTraitsSize;
assert(Ty < MemTraitsSize);
auto *TypeTraits = &MemTraits[Ty];
- const bool CanHaveIndex = TypeTraits->CanHaveIndex;
- const bool CanHaveShiftedIndex = TypeTraits->CanHaveShiftedIndex;
+ const bool CanHaveIndex = !NeedSandboxing && TypeTraits->CanHaveIndex;
+ const bool CanHaveShiftedIndex =
+ !NeedSandboxing && TypeTraits->CanHaveShiftedIndex;
const bool CanHaveImm = TypeTraits->CanHaveImm;
const int32_t ValidImmMask = TypeTraits->ValidImmMask;
(void)ValidImmMask;
@@ -5160,6 +5185,7 @@ void TargetARM32::lowerRet(const InstRet *Inst) {
// frame removal instructions. addEpilog is responsible for restoring the
// "lr" register as needed prior to this ret instruction.
_ret(getPhysicalRegister(RegARM32::Reg_lr), Reg);
+
// Add a fake use of sp to make sure sp stays alive for the entire function.
// Otherwise post-call sp adjustments get dead-code eliminated.
// TODO: Are there more places where the fake use should be inserted? E.g.
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/assembler/arm32/sandboxing.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698