Fix incomplete trap metadata due to multiple traps at one address.
If an instruction has more than one trap record associated with it (for example: a divide instruction that has participated in load-op fusion, so we have both a heap-out-of-bounds trap record due to its load and a divide-by-zero trap record due to its divide op), the current MachBuffer code would emit only one of the trap records to the sink. Separately, divide instructions probably shouldn't merge loads, because the two separate possible traps at one location might be confusing for some embedders (certainly in Lucet). Divide seems to be the only case in our current codegen where such merging might occur. This PR changes the lowering to always force the divisor into a register. Finally, while working out why trap records were not appearing, I had noticed that `isa::x64::emit_std_enc_mem()` was only emitting heap-OOB trap metadata for loads/stores when it had a srcloc. This PR ensures that the metadata is emitted even when the srcloc is empty. Note that none of the above presents a security or correctness problem; trap metadata only affects the status that we return to the embedder when a Wasm program terminates with a trap.
This commit is contained in:
@@ -5113,7 +5113,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
));
|
||||
ctx.emit(Inst::checked_div_or_rem_seq(kind, size, divisor_copy, tmp));
|
||||
} else {
|
||||
let divisor = input_to_reg_mem(ctx, inputs[1]);
|
||||
// We don't want more than one trap record for a single instruction,
|
||||
// so let's not allow the "mem" case (load-op merging) here; force
|
||||
// divisor into a register instead.
|
||||
let divisor = RegMem::reg(put_input_in_reg(ctx, inputs[1]));
|
||||
|
||||
// Fill in the high parts:
|
||||
if kind.is_signed() {
|
||||
|
||||
Reference in New Issue
Block a user