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

Unified Diff: lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp

Issue 1269273002: Auto sandboxing: control flow expansions for ARM (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: fixed branch through sp Created 5 years, 4 months 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 | « lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.h ('k') | test/MC/ARM/nacl-autosandbox/branch.s » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp
index 060609f371f6635cf1456f93a6526124249295cb..c44937fc142f68b23f1b31eea2ca1a7ab550e9cf 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.cpp
@@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//
#include "ARMMCNaClExpander.h"
+#include "ARMAddressingModes.h"
+#include "MCTargetDesc/ARMBaseInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -23,9 +25,98 @@
using namespace llvm;
+const unsigned kBranchTargetMask = 0xC000000F;
+const unsigned kAlwaysPredicate = 14;
+
+static void emitBicMask(unsigned Mask, unsigned Reg, int64_t Pred,
+ MCStreamer &Out, const MCSubtargetInfo &STI) {
+ MCInst Bic;
+ const int32_t EncodedMask = ARM_AM::getSOImmVal(Mask);
+ Bic.setOpcode(ARM::BICri);
+ Bic.addOperand(MCOperand::CreateReg(Reg));
+ Bic.addOperand(MCOperand::CreateReg(Reg));
+ Bic.addOperand(MCOperand::CreateImm(EncodedMask));
+ Bic.addOperand(MCOperand::CreateImm(Pred));
+ Bic.addOperand(MCOperand::CreateReg(ARM::CPSR));
+ Bic.addOperand(MCOperand::CreateReg(0));
+ Out.EmitInstruction(Bic, STI);
+}
+
+void ARM::ARMMCNaClExpander::expandIndirectBranch(const MCInst &Inst,
+ MCStreamer &Out,
+ const MCSubtargetInfo &STI,
+ bool isCall) {
+ assert(Inst.getOperand(0).isReg());
+ // No need to sandbox branch through pc
+ if (Inst.getOperand(0).getReg() == ARM::PC ||
+ Inst.getOperand(0).getReg() == ARM::SP)
+ return Out.EmitInstruction(Inst, STI);
+
+ // Otherwise, mask target and branch through
+ Out.EmitBundleLock(isCall);
+
+ unsigned Reg = Inst.getOperand(0).getReg();
+ int64_t Pred = Inst.getNumOperands() > 1 ? Inst.getOperand(1).getImm()
+ : kAlwaysPredicate;
+ emitBicMask(kBranchTargetMask, Reg, Pred, Out, STI);
+
+ Out.EmitInstruction(Inst, STI);
+
+ Out.EmitBundleUnlock();
+}
+
+void ARM::ARMMCNaClExpander::expandCall(const MCInst &Inst, MCStreamer &Out,
+ const MCSubtargetInfo &STI) {
+ // Test for indirect call
+ if (Inst.getOperand(0).isReg()) {
+ expandIndirectBranch(Inst, Out, STI, true);
+ }
+
+ // Otherwise, we are a direct call, so just emit
+ else {
+ Out.EmitInstruction(Inst, STI);
+ }
+}
+
void ARM::ARMMCNaClExpander::doExpandInst(const MCInst &Inst, MCStreamer &Out,
const MCSubtargetInfo &STI) {
- Out.EmitInstruction(Inst, STI);
+ if (SaveCount == 0) {
+ switch (Inst.getOpcode()) {
+ case ARM::SFI_NOP_IF_AT_BUNDLE_END:
Derek Schuff 2015/08/05 06:11:44 It looks like this is the logic necessary to keep
+ SaveCount = 3;
+ break;
+ case ARM::SFI_DATA_MASK:
+ llvm_unreachable(
+ "SFI_DATA_MASK found without preceding SFI_NOP_IF_AT_BUNDLE_END");
+ break;
+ case ARM::SFI_GUARD_CALL:
+ case ARM::SFI_GUARD_INDIRECT_CALL:
+ case ARM::SFI_GUARD_INDIRECT_JMP:
+ case ARM::SFI_GUARD_RETURN:
+ case ARM::SFI_GUARD_LOADSTORE:
+ case ARM::SFI_GUARD_LOADSTORE_TST:
+ SaveCount = 2;
+ break;
+ case ARM::SFI_GUARD_SP_LOAD:
+ SaveCount = 4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (SaveCount == 0) {
+ if (isIndirectBranch(Inst)) {
+ return expandIndirectBranch(Inst, Out, STI, false);
+ } else if (isCall(Inst)) {
+ return expandCall(Inst, Out, STI);
+ } else {
+ return Out.EmitInstruction(Inst, STI);
+ }
+ } else {
+ SaveCount--;
+ Out.EmitInstruction(Inst, STI);
+ }
}
bool ARM::ARMMCNaClExpander::expandInst(const MCInst &Inst, MCStreamer &Out,
« no previous file with comments | « lib/Target/ARM/MCTargetDesc/ARMMCNaClExpander.h ('k') | test/MC/ARM/nacl-autosandbox/branch.s » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698