[WIP] Add a Trap sink to code generation (#279)

* First draft of TrapSink implementation.

* Add trap sink calls to 'trapif' and 'trapff' recipes.

* Add SourceLoc to trap sink calls, and add trap sink calls to all loads and stores.

* Add IntegerDivisionByZero trap to div recipe.

* Only emit load/store traps if 'notrap' flag is not set on the instruction.

* Update filetest machinery to add new trap sink functionality.

* Update filetests to include traps in output.

* Add a few more trap outputs to filetests.

* Add trap output to CLI tool.
This commit is contained in:
Tyler McMullen
2018-03-28 22:48:03 -07:00
committed by Dan Gohman
parent d566faa8fb
commit 951ff11f85
12 changed files with 358 additions and 263 deletions

View File

@@ -278,7 +278,10 @@ null = EncRecipe('null', Unary, size=0, ins=GPR, outs=0, emit='')
# XX opcode, no ModR/M.
trap = TailRecipe(
'trap', Trap, size=0, ins=(), outs=(),
emit='PUT_OP(bits, BASE_REX, sink);')
emit='''
sink.trap(code, func.srclocs[inst]);
PUT_OP(bits, BASE_REX, sink);
''')
# Macro: conditional jump over a ud2.
trapif = EncRecipe(
@@ -289,6 +292,7 @@ trapif = EncRecipe(
sink.put1(0x70 | (icc2opc(cond.inverse()) as u8));
sink.put1(2);
// ud2.
sink.trap(code, func.srclocs[inst]);
sink.put1(0x0f);
sink.put1(0x0b);
''')
@@ -302,6 +306,7 @@ trapff = EncRecipe(
sink.put1(0x70 | (fcc2opc(cond.inverse()) as u8));
sink.put1(2);
// ud2.
sink.trap(code, func.srclocs[inst]);
sink.put1(0x0f);
sink.put1(0x0b);
''')
@@ -450,6 +455,7 @@ div = TailRecipe(
'div', Ternary, size=1,
ins=(GPR.rax, GPR.rdx, GPR), outs=(GPR.rax, GPR.rdx),
emit='''
sink.trap(TrapCode::IntegerDivisionByZero, func.srclocs[inst]);
PUT_OP(bits, rex1(in_reg2), sink);
modrm_r_bits(in_reg2, bits, sink);
''')
@@ -678,6 +684,9 @@ st = TailRecipe(
instp=IsEqual(Store.offset, 0),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink);
''')
@@ -690,6 +699,9 @@ st_abcd = TailRecipe(
when_prefixed=st,
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink);
''')
@@ -700,6 +712,9 @@ fst = TailRecipe(
instp=IsEqual(Store.offset, 0),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink);
''')
@@ -710,6 +725,9 @@ stDisp8 = TailRecipe(
instp=IsSignedInt(Store.offset, 8),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -721,6 +739,9 @@ stDisp8_abcd = TailRecipe(
when_prefixed=stDisp8,
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -731,6 +752,9 @@ fstDisp8 = TailRecipe(
instp=IsSignedInt(Store.offset, 8),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -742,6 +766,9 @@ stDisp32 = TailRecipe(
'stDisp32', Store, size=5, ins=(GPR, GPR_DEREF_SAFE), outs=(),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -752,6 +779,9 @@ stDisp32_abcd = TailRecipe(
when_prefixed=stDisp32,
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -761,6 +791,9 @@ fstDisp32 = TailRecipe(
'fstDisp32', Store, size=5, ins=(FPR, GPR_DEREF_SAFE), outs=(),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink);
let offset: i32 = offset.into();
@@ -827,6 +860,9 @@ ld = TailRecipe(
instp=IsEqual(Load.offset, 0),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rm(in_reg0, out_reg0, sink);
''')
@@ -837,6 +873,9 @@ fld = TailRecipe(
instp=IsEqual(Load.offset, 0),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rm(in_reg0, out_reg0, sink);
''')
@@ -847,6 +886,9 @@ ldDisp8 = TailRecipe(
instp=IsSignedInt(Load.offset, 8),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp8(in_reg0, out_reg0, sink);
let offset: i32 = offset.into();
@@ -859,6 +901,9 @@ fldDisp8 = TailRecipe(
instp=IsSignedInt(Load.offset, 8),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp8(in_reg0, out_reg0, sink);
let offset: i32 = offset.into();
@@ -871,6 +916,9 @@ ldDisp32 = TailRecipe(
instp=IsSignedInt(Load.offset, 32),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp32(in_reg0, out_reg0, sink);
let offset: i32 = offset.into();
@@ -883,6 +931,9 @@ fldDisp32 = TailRecipe(
instp=IsSignedInt(Load.offset, 32),
clobbers_flags=False,
emit='''
if !flags.notrap() {
sink.trap(TrapCode::HeapOutOfBounds, func.srclocs[inst]);
}
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp32(in_reg0, out_reg0, sink);
let offset: i32 = offset.into();