Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 1ce51a0

Browse files
committed
Add support for using MI bundles as bundle-locked groups on x86
Use it to sandbox lea instructions with esp as the destination Review URL: https://codereview.chromium.org/1137803004/
1 parent ce55737 commit 1ce51a0

File tree

3 files changed

+68
-13
lines changed

3 files changed

+68
-13
lines changed

lib/Target/X86/X86MCInstLower.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,22 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
10071007
X86MCInstLower MCInstLowering(*MF, *this);
10081008
const X86RegisterInfo *RI = MF->getSubtarget<X86Subtarget>().getRegisterInfo();
10091009

1010+
// @LOCALMOD-START
1011+
// MI Bundles are used to represent bundle-locked groups.
1012+
// MBB iterators skip bundles, so when we reach a bundle head, unpack it here.
1013+
if (MI->isBundle()) {
1014+
MachineBasicBlock::const_iterator MBBI(MI);
1015+
MachineBasicBlock::const_instr_iterator MII (MBBI.getInstrIterator());
1016+
++MBBI;
1017+
OutStreamer.EmitBundleLock(false);
1018+
while (++MII != MBBI) {
1019+
EmitInstruction(MII);
1020+
}
1021+
OutStreamer.EmitBundleUnlock();
1022+
return;
1023+
}
1024+
// @LOCALMOD-END
1025+
10101026
switch (MI->getOpcode()) {
10111027
case TargetOpcode::DBG_VALUE:
10121028
llvm_unreachable("Should be handled target independently");

lib/Target/X86/X86NaClRewritePass.cpp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,37 @@ bool X86NaClRewritePass::ApplyStackSFI(MachineBasicBlock &MBB,
260260
return true;
261261
}
262262

263-
// Promote 32-bit lea to 64-bit lea (does this ever happen?)
264263
assert(Opc != X86::LEA32r && "Invalid opcode in 64-bit mode!");
265-
if (Opc == X86::LEA64_32r) {
266-
unsigned DestReg = MI.getOperand(0).getReg();
264+
if (Opc == X86::LEA64_32r){
267265
unsigned BaseReg = MI.getOperand(1).getReg();
268-
unsigned Scale = MI.getOperand(2).getImm();
269-
unsigned IndexReg = MI.getOperand(3).getReg();
270-
assert(DestReg == X86::ESP);
271-
assert(Scale == 1);
272-
assert(BaseReg == X86::EBP);
273-
assert(IndexReg == 0);
274-
MI.getOperand(0).setReg(X86::RSP);
275-
MI.getOperand(1).setReg(X86::RBP);
276-
MI.setDesc(TII->get(X86::LEA64r));
277-
Opc = X86::LEA64r;
266+
if (BaseReg == X86::EBP) {
267+
// leal N(%ebp), %esp can be promoted to leaq N(%rbp), %rsp, which
268+
// converts to SPAJDi32 below.
269+
unsigned DestReg = MI.getOperand(0).getReg();
270+
unsigned Scale = MI.getOperand(2).getImm();
271+
unsigned IndexReg = MI.getOperand(3).getReg();
272+
assert(DestReg == X86::ESP);
273+
assert(Scale == 1);
274+
assert(BaseReg == X86::EBP);
275+
assert(IndexReg == 0);
276+
MI.getOperand(0).setReg(X86::RSP);
277+
MI.getOperand(1).setReg(X86::RBP);
278+
MI.setDesc(TII->get(X86::LEA64r));
279+
Opc = X86::LEA64r;
280+
} else {
281+
// Create a MachineInstr bundle (i.e. a bundle-locked group) and fix up
282+
// the stack pointer by adding R15. TODO(dschuff): generalize this for
283+
// other uses if needed, and try to replace some pseudos if
284+
// possible. Eventually replace with auto-sandboxing.
285+
auto NextMBBI = MBBI;
286+
++NextMBBI;
287+
BuildMI(MBB, NextMBBI, MBBI->getDebugLoc(),
288+
TII->get(X86::ADD64rr), X86::RSP)
289+
.addReg(X86::RSP).addReg(X86::R15);
290+
MIBundleBuilder(MBB, MBBI, NextMBBI);
291+
finalizeBundle(MBB, MBBI.getInstrIterator());
292+
return true;
293+
}
278294
}
279295

280296
if (Opc == X86::LEA64r && MatchesSPAdj(MI)) {

test/NaCl/X86/dynamic-stack-alloc2.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: llc -mtriple=x86_64-nacl %s -o - | FileCheck %s
2+
3+
target datalayout = "e-p:32:32-i64:64-n32"
4+
target triple = "le32-unknown-nacl"
5+
6+
; CHECK-LABEL: @foo
7+
; CHECK: .bundle_lock
8+
; CHECK: leal -16({{.*}}), %esp
9+
; CHECK: addq %r15, %rsp
10+
; CHECK: .bundle_unlock
11+
define hidden void @foo() {
12+
entry:
13+
br label %bb1
14+
; The alloca must be in a non-entry block so it gets lowered in the dag as
15+
; a dynamic_stackalloc node
16+
bb1:
17+
%0 = alloca i8, i32 16, align 16
18+
%1 = load i8, i8* %0, align 1
19+
%call5 = call i32 @bar(i8 %1)
20+
unreachable
21+
}
22+
23+
declare hidden i32 @bar(i8)

0 commit comments

Comments
 (0)