Stream: git-wasmtime

Topic: wasmtime / Issue #2082 Cranelift: broken two-way jump in ...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 30 2020 at 19:48):

bnjbvr opened Issue #2082:

This has taken some time to track down, but I eventually managed to pinpoint to one function that was sufficient to trigger the crash in Firefox, and so I went on and ran Firefox in a debugger, stepping in until i could see where control flow seemed to go wrong.

Here's a summary of the input function, plus a runtime trace to explicit where the bug is (and where i observed the crash):

<details><summary>Clif test</summary>

function u0:7705(i32, i64 vmctx) baldrdash_system_v {
    gv0 = vmctx
    gv1 = load.i64 notrap aligned readonly gv0
    gv2 = iadd_imm.i64 gv0, 56
    heap0 = static gv1, min 0x0100_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    jt0 = jump_table [block14, block13]

block0(v0: i32, v1: i64):
    v31 -> v0
    v32 -> v31
    v2 = iconst.i32 0
    v3 = heap_addr.i64 heap0, v0, 1
    v4 = sload16.i32 v3+420
    v5 = iconst.i32 0xffff
    v6 = band v4, v5
    v14 -> v6
    v29 -> v14
    v7 = iconst.i32 524
    v8 = iadd v0, v7
    v17 -> v8
    v30 -> v17
    brz v4, block15
    jump block6

block6:
    v9 = iconst.i32 0
    v10 = iconst.i32 0
    jump block7(v9, v10)

block7(v13: i32, v52: i32):
    v26 -> v13
    v11 = global_value.i64 gv2
    v12 = load.i32 notrap aligned v11
    resumable_trapnz v12, interrupt
    v15 = icmp sge v13, v14
    v16 = bint.i32 v15
    brnz v16, block4(v31, v52, v14, v17)
    jump block10

block10:
    v18 = heap_addr.i64 heap0, v17, 1
    v19 = load.i32 v18
    v20 = iadd v19, v13
    v21 = heap_addr.i64 heap0, v20, 1
    v22 = sload8.i32 v21
    v23 = iconst.i32 -1
    v24 = isub v22, v23
    br_table v24, block12, jt0

block14:
    jump block11(v52)

block13:
    v25 = iconst.i32 1
    jump block11(v25)

block12:
    jump block9

block11(v53: i32):
    v27 = iconst.i32 1
    v28 = iadd.i32 v13, v27
    jump block7(v28, v53)

block9:
    jump block8

block8:
    v33 = heap_addr.i64 heap0, v0, 1
    v34 = load.i32 v33+216
    jump block5

block15:
    v35 = iconst.i32 0
    jump block4(v0, v35, v6, v8)

block5:
    jump block3(v34, v0, v14, v17)

block4(v36: i32, v51: i32, v111: i32, v114: i32):
    v65 -> v36
    v110 -> v111
    v113 -> v114
    v37 = iconst.i32 216
    v38 = iadd v36, v37
    v39 = heap_addr.i64 heap0, v38, 1
    v40 = load.i32 v39
    v41 = iconst.i32 0xffff_ffff_ff7f_ffff
    v42 = band v40, v41
    v43 = heap_addr.i64 heap0, v38, 1
    store v42, v43
    v44 = iconst.i32 212
    v45 = iadd v36, v44
    v46 = heap_addr.i64 heap0, v45, 1
    v47 = load.i32 v46
    v48 = iconst.i32 -8193
    v49 = band v47, v48
    v50 = heap_addr.i64 heap0, v45, 1
    store v49, v50
    brz v51, block18
    jump block17

block17:
    jump block16(v42)

block18:
    v54 = iconst.i32 0xffff_ffff_ff7f_fe7f
    v55 = band.i32 v40, v54
    v56 = heap_addr.i64 heap0, v38, 1
    store v55, v56
    jump block16(v55)

block16(v58: i32):
    jump block3(v58, v65, v110, v113)

block3(v57: i32, v64: i32, v109: i32, v112: i32):
    v95 -> v109
    v98 -> v112
    v59 = iconst.i32 4352
    v60 = band v57, v59
    v61 = iconst.i32 4352
    v62 = icmp eq v60, v61
    v63 = bint.i32 v62
    brz v63, block20
    jump block21

block21:
    v66 = heap_addr.i64 heap0, v64, 1
    v67 = load.i32 v66+408
    v68 = heap_addr.i64 heap0, v64, 1
    v69 = uload8.i32 v68+448
    v70 = iconst.i32 3
    v71 = imul v69, v70
    v72 = iadd v67, v71
    v73 = heap_addr.i64 heap0, v72, 1
    v74 = uload8.i32 v73
    v75 = heap_addr.i64 heap0, v64, 1
    istore16 v74, v75+450
    v76 = iconst.i32 3
    v77 = imul v69, v76
    v78 = iadd v67, v77
    v79 = heap_addr.i64 heap0, v78, 1
    v80 = uload8.i32 v79+1
    v81 = heap_addr.i64 heap0, v64, 1
    istore16 v80, v81+452
    v82 = iadd v67, v77
    v83 = heap_addr.i64 heap0, v82, 1
    v84 = uload8.i32 v83+2
    v85 = heap_addr.i64 heap0, v64, 1
    istore16 v84, v85+454
    v86 = iconst.i32 0x0208_0000
    v87 = band.i32 v57, v86
    v88 = iconst.i32 0x0008_0000
    v89 = icmp eq v87, v88
    v90 = bint.i32 v89
    brz v90, block22
    jump block23

block23:
    v91 = iconst.i32 0
    jump block24(v91)

block24(v94: i32):
    v92 = global_value.i64 gv2
    v93 = load.i32 notrap aligned v92
    resumable_trapnz v93, interrupt
    v96 = icmp eq v94, v95
    v97 = bint.i32 v96
    brnz v97, block19
    jump block26

block26:
    v99 = heap_addr.i64 heap0, v98, 1
    v100 = load.i32 v99
    v101 = iadd v100, v94
    v102 = heap_addr.i64 heap0, v101, 1
    v103 = sload8.i32 v102
    v104 = iconst.i32 -1
    v105 = bxor v103, v104
    v106 = heap_addr.i64 heap0, v101, 1
    istore8 v105, v106
    v107 = iconst.i32 1
    v108 = iadd.i32 v94, v107
    jump block24(v108)

block22:
    jump block20

block20:
    jump block19

block19:
    jump block2

block2:
    jump block1

block1:
    fallthrough_return
}

</details>

<details><summary>x64 trace</summary>

don't pay attention to the codegen inefficiencies (yet)

VCode_ShowWithRRU {{
  Entry block: 0
Block 0:
  (original IR block: block0)
  (successor: Block 1)
  (successor: Block 3)
  (instruction range: 0 .. 14)
  Inst 0:   pushq   %rbx
  Inst 1:   pushq   %r12
  Inst 2:   pushq   %r13
  Inst 3:   virtual_sp_offset_adjust 24
  Inst 4:   movl    %edi, %ebx // edi = ebx = 0xbb0508 @ 0xbb0668
  Inst 5:   movq    %r15/pinned, %r12 // r15 = r12 = 0x7ffe52af0000
  Inst 6:   addq    %rbx, %r12 // r12 = 0x7ffe536a0508
  Inst 7:   movswq  420(%r12), %rsi // rsi = 0
  Inst 8:   movq    %rsi, %r12 // r12 = 0
  Inst 9:   andl    $65535, %r12d // 0
  Inst 10:   movq    %rdi, %r13 // rdi = r13 = 0xbb0508
  Inst 11:   addl    $524, %r13d // 0xbb0714 @ bb0874
  Inst 12:   cmpl    $0, %esi // 0
  Inst 13:   jz      taken=MachLabel(1) not_taken=MachLabel(3) --> jmp 1
Block 1:
  (original IR block: block15)
  (successor: Block 2)
  (instruction range: 14 .. 15)
  Inst 14:   jmp     MachLabel(2) --> jmp 2
Block 2:
  (successor: Block 11)
  (instruction range: 15 .. 17)
  Inst 15:   movl    $0, %edx // edx = 0
  Inst 16:   jmp     MachLabel(11) --> jmp 11
Block 3:
  (original IR block: block6)
  (successor: Block 4)
  (instruction range: 17 .. 21)
  Inst 17:   movq    %r14, %rsi
  Inst 18:   addq    $56, %rsi
  Inst 19:   movl    %r13d, %eax
  Inst 20:   jmp     MachLabel(4)
Block 4:
  (successor: Block 5)
  (instruction range: 21 .. 24)
  Inst 21:   movl    $0, %ecx
  Inst 22:   movl    $0, %edx
  Inst 23:   jmp     MachLabel(5)
Block 5:
  (original IR block: block7)
  (successor: Block 6)
  (successor: Block 7)
  (instruction range: 24 .. 27)
  Inst 24:   movl    0(%rsi), %r8d
  Inst 25:   cmpl    $0, %r8d
  Inst 26:   jz      taken=MachLabel(6) not_taken=MachLabel(7)
Block 6:
  (successor: Block 9)
  (instruction range: 27 .. 28)
  Inst 27:   jmp     MachLabel(9)
Block 7:
  (original IR block: block27)
  (successor: Block 8)
  (instruction range: 28 .. 30)
  Inst 28:   ud2 interrupt
  Inst 29:   jmp     MachLabel(8)
Block 8:
  (successor: Block 9)
  (instruction range: 30 .. 31)
  Inst 30:   jmp     MachLabel(9)
Block 9:
  (original IR block: block28)
  (successor: Block 10)
  (successor: Block 17)
  (instruction range: 31 .. 35)
  Inst 31:   cmpl    %r12d, %ecx
  Inst 32:   setnl   %r8b
  Inst 33:   cmpb    $0, %r8b
  Inst 34:   jnz     taken=MachLabel(10) not_taken=MachLabel(17)
Block 10:
  (successor: Block 11)
  (instruction range: 35 .. 36)
  Inst 35:   jmp     MachLabel(11)
Block 11:
  (original IR block: block4)
  (successor: Block 12)
  (successor: Block 14)
  (instruction range: 36 .. 59)
  Inst 36:   movq    %rdi, %rbx // 0xbb0508 @ bb0668
  Inst 37:   addl    $216, %ebx // 0xbb05e0
  Inst 38:   movl    %ebx, %eax // 0xbb05e0
  Inst 39:   movq    %r15/pinned, %rbx // 7ffe52af0000 = HEAP_BASE
  Inst 40:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 41:   movl    0(%rbx), %esi // 0x2001004
  Inst 42:   movq    %rsi, %rbx // 0x2001004
  Inst 43:   andl    $-8388609, %ebx // same
  Inst 44:   movq    %r15/pinned, %rcx // HEAP_BASE
  Inst 45:   addq    %rax, %rcx // 7ffe536a05e0
  Inst 46:   movl    %ebx, 0(%rcx) // 0x2001004 -> *$rcx
  Inst 47:   movq    %rdi, %rcx // bb0508
  Inst 48:   addl    $212, %ecx // bb05dc // bb073c
  Inst 49:   movl    %ecx, %ecx // same
  Inst 50:   movq    %r15/pinned, %r8
  Inst 51:   addq    %rcx, %r8 // 7ffe536a05dc
  Inst 52:   movl    0(%r8), %r8d // read: 0x304000
  Inst 53:   andl    $-8193, %r8d // same
  Inst 54:   movq    %r15/pinned, %r9 // HEAP_BASE
  Inst 55:   addq    %rcx, %r9 // bb05dc
  Inst 56:   movl    %r8d, 0(%r9)
  Inst 57:   cmpl    $0, %edx // 0
  Inst 58:   jz      taken=MachLabel(12) not_taken=MachLabel(14) --> jmp 12
Block 12:
  (original IR block: block18)
  (successor: Block 13)
  (instruction range: 59 .. 64)
  Inst 59:   andl    $-8388993, %esi // 2001004
  Inst 60:   movq    %r15/pinned, %rbx // HEAP_BASE
  Inst 61:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 62:   movl    %esi, 0(%rbx) // esi = 2001004, stored
  Inst 63:   jmp     MachLabel(13) -> jmp 13
Block 13:
  (successor: Block 16)
  (instruction range: 64 .. 65)
  Inst 64:   jmp     MachLabel(16) -> jmp 16
Block 14:
  (original IR block: block17)
  (successor: Block 15)
  (instruction range: 65 .. 66)
  Inst 65:   jmp     MachLabel(15)
Block 15:
  (successor: Block 16)
  (instruction range: 66 .. 68)
  Inst 66:   movq    %rbx, %rsi
  Inst 67:   jmp     MachLabel(16)
Block 16:
  (original IR block: block16)
  (successor: Block 23)
  (instruction range: 68 .. 70)
  Inst 68:   movq    %rsi, %rbx 2001004
  Inst 69:   jmp     MachLabel(23) --> jmp 23
Block 17:
  (original IR block: block10)

[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Jul 30 2020 at 19:48):

bnjbvr labeled Issue #2082:

This has taken some time to track down, but I eventually managed to pinpoint to one function that was sufficient to trigger the crash in Firefox, and so I went on and ran Firefox in a debugger, stepping in until i could see where control flow seemed to go wrong.

Here's a summary of the input function, plus a runtime trace to explicit where the bug is (and where i observed the crash):

<details><summary>Clif test</summary>

function u0:7705(i32, i64 vmctx) baldrdash_system_v {
    gv0 = vmctx
    gv1 = load.i64 notrap aligned readonly gv0
    gv2 = iadd_imm.i64 gv0, 56
    heap0 = static gv1, min 0x0100_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    jt0 = jump_table [block14, block13]

block0(v0: i32, v1: i64):
    v31 -> v0
    v32 -> v31
    v2 = iconst.i32 0
    v3 = heap_addr.i64 heap0, v0, 1
    v4 = sload16.i32 v3+420
    v5 = iconst.i32 0xffff
    v6 = band v4, v5
    v14 -> v6
    v29 -> v14
    v7 = iconst.i32 524
    v8 = iadd v0, v7
    v17 -> v8
    v30 -> v17
    brz v4, block15
    jump block6

block6:
    v9 = iconst.i32 0
    v10 = iconst.i32 0
    jump block7(v9, v10)

block7(v13: i32, v52: i32):
    v26 -> v13
    v11 = global_value.i64 gv2
    v12 = load.i32 notrap aligned v11
    resumable_trapnz v12, interrupt
    v15 = icmp sge v13, v14
    v16 = bint.i32 v15
    brnz v16, block4(v31, v52, v14, v17)
    jump block10

block10:
    v18 = heap_addr.i64 heap0, v17, 1
    v19 = load.i32 v18
    v20 = iadd v19, v13
    v21 = heap_addr.i64 heap0, v20, 1
    v22 = sload8.i32 v21
    v23 = iconst.i32 -1
    v24 = isub v22, v23
    br_table v24, block12, jt0

block14:
    jump block11(v52)

block13:
    v25 = iconst.i32 1
    jump block11(v25)

block12:
    jump block9

block11(v53: i32):
    v27 = iconst.i32 1
    v28 = iadd.i32 v13, v27
    jump block7(v28, v53)

block9:
    jump block8

block8:
    v33 = heap_addr.i64 heap0, v0, 1
    v34 = load.i32 v33+216
    jump block5

block15:
    v35 = iconst.i32 0
    jump block4(v0, v35, v6, v8)

block5:
    jump block3(v34, v0, v14, v17)

block4(v36: i32, v51: i32, v111: i32, v114: i32):
    v65 -> v36
    v110 -> v111
    v113 -> v114
    v37 = iconst.i32 216
    v38 = iadd v36, v37
    v39 = heap_addr.i64 heap0, v38, 1
    v40 = load.i32 v39
    v41 = iconst.i32 0xffff_ffff_ff7f_ffff
    v42 = band v40, v41
    v43 = heap_addr.i64 heap0, v38, 1
    store v42, v43
    v44 = iconst.i32 212
    v45 = iadd v36, v44
    v46 = heap_addr.i64 heap0, v45, 1
    v47 = load.i32 v46
    v48 = iconst.i32 -8193
    v49 = band v47, v48
    v50 = heap_addr.i64 heap0, v45, 1
    store v49, v50
    brz v51, block18
    jump block17

block17:
    jump block16(v42)

block18:
    v54 = iconst.i32 0xffff_ffff_ff7f_fe7f
    v55 = band.i32 v40, v54
    v56 = heap_addr.i64 heap0, v38, 1
    store v55, v56
    jump block16(v55)

block16(v58: i32):
    jump block3(v58, v65, v110, v113)

block3(v57: i32, v64: i32, v109: i32, v112: i32):
    v95 -> v109
    v98 -> v112
    v59 = iconst.i32 4352
    v60 = band v57, v59
    v61 = iconst.i32 4352
    v62 = icmp eq v60, v61
    v63 = bint.i32 v62
    brz v63, block20
    jump block21

block21:
    v66 = heap_addr.i64 heap0, v64, 1
    v67 = load.i32 v66+408
    v68 = heap_addr.i64 heap0, v64, 1
    v69 = uload8.i32 v68+448
    v70 = iconst.i32 3
    v71 = imul v69, v70
    v72 = iadd v67, v71
    v73 = heap_addr.i64 heap0, v72, 1
    v74 = uload8.i32 v73
    v75 = heap_addr.i64 heap0, v64, 1
    istore16 v74, v75+450
    v76 = iconst.i32 3
    v77 = imul v69, v76
    v78 = iadd v67, v77
    v79 = heap_addr.i64 heap0, v78, 1
    v80 = uload8.i32 v79+1
    v81 = heap_addr.i64 heap0, v64, 1
    istore16 v80, v81+452
    v82 = iadd v67, v77
    v83 = heap_addr.i64 heap0, v82, 1
    v84 = uload8.i32 v83+2
    v85 = heap_addr.i64 heap0, v64, 1
    istore16 v84, v85+454
    v86 = iconst.i32 0x0208_0000
    v87 = band.i32 v57, v86
    v88 = iconst.i32 0x0008_0000
    v89 = icmp eq v87, v88
    v90 = bint.i32 v89
    brz v90, block22
    jump block23

block23:
    v91 = iconst.i32 0
    jump block24(v91)

block24(v94: i32):
    v92 = global_value.i64 gv2
    v93 = load.i32 notrap aligned v92
    resumable_trapnz v93, interrupt
    v96 = icmp eq v94, v95
    v97 = bint.i32 v96
    brnz v97, block19
    jump block26

block26:
    v99 = heap_addr.i64 heap0, v98, 1
    v100 = load.i32 v99
    v101 = iadd v100, v94
    v102 = heap_addr.i64 heap0, v101, 1
    v103 = sload8.i32 v102
    v104 = iconst.i32 -1
    v105 = bxor v103, v104
    v106 = heap_addr.i64 heap0, v101, 1
    istore8 v105, v106
    v107 = iconst.i32 1
    v108 = iadd.i32 v94, v107
    jump block24(v108)

block22:
    jump block20

block20:
    jump block19

block19:
    jump block2

block2:
    jump block1

block1:
    fallthrough_return
}

</details>

<details><summary>x64 trace</summary>

don't pay attention to the codegen inefficiencies (yet)

VCode_ShowWithRRU {{
  Entry block: 0
Block 0:
  (original IR block: block0)
  (successor: Block 1)
  (successor: Block 3)
  (instruction range: 0 .. 14)
  Inst 0:   pushq   %rbx
  Inst 1:   pushq   %r12
  Inst 2:   pushq   %r13
  Inst 3:   virtual_sp_offset_adjust 24
  Inst 4:   movl    %edi, %ebx // edi = ebx = 0xbb0508 @ 0xbb0668
  Inst 5:   movq    %r15/pinned, %r12 // r15 = r12 = 0x7ffe52af0000
  Inst 6:   addq    %rbx, %r12 // r12 = 0x7ffe536a0508
  Inst 7:   movswq  420(%r12), %rsi // rsi = 0
  Inst 8:   movq    %rsi, %r12 // r12 = 0
  Inst 9:   andl    $65535, %r12d // 0
  Inst 10:   movq    %rdi, %r13 // rdi = r13 = 0xbb0508
  Inst 11:   addl    $524, %r13d // 0xbb0714 @ bb0874
  Inst 12:   cmpl    $0, %esi // 0
  Inst 13:   jz      taken=MachLabel(1) not_taken=MachLabel(3) --> jmp 1
Block 1:
  (original IR block: block15)
  (successor: Block 2)
  (instruction range: 14 .. 15)
  Inst 14:   jmp     MachLabel(2) --> jmp 2
Block 2:
  (successor: Block 11)
  (instruction range: 15 .. 17)
  Inst 15:   movl    $0, %edx // edx = 0
  Inst 16:   jmp     MachLabel(11) --> jmp 11
Block 3:
  (original IR block: block6)
  (successor: Block 4)
  (instruction range: 17 .. 21)
  Inst 17:   movq    %r14, %rsi
  Inst 18:   addq    $56, %rsi
  Inst 19:   movl    %r13d, %eax
  Inst 20:   jmp     MachLabel(4)
Block 4:
  (successor: Block 5)
  (instruction range: 21 .. 24)
  Inst 21:   movl    $0, %ecx
  Inst 22:   movl    $0, %edx
  Inst 23:   jmp     MachLabel(5)
Block 5:
  (original IR block: block7)
  (successor: Block 6)
  (successor: Block 7)
  (instruction range: 24 .. 27)
  Inst 24:   movl    0(%rsi), %r8d
  Inst 25:   cmpl    $0, %r8d
  Inst 26:   jz      taken=MachLabel(6) not_taken=MachLabel(7)
Block 6:
  (successor: Block 9)
  (instruction range: 27 .. 28)
  Inst 27:   jmp     MachLabel(9)
Block 7:
  (original IR block: block27)
  (successor: Block 8)
  (instruction range: 28 .. 30)
  Inst 28:   ud2 interrupt
  Inst 29:   jmp     MachLabel(8)
Block 8:
  (successor: Block 9)
  (instruction range: 30 .. 31)
  Inst 30:   jmp     MachLabel(9)
Block 9:
  (original IR block: block28)
  (successor: Block 10)
  (successor: Block 17)
  (instruction range: 31 .. 35)
  Inst 31:   cmpl    %r12d, %ecx
  Inst 32:   setnl   %r8b
  Inst 33:   cmpb    $0, %r8b
  Inst 34:   jnz     taken=MachLabel(10) not_taken=MachLabel(17)
Block 10:
  (successor: Block 11)
  (instruction range: 35 .. 36)
  Inst 35:   jmp     MachLabel(11)
Block 11:
  (original IR block: block4)
  (successor: Block 12)
  (successor: Block 14)
  (instruction range: 36 .. 59)
  Inst 36:   movq    %rdi, %rbx // 0xbb0508 @ bb0668
  Inst 37:   addl    $216, %ebx // 0xbb05e0
  Inst 38:   movl    %ebx, %eax // 0xbb05e0
  Inst 39:   movq    %r15/pinned, %rbx // 7ffe52af0000 = HEAP_BASE
  Inst 40:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 41:   movl    0(%rbx), %esi // 0x2001004
  Inst 42:   movq    %rsi, %rbx // 0x2001004
  Inst 43:   andl    $-8388609, %ebx // same
  Inst 44:   movq    %r15/pinned, %rcx // HEAP_BASE
  Inst 45:   addq    %rax, %rcx // 7ffe536a05e0
  Inst 46:   movl    %ebx, 0(%rcx) // 0x2001004 -> *$rcx
  Inst 47:   movq    %rdi, %rcx // bb0508
  Inst 48:   addl    $212, %ecx // bb05dc // bb073c
  Inst 49:   movl    %ecx, %ecx // same
  Inst 50:   movq    %r15/pinned, %r8
  Inst 51:   addq    %rcx, %r8 // 7ffe536a05dc
  Inst 52:   movl    0(%r8), %r8d // read: 0x304000
  Inst 53:   andl    $-8193, %r8d // same
  Inst 54:   movq    %r15/pinned, %r9 // HEAP_BASE
  Inst 55:   addq    %rcx, %r9 // bb05dc
  Inst 56:   movl    %r8d, 0(%r9)
  Inst 57:   cmpl    $0, %edx // 0
  Inst 58:   jz      taken=MachLabel(12) not_taken=MachLabel(14) --> jmp 12
Block 12:
  (original IR block: block18)
  (successor: Block 13)
  (instruction range: 59 .. 64)
  Inst 59:   andl    $-8388993, %esi // 2001004
  Inst 60:   movq    %r15/pinned, %rbx // HEAP_BASE
  Inst 61:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 62:   movl    %esi, 0(%rbx) // esi = 2001004, stored
  Inst 63:   jmp     MachLabel(13) -> jmp 13
Block 13:
  (successor: Block 16)
  (instruction range: 64 .. 65)
  Inst 64:   jmp     MachLabel(16) -> jmp 16
Block 14:
  (original IR block: block17)
  (successor: Block 15)
  (instruction range: 65 .. 66)
  Inst 65:   jmp     MachLabel(15)
Block 15:
  (successor: Block 16)
  (instruction range: 66 .. 68)
  Inst 66:   movq    %rbx, %rsi
  Inst 67:   jmp     MachLabel(16)
Block 16:
  (original IR block: block16)
  (successor: Block 23)
  (instruction range: 68 .. 70)
  Inst 68:   movq    %rsi, %rbx 2001004
  Inst 69:   jmp     MachLabel(23) --> jmp 23
Block 17:
  (original IR block: block10)

[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Jul 30 2020 at 19:48):

bnjbvr labeled Issue #2082:

This has taken some time to track down, but I eventually managed to pinpoint to one function that was sufficient to trigger the crash in Firefox, and so I went on and ran Firefox in a debugger, stepping in until i could see where control flow seemed to go wrong.

Here's a summary of the input function, plus a runtime trace to explicit where the bug is (and where i observed the crash):

<details><summary>Clif test</summary>

function u0:7705(i32, i64 vmctx) baldrdash_system_v {
    gv0 = vmctx
    gv1 = load.i64 notrap aligned readonly gv0
    gv2 = iadd_imm.i64 gv0, 56
    heap0 = static gv1, min 0x0100_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    jt0 = jump_table [block14, block13]

block0(v0: i32, v1: i64):
    v31 -> v0
    v32 -> v31
    v2 = iconst.i32 0
    v3 = heap_addr.i64 heap0, v0, 1
    v4 = sload16.i32 v3+420
    v5 = iconst.i32 0xffff
    v6 = band v4, v5
    v14 -> v6
    v29 -> v14
    v7 = iconst.i32 524
    v8 = iadd v0, v7
    v17 -> v8
    v30 -> v17
    brz v4, block15
    jump block6

block6:
    v9 = iconst.i32 0
    v10 = iconst.i32 0
    jump block7(v9, v10)

block7(v13: i32, v52: i32):
    v26 -> v13
    v11 = global_value.i64 gv2
    v12 = load.i32 notrap aligned v11
    resumable_trapnz v12, interrupt
    v15 = icmp sge v13, v14
    v16 = bint.i32 v15
    brnz v16, block4(v31, v52, v14, v17)
    jump block10

block10:
    v18 = heap_addr.i64 heap0, v17, 1
    v19 = load.i32 v18
    v20 = iadd v19, v13
    v21 = heap_addr.i64 heap0, v20, 1
    v22 = sload8.i32 v21
    v23 = iconst.i32 -1
    v24 = isub v22, v23
    br_table v24, block12, jt0

block14:
    jump block11(v52)

block13:
    v25 = iconst.i32 1
    jump block11(v25)

block12:
    jump block9

block11(v53: i32):
    v27 = iconst.i32 1
    v28 = iadd.i32 v13, v27
    jump block7(v28, v53)

block9:
    jump block8

block8:
    v33 = heap_addr.i64 heap0, v0, 1
    v34 = load.i32 v33+216
    jump block5

block15:
    v35 = iconst.i32 0
    jump block4(v0, v35, v6, v8)

block5:
    jump block3(v34, v0, v14, v17)

block4(v36: i32, v51: i32, v111: i32, v114: i32):
    v65 -> v36
    v110 -> v111
    v113 -> v114
    v37 = iconst.i32 216
    v38 = iadd v36, v37
    v39 = heap_addr.i64 heap0, v38, 1
    v40 = load.i32 v39
    v41 = iconst.i32 0xffff_ffff_ff7f_ffff
    v42 = band v40, v41
    v43 = heap_addr.i64 heap0, v38, 1
    store v42, v43
    v44 = iconst.i32 212
    v45 = iadd v36, v44
    v46 = heap_addr.i64 heap0, v45, 1
    v47 = load.i32 v46
    v48 = iconst.i32 -8193
    v49 = band v47, v48
    v50 = heap_addr.i64 heap0, v45, 1
    store v49, v50
    brz v51, block18
    jump block17

block17:
    jump block16(v42)

block18:
    v54 = iconst.i32 0xffff_ffff_ff7f_fe7f
    v55 = band.i32 v40, v54
    v56 = heap_addr.i64 heap0, v38, 1
    store v55, v56
    jump block16(v55)

block16(v58: i32):
    jump block3(v58, v65, v110, v113)

block3(v57: i32, v64: i32, v109: i32, v112: i32):
    v95 -> v109
    v98 -> v112
    v59 = iconst.i32 4352
    v60 = band v57, v59
    v61 = iconst.i32 4352
    v62 = icmp eq v60, v61
    v63 = bint.i32 v62
    brz v63, block20
    jump block21

block21:
    v66 = heap_addr.i64 heap0, v64, 1
    v67 = load.i32 v66+408
    v68 = heap_addr.i64 heap0, v64, 1
    v69 = uload8.i32 v68+448
    v70 = iconst.i32 3
    v71 = imul v69, v70
    v72 = iadd v67, v71
    v73 = heap_addr.i64 heap0, v72, 1
    v74 = uload8.i32 v73
    v75 = heap_addr.i64 heap0, v64, 1
    istore16 v74, v75+450
    v76 = iconst.i32 3
    v77 = imul v69, v76
    v78 = iadd v67, v77
    v79 = heap_addr.i64 heap0, v78, 1
    v80 = uload8.i32 v79+1
    v81 = heap_addr.i64 heap0, v64, 1
    istore16 v80, v81+452
    v82 = iadd v67, v77
    v83 = heap_addr.i64 heap0, v82, 1
    v84 = uload8.i32 v83+2
    v85 = heap_addr.i64 heap0, v64, 1
    istore16 v84, v85+454
    v86 = iconst.i32 0x0208_0000
    v87 = band.i32 v57, v86
    v88 = iconst.i32 0x0008_0000
    v89 = icmp eq v87, v88
    v90 = bint.i32 v89
    brz v90, block22
    jump block23

block23:
    v91 = iconst.i32 0
    jump block24(v91)

block24(v94: i32):
    v92 = global_value.i64 gv2
    v93 = load.i32 notrap aligned v92
    resumable_trapnz v93, interrupt
    v96 = icmp eq v94, v95
    v97 = bint.i32 v96
    brnz v97, block19
    jump block26

block26:
    v99 = heap_addr.i64 heap0, v98, 1
    v100 = load.i32 v99
    v101 = iadd v100, v94
    v102 = heap_addr.i64 heap0, v101, 1
    v103 = sload8.i32 v102
    v104 = iconst.i32 -1
    v105 = bxor v103, v104
    v106 = heap_addr.i64 heap0, v101, 1
    istore8 v105, v106
    v107 = iconst.i32 1
    v108 = iadd.i32 v94, v107
    jump block24(v108)

block22:
    jump block20

block20:
    jump block19

block19:
    jump block2

block2:
    jump block1

block1:
    fallthrough_return
}

</details>

<details><summary>x64 trace</summary>

don't pay attention to the codegen inefficiencies (yet)

VCode_ShowWithRRU {{
  Entry block: 0
Block 0:
  (original IR block: block0)
  (successor: Block 1)
  (successor: Block 3)
  (instruction range: 0 .. 14)
  Inst 0:   pushq   %rbx
  Inst 1:   pushq   %r12
  Inst 2:   pushq   %r13
  Inst 3:   virtual_sp_offset_adjust 24
  Inst 4:   movl    %edi, %ebx // edi = ebx = 0xbb0508 @ 0xbb0668
  Inst 5:   movq    %r15/pinned, %r12 // r15 = r12 = 0x7ffe52af0000
  Inst 6:   addq    %rbx, %r12 // r12 = 0x7ffe536a0508
  Inst 7:   movswq  420(%r12), %rsi // rsi = 0
  Inst 8:   movq    %rsi, %r12 // r12 = 0
  Inst 9:   andl    $65535, %r12d // 0
  Inst 10:   movq    %rdi, %r13 // rdi = r13 = 0xbb0508
  Inst 11:   addl    $524, %r13d // 0xbb0714 @ bb0874
  Inst 12:   cmpl    $0, %esi // 0
  Inst 13:   jz      taken=MachLabel(1) not_taken=MachLabel(3) --> jmp 1
Block 1:
  (original IR block: block15)
  (successor: Block 2)
  (instruction range: 14 .. 15)
  Inst 14:   jmp     MachLabel(2) --> jmp 2
Block 2:
  (successor: Block 11)
  (instruction range: 15 .. 17)
  Inst 15:   movl    $0, %edx // edx = 0
  Inst 16:   jmp     MachLabel(11) --> jmp 11
Block 3:
  (original IR block: block6)
  (successor: Block 4)
  (instruction range: 17 .. 21)
  Inst 17:   movq    %r14, %rsi
  Inst 18:   addq    $56, %rsi
  Inst 19:   movl    %r13d, %eax
  Inst 20:   jmp     MachLabel(4)
Block 4:
  (successor: Block 5)
  (instruction range: 21 .. 24)
  Inst 21:   movl    $0, %ecx
  Inst 22:   movl    $0, %edx
  Inst 23:   jmp     MachLabel(5)
Block 5:
  (original IR block: block7)
  (successor: Block 6)
  (successor: Block 7)
  (instruction range: 24 .. 27)
  Inst 24:   movl    0(%rsi), %r8d
  Inst 25:   cmpl    $0, %r8d
  Inst 26:   jz      taken=MachLabel(6) not_taken=MachLabel(7)
Block 6:
  (successor: Block 9)
  (instruction range: 27 .. 28)
  Inst 27:   jmp     MachLabel(9)
Block 7:
  (original IR block: block27)
  (successor: Block 8)
  (instruction range: 28 .. 30)
  Inst 28:   ud2 interrupt
  Inst 29:   jmp     MachLabel(8)
Block 8:
  (successor: Block 9)
  (instruction range: 30 .. 31)
  Inst 30:   jmp     MachLabel(9)
Block 9:
  (original IR block: block28)
  (successor: Block 10)
  (successor: Block 17)
  (instruction range: 31 .. 35)
  Inst 31:   cmpl    %r12d, %ecx
  Inst 32:   setnl   %r8b
  Inst 33:   cmpb    $0, %r8b
  Inst 34:   jnz     taken=MachLabel(10) not_taken=MachLabel(17)
Block 10:
  (successor: Block 11)
  (instruction range: 35 .. 36)
  Inst 35:   jmp     MachLabel(11)
Block 11:
  (original IR block: block4)
  (successor: Block 12)
  (successor: Block 14)
  (instruction range: 36 .. 59)
  Inst 36:   movq    %rdi, %rbx // 0xbb0508 @ bb0668
  Inst 37:   addl    $216, %ebx // 0xbb05e0
  Inst 38:   movl    %ebx, %eax // 0xbb05e0
  Inst 39:   movq    %r15/pinned, %rbx // 7ffe52af0000 = HEAP_BASE
  Inst 40:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 41:   movl    0(%rbx), %esi // 0x2001004
  Inst 42:   movq    %rsi, %rbx // 0x2001004
  Inst 43:   andl    $-8388609, %ebx // same
  Inst 44:   movq    %r15/pinned, %rcx // HEAP_BASE
  Inst 45:   addq    %rax, %rcx // 7ffe536a05e0
  Inst 46:   movl    %ebx, 0(%rcx) // 0x2001004 -> *$rcx
  Inst 47:   movq    %rdi, %rcx // bb0508
  Inst 48:   addl    $212, %ecx // bb05dc // bb073c
  Inst 49:   movl    %ecx, %ecx // same
  Inst 50:   movq    %r15/pinned, %r8
  Inst 51:   addq    %rcx, %r8 // 7ffe536a05dc
  Inst 52:   movl    0(%r8), %r8d // read: 0x304000
  Inst 53:   andl    $-8193, %r8d // same
  Inst 54:   movq    %r15/pinned, %r9 // HEAP_BASE
  Inst 55:   addq    %rcx, %r9 // bb05dc
  Inst 56:   movl    %r8d, 0(%r9)
  Inst 57:   cmpl    $0, %edx // 0
  Inst 58:   jz      taken=MachLabel(12) not_taken=MachLabel(14) --> jmp 12
Block 12:
  (original IR block: block18)
  (successor: Block 13)
  (instruction range: 59 .. 64)
  Inst 59:   andl    $-8388993, %esi // 2001004
  Inst 60:   movq    %r15/pinned, %rbx // HEAP_BASE
  Inst 61:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 62:   movl    %esi, 0(%rbx) // esi = 2001004, stored
  Inst 63:   jmp     MachLabel(13) -> jmp 13
Block 13:
  (successor: Block 16)
  (instruction range: 64 .. 65)
  Inst 64:   jmp     MachLabel(16) -> jmp 16
Block 14:
  (original IR block: block17)
  (successor: Block 15)
  (instruction range: 65 .. 66)
  Inst 65:   jmp     MachLabel(15)
Block 15:
  (successor: Block 16)
  (instruction range: 66 .. 68)
  Inst 66:   movq    %rbx, %rsi
  Inst 67:   jmp     MachLabel(16)
Block 16:
  (original IR block: block16)
  (successor: Block 23)
  (instruction range: 68 .. 70)
  Inst 68:   movq    %rsi, %rbx 2001004
  Inst 69:   jmp     MachLabel(23) --> jmp 23
Block 17:
  (original IR block: block10)

[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Jul 30 2020 at 19:48):

bnjbvr labeled Issue #2082:

This has taken some time to track down, but I eventually managed to pinpoint to one function that was sufficient to trigger the crash in Firefox, and so I went on and ran Firefox in a debugger, stepping in until i could see where control flow seemed to go wrong.

Here's a summary of the input function, plus a runtime trace to explicit where the bug is (and where i observed the crash):

<details><summary>Clif test</summary>

function u0:7705(i32, i64 vmctx) baldrdash_system_v {
    gv0 = vmctx
    gv1 = load.i64 notrap aligned readonly gv0
    gv2 = iadd_imm.i64 gv0, 56
    heap0 = static gv1, min 0x0100_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    jt0 = jump_table [block14, block13]

block0(v0: i32, v1: i64):
    v31 -> v0
    v32 -> v31
    v2 = iconst.i32 0
    v3 = heap_addr.i64 heap0, v0, 1
    v4 = sload16.i32 v3+420
    v5 = iconst.i32 0xffff
    v6 = band v4, v5
    v14 -> v6
    v29 -> v14
    v7 = iconst.i32 524
    v8 = iadd v0, v7
    v17 -> v8
    v30 -> v17
    brz v4, block15
    jump block6

block6:
    v9 = iconst.i32 0
    v10 = iconst.i32 0
    jump block7(v9, v10)

block7(v13: i32, v52: i32):
    v26 -> v13
    v11 = global_value.i64 gv2
    v12 = load.i32 notrap aligned v11
    resumable_trapnz v12, interrupt
    v15 = icmp sge v13, v14
    v16 = bint.i32 v15
    brnz v16, block4(v31, v52, v14, v17)
    jump block10

block10:
    v18 = heap_addr.i64 heap0, v17, 1
    v19 = load.i32 v18
    v20 = iadd v19, v13
    v21 = heap_addr.i64 heap0, v20, 1
    v22 = sload8.i32 v21
    v23 = iconst.i32 -1
    v24 = isub v22, v23
    br_table v24, block12, jt0

block14:
    jump block11(v52)

block13:
    v25 = iconst.i32 1
    jump block11(v25)

block12:
    jump block9

block11(v53: i32):
    v27 = iconst.i32 1
    v28 = iadd.i32 v13, v27
    jump block7(v28, v53)

block9:
    jump block8

block8:
    v33 = heap_addr.i64 heap0, v0, 1
    v34 = load.i32 v33+216
    jump block5

block15:
    v35 = iconst.i32 0
    jump block4(v0, v35, v6, v8)

block5:
    jump block3(v34, v0, v14, v17)

block4(v36: i32, v51: i32, v111: i32, v114: i32):
    v65 -> v36
    v110 -> v111
    v113 -> v114
    v37 = iconst.i32 216
    v38 = iadd v36, v37
    v39 = heap_addr.i64 heap0, v38, 1
    v40 = load.i32 v39
    v41 = iconst.i32 0xffff_ffff_ff7f_ffff
    v42 = band v40, v41
    v43 = heap_addr.i64 heap0, v38, 1
    store v42, v43
    v44 = iconst.i32 212
    v45 = iadd v36, v44
    v46 = heap_addr.i64 heap0, v45, 1
    v47 = load.i32 v46
    v48 = iconst.i32 -8193
    v49 = band v47, v48
    v50 = heap_addr.i64 heap0, v45, 1
    store v49, v50
    brz v51, block18
    jump block17

block17:
    jump block16(v42)

block18:
    v54 = iconst.i32 0xffff_ffff_ff7f_fe7f
    v55 = band.i32 v40, v54
    v56 = heap_addr.i64 heap0, v38, 1
    store v55, v56
    jump block16(v55)

block16(v58: i32):
    jump block3(v58, v65, v110, v113)

block3(v57: i32, v64: i32, v109: i32, v112: i32):
    v95 -> v109
    v98 -> v112
    v59 = iconst.i32 4352
    v60 = band v57, v59
    v61 = iconst.i32 4352
    v62 = icmp eq v60, v61
    v63 = bint.i32 v62
    brz v63, block20
    jump block21

block21:
    v66 = heap_addr.i64 heap0, v64, 1
    v67 = load.i32 v66+408
    v68 = heap_addr.i64 heap0, v64, 1
    v69 = uload8.i32 v68+448
    v70 = iconst.i32 3
    v71 = imul v69, v70
    v72 = iadd v67, v71
    v73 = heap_addr.i64 heap0, v72, 1
    v74 = uload8.i32 v73
    v75 = heap_addr.i64 heap0, v64, 1
    istore16 v74, v75+450
    v76 = iconst.i32 3
    v77 = imul v69, v76
    v78 = iadd v67, v77
    v79 = heap_addr.i64 heap0, v78, 1
    v80 = uload8.i32 v79+1
    v81 = heap_addr.i64 heap0, v64, 1
    istore16 v80, v81+452
    v82 = iadd v67, v77
    v83 = heap_addr.i64 heap0, v82, 1
    v84 = uload8.i32 v83+2
    v85 = heap_addr.i64 heap0, v64, 1
    istore16 v84, v85+454
    v86 = iconst.i32 0x0208_0000
    v87 = band.i32 v57, v86
    v88 = iconst.i32 0x0008_0000
    v89 = icmp eq v87, v88
    v90 = bint.i32 v89
    brz v90, block22
    jump block23

block23:
    v91 = iconst.i32 0
    jump block24(v91)

block24(v94: i32):
    v92 = global_value.i64 gv2
    v93 = load.i32 notrap aligned v92
    resumable_trapnz v93, interrupt
    v96 = icmp eq v94, v95
    v97 = bint.i32 v96
    brnz v97, block19
    jump block26

block26:
    v99 = heap_addr.i64 heap0, v98, 1
    v100 = load.i32 v99
    v101 = iadd v100, v94
    v102 = heap_addr.i64 heap0, v101, 1
    v103 = sload8.i32 v102
    v104 = iconst.i32 -1
    v105 = bxor v103, v104
    v106 = heap_addr.i64 heap0, v101, 1
    istore8 v105, v106
    v107 = iconst.i32 1
    v108 = iadd.i32 v94, v107
    jump block24(v108)

block22:
    jump block20

block20:
    jump block19

block19:
    jump block2

block2:
    jump block1

block1:
    fallthrough_return
}

</details>

<details><summary>x64 trace</summary>

don't pay attention to the codegen inefficiencies (yet)

VCode_ShowWithRRU {{
  Entry block: 0
Block 0:
  (original IR block: block0)
  (successor: Block 1)
  (successor: Block 3)
  (instruction range: 0 .. 14)
  Inst 0:   pushq   %rbx
  Inst 1:   pushq   %r12
  Inst 2:   pushq   %r13
  Inst 3:   virtual_sp_offset_adjust 24
  Inst 4:   movl    %edi, %ebx // edi = ebx = 0xbb0508 @ 0xbb0668
  Inst 5:   movq    %r15/pinned, %r12 // r15 = r12 = 0x7ffe52af0000
  Inst 6:   addq    %rbx, %r12 // r12 = 0x7ffe536a0508
  Inst 7:   movswq  420(%r12), %rsi // rsi = 0
  Inst 8:   movq    %rsi, %r12 // r12 = 0
  Inst 9:   andl    $65535, %r12d // 0
  Inst 10:   movq    %rdi, %r13 // rdi = r13 = 0xbb0508
  Inst 11:   addl    $524, %r13d // 0xbb0714 @ bb0874
  Inst 12:   cmpl    $0, %esi // 0
  Inst 13:   jz      taken=MachLabel(1) not_taken=MachLabel(3) --> jmp 1
Block 1:
  (original IR block: block15)
  (successor: Block 2)
  (instruction range: 14 .. 15)
  Inst 14:   jmp     MachLabel(2) --> jmp 2
Block 2:
  (successor: Block 11)
  (instruction range: 15 .. 17)
  Inst 15:   movl    $0, %edx // edx = 0
  Inst 16:   jmp     MachLabel(11) --> jmp 11
Block 3:
  (original IR block: block6)
  (successor: Block 4)
  (instruction range: 17 .. 21)
  Inst 17:   movq    %r14, %rsi
  Inst 18:   addq    $56, %rsi
  Inst 19:   movl    %r13d, %eax
  Inst 20:   jmp     MachLabel(4)
Block 4:
  (successor: Block 5)
  (instruction range: 21 .. 24)
  Inst 21:   movl    $0, %ecx
  Inst 22:   movl    $0, %edx
  Inst 23:   jmp     MachLabel(5)
Block 5:
  (original IR block: block7)
  (successor: Block 6)
  (successor: Block 7)
  (instruction range: 24 .. 27)
  Inst 24:   movl    0(%rsi), %r8d
  Inst 25:   cmpl    $0, %r8d
  Inst 26:   jz      taken=MachLabel(6) not_taken=MachLabel(7)
Block 6:
  (successor: Block 9)
  (instruction range: 27 .. 28)
  Inst 27:   jmp     MachLabel(9)
Block 7:
  (original IR block: block27)
  (successor: Block 8)
  (instruction range: 28 .. 30)
  Inst 28:   ud2 interrupt
  Inst 29:   jmp     MachLabel(8)
Block 8:
  (successor: Block 9)
  (instruction range: 30 .. 31)
  Inst 30:   jmp     MachLabel(9)
Block 9:
  (original IR block: block28)
  (successor: Block 10)
  (successor: Block 17)
  (instruction range: 31 .. 35)
  Inst 31:   cmpl    %r12d, %ecx
  Inst 32:   setnl   %r8b
  Inst 33:   cmpb    $0, %r8b
  Inst 34:   jnz     taken=MachLabel(10) not_taken=MachLabel(17)
Block 10:
  (successor: Block 11)
  (instruction range: 35 .. 36)
  Inst 35:   jmp     MachLabel(11)
Block 11:
  (original IR block: block4)
  (successor: Block 12)
  (successor: Block 14)
  (instruction range: 36 .. 59)
  Inst 36:   movq    %rdi, %rbx // 0xbb0508 @ bb0668
  Inst 37:   addl    $216, %ebx // 0xbb05e0
  Inst 38:   movl    %ebx, %eax // 0xbb05e0
  Inst 39:   movq    %r15/pinned, %rbx // 7ffe52af0000 = HEAP_BASE
  Inst 40:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 41:   movl    0(%rbx), %esi // 0x2001004
  Inst 42:   movq    %rsi, %rbx // 0x2001004
  Inst 43:   andl    $-8388609, %ebx // same
  Inst 44:   movq    %r15/pinned, %rcx // HEAP_BASE
  Inst 45:   addq    %rax, %rcx // 7ffe536a05e0
  Inst 46:   movl    %ebx, 0(%rcx) // 0x2001004 -> *$rcx
  Inst 47:   movq    %rdi, %rcx // bb0508
  Inst 48:   addl    $212, %ecx // bb05dc // bb073c
  Inst 49:   movl    %ecx, %ecx // same
  Inst 50:   movq    %r15/pinned, %r8
  Inst 51:   addq    %rcx, %r8 // 7ffe536a05dc
  Inst 52:   movl    0(%r8), %r8d // read: 0x304000
  Inst 53:   andl    $-8193, %r8d // same
  Inst 54:   movq    %r15/pinned, %r9 // HEAP_BASE
  Inst 55:   addq    %rcx, %r9 // bb05dc
  Inst 56:   movl    %r8d, 0(%r9)
  Inst 57:   cmpl    $0, %edx // 0
  Inst 58:   jz      taken=MachLabel(12) not_taken=MachLabel(14) --> jmp 12
Block 12:
  (original IR block: block18)
  (successor: Block 13)
  (instruction range: 59 .. 64)
  Inst 59:   andl    $-8388993, %esi // 2001004
  Inst 60:   movq    %r15/pinned, %rbx // HEAP_BASE
  Inst 61:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 62:   movl    %esi, 0(%rbx) // esi = 2001004, stored
  Inst 63:   jmp     MachLabel(13) -> jmp 13
Block 13:
  (successor: Block 16)
  (instruction range: 64 .. 65)
  Inst 64:   jmp     MachLabel(16) -> jmp 16
Block 14:
  (original IR block: block17)
  (successor: Block 15)
  (instruction range: 65 .. 66)
  Inst 65:   jmp     MachLabel(15)
Block 15:
  (successor: Block 16)
  (instruction range: 66 .. 68)
  Inst 66:   movq    %rbx, %rsi
  Inst 67:   jmp     MachLabel(16)
Block 16:
  (original IR block: block16)
  (successor: Block 23)
  (instruction range: 68 .. 70)
  Inst 68:   movq    %rsi, %rbx 2001004
  Inst 69:   jmp     MachLabel(23) --> jmp 23
Block 17:
  (original IR block: block10)

[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Jul 30 2020 at 19:48):

github-actions[bot] commented on Issue #2082:

Subscribe to Label Action

cc @bnjbvr

<details>
This issue or pull request has been labeled: "cranelift"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (Jul 31 2020 at 17:52):

bnjbvr closed Issue #2082:

This has taken some time to track down, but I eventually managed to pinpoint to one function that was sufficient to trigger the crash in Firefox, and so I went on and ran Firefox in a debugger, stepping in until i could see where control flow seemed to go wrong.

Here's a summary of the input function, plus a runtime trace to explicit where the bug is (and where i observed the crash):

<details><summary>Clif test</summary>

function u0:7705(i32, i64 vmctx) baldrdash_system_v {
    gv0 = vmctx
    gv1 = load.i64 notrap aligned readonly gv0
    gv2 = iadd_imm.i64 gv0, 56
    heap0 = static gv1, min 0x0100_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    jt0 = jump_table [block14, block13]

block0(v0: i32, v1: i64):
    v31 -> v0
    v32 -> v31
    v2 = iconst.i32 0
    v3 = heap_addr.i64 heap0, v0, 1
    v4 = sload16.i32 v3+420
    v5 = iconst.i32 0xffff
    v6 = band v4, v5
    v14 -> v6
    v29 -> v14
    v7 = iconst.i32 524
    v8 = iadd v0, v7
    v17 -> v8
    v30 -> v17
    brz v4, block15
    jump block6

block6:
    v9 = iconst.i32 0
    v10 = iconst.i32 0
    jump block7(v9, v10)

block7(v13: i32, v52: i32):
    v26 -> v13
    v11 = global_value.i64 gv2
    v12 = load.i32 notrap aligned v11
    resumable_trapnz v12, interrupt
    v15 = icmp sge v13, v14
    v16 = bint.i32 v15
    brnz v16, block4(v31, v52, v14, v17)
    jump block10

block10:
    v18 = heap_addr.i64 heap0, v17, 1
    v19 = load.i32 v18
    v20 = iadd v19, v13
    v21 = heap_addr.i64 heap0, v20, 1
    v22 = sload8.i32 v21
    v23 = iconst.i32 -1
    v24 = isub v22, v23
    br_table v24, block12, jt0

block14:
    jump block11(v52)

block13:
    v25 = iconst.i32 1
    jump block11(v25)

block12:
    jump block9

block11(v53: i32):
    v27 = iconst.i32 1
    v28 = iadd.i32 v13, v27
    jump block7(v28, v53)

block9:
    jump block8

block8:
    v33 = heap_addr.i64 heap0, v0, 1
    v34 = load.i32 v33+216
    jump block5

block15:
    v35 = iconst.i32 0
    jump block4(v0, v35, v6, v8)

block5:
    jump block3(v34, v0, v14, v17)

block4(v36: i32, v51: i32, v111: i32, v114: i32):
    v65 -> v36
    v110 -> v111
    v113 -> v114
    v37 = iconst.i32 216
    v38 = iadd v36, v37
    v39 = heap_addr.i64 heap0, v38, 1
    v40 = load.i32 v39
    v41 = iconst.i32 0xffff_ffff_ff7f_ffff
    v42 = band v40, v41
    v43 = heap_addr.i64 heap0, v38, 1
    store v42, v43
    v44 = iconst.i32 212
    v45 = iadd v36, v44
    v46 = heap_addr.i64 heap0, v45, 1
    v47 = load.i32 v46
    v48 = iconst.i32 -8193
    v49 = band v47, v48
    v50 = heap_addr.i64 heap0, v45, 1
    store v49, v50
    brz v51, block18
    jump block17

block17:
    jump block16(v42)

block18:
    v54 = iconst.i32 0xffff_ffff_ff7f_fe7f
    v55 = band.i32 v40, v54
    v56 = heap_addr.i64 heap0, v38, 1
    store v55, v56
    jump block16(v55)

block16(v58: i32):
    jump block3(v58, v65, v110, v113)

block3(v57: i32, v64: i32, v109: i32, v112: i32):
    v95 -> v109
    v98 -> v112
    v59 = iconst.i32 4352
    v60 = band v57, v59
    v61 = iconst.i32 4352
    v62 = icmp eq v60, v61
    v63 = bint.i32 v62
    brz v63, block20
    jump block21

block21:
    v66 = heap_addr.i64 heap0, v64, 1
    v67 = load.i32 v66+408
    v68 = heap_addr.i64 heap0, v64, 1
    v69 = uload8.i32 v68+448
    v70 = iconst.i32 3
    v71 = imul v69, v70
    v72 = iadd v67, v71
    v73 = heap_addr.i64 heap0, v72, 1
    v74 = uload8.i32 v73
    v75 = heap_addr.i64 heap0, v64, 1
    istore16 v74, v75+450
    v76 = iconst.i32 3
    v77 = imul v69, v76
    v78 = iadd v67, v77
    v79 = heap_addr.i64 heap0, v78, 1
    v80 = uload8.i32 v79+1
    v81 = heap_addr.i64 heap0, v64, 1
    istore16 v80, v81+452
    v82 = iadd v67, v77
    v83 = heap_addr.i64 heap0, v82, 1
    v84 = uload8.i32 v83+2
    v85 = heap_addr.i64 heap0, v64, 1
    istore16 v84, v85+454
    v86 = iconst.i32 0x0208_0000
    v87 = band.i32 v57, v86
    v88 = iconst.i32 0x0008_0000
    v89 = icmp eq v87, v88
    v90 = bint.i32 v89
    brz v90, block22
    jump block23

block23:
    v91 = iconst.i32 0
    jump block24(v91)

block24(v94: i32):
    v92 = global_value.i64 gv2
    v93 = load.i32 notrap aligned v92
    resumable_trapnz v93, interrupt
    v96 = icmp eq v94, v95
    v97 = bint.i32 v96
    brnz v97, block19
    jump block26

block26:
    v99 = heap_addr.i64 heap0, v98, 1
    v100 = load.i32 v99
    v101 = iadd v100, v94
    v102 = heap_addr.i64 heap0, v101, 1
    v103 = sload8.i32 v102
    v104 = iconst.i32 -1
    v105 = bxor v103, v104
    v106 = heap_addr.i64 heap0, v101, 1
    istore8 v105, v106
    v107 = iconst.i32 1
    v108 = iadd.i32 v94, v107
    jump block24(v108)

block22:
    jump block20

block20:
    jump block19

block19:
    jump block2

block2:
    jump block1

block1:
    fallthrough_return
}

</details>

<details><summary>x64 trace</summary>

don't pay attention to the codegen inefficiencies (yet)

VCode_ShowWithRRU {{
  Entry block: 0
Block 0:
  (original IR block: block0)
  (successor: Block 1)
  (successor: Block 3)
  (instruction range: 0 .. 14)
  Inst 0:   pushq   %rbx
  Inst 1:   pushq   %r12
  Inst 2:   pushq   %r13
  Inst 3:   virtual_sp_offset_adjust 24
  Inst 4:   movl    %edi, %ebx // edi = ebx = 0xbb0508 @ 0xbb0668
  Inst 5:   movq    %r15/pinned, %r12 // r15 = r12 = 0x7ffe52af0000
  Inst 6:   addq    %rbx, %r12 // r12 = 0x7ffe536a0508
  Inst 7:   movswq  420(%r12), %rsi // rsi = 0
  Inst 8:   movq    %rsi, %r12 // r12 = 0
  Inst 9:   andl    $65535, %r12d // 0
  Inst 10:   movq    %rdi, %r13 // rdi = r13 = 0xbb0508
  Inst 11:   addl    $524, %r13d // 0xbb0714 @ bb0874
  Inst 12:   cmpl    $0, %esi // 0
  Inst 13:   jz      taken=MachLabel(1) not_taken=MachLabel(3) --> jmp 1
Block 1:
  (original IR block: block15)
  (successor: Block 2)
  (instruction range: 14 .. 15)
  Inst 14:   jmp     MachLabel(2) --> jmp 2
Block 2:
  (successor: Block 11)
  (instruction range: 15 .. 17)
  Inst 15:   movl    $0, %edx // edx = 0
  Inst 16:   jmp     MachLabel(11) --> jmp 11
Block 3:
  (original IR block: block6)
  (successor: Block 4)
  (instruction range: 17 .. 21)
  Inst 17:   movq    %r14, %rsi
  Inst 18:   addq    $56, %rsi
  Inst 19:   movl    %r13d, %eax
  Inst 20:   jmp     MachLabel(4)
Block 4:
  (successor: Block 5)
  (instruction range: 21 .. 24)
  Inst 21:   movl    $0, %ecx
  Inst 22:   movl    $0, %edx
  Inst 23:   jmp     MachLabel(5)
Block 5:
  (original IR block: block7)
  (successor: Block 6)
  (successor: Block 7)
  (instruction range: 24 .. 27)
  Inst 24:   movl    0(%rsi), %r8d
  Inst 25:   cmpl    $0, %r8d
  Inst 26:   jz      taken=MachLabel(6) not_taken=MachLabel(7)
Block 6:
  (successor: Block 9)
  (instruction range: 27 .. 28)
  Inst 27:   jmp     MachLabel(9)
Block 7:
  (original IR block: block27)
  (successor: Block 8)
  (instruction range: 28 .. 30)
  Inst 28:   ud2 interrupt
  Inst 29:   jmp     MachLabel(8)
Block 8:
  (successor: Block 9)
  (instruction range: 30 .. 31)
  Inst 30:   jmp     MachLabel(9)
Block 9:
  (original IR block: block28)
  (successor: Block 10)
  (successor: Block 17)
  (instruction range: 31 .. 35)
  Inst 31:   cmpl    %r12d, %ecx
  Inst 32:   setnl   %r8b
  Inst 33:   cmpb    $0, %r8b
  Inst 34:   jnz     taken=MachLabel(10) not_taken=MachLabel(17)
Block 10:
  (successor: Block 11)
  (instruction range: 35 .. 36)
  Inst 35:   jmp     MachLabel(11)
Block 11:
  (original IR block: block4)
  (successor: Block 12)
  (successor: Block 14)
  (instruction range: 36 .. 59)
  Inst 36:   movq    %rdi, %rbx // 0xbb0508 @ bb0668
  Inst 37:   addl    $216, %ebx // 0xbb05e0
  Inst 38:   movl    %ebx, %eax // 0xbb05e0
  Inst 39:   movq    %r15/pinned, %rbx // 7ffe52af0000 = HEAP_BASE
  Inst 40:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 41:   movl    0(%rbx), %esi // 0x2001004
  Inst 42:   movq    %rsi, %rbx // 0x2001004
  Inst 43:   andl    $-8388609, %ebx // same
  Inst 44:   movq    %r15/pinned, %rcx // HEAP_BASE
  Inst 45:   addq    %rax, %rcx // 7ffe536a05e0
  Inst 46:   movl    %ebx, 0(%rcx) // 0x2001004 -> *$rcx
  Inst 47:   movq    %rdi, %rcx // bb0508
  Inst 48:   addl    $212, %ecx // bb05dc // bb073c
  Inst 49:   movl    %ecx, %ecx // same
  Inst 50:   movq    %r15/pinned, %r8
  Inst 51:   addq    %rcx, %r8 // 7ffe536a05dc
  Inst 52:   movl    0(%r8), %r8d // read: 0x304000
  Inst 53:   andl    $-8193, %r8d // same
  Inst 54:   movq    %r15/pinned, %r9 // HEAP_BASE
  Inst 55:   addq    %rcx, %r9 // bb05dc
  Inst 56:   movl    %r8d, 0(%r9)
  Inst 57:   cmpl    $0, %edx // 0
  Inst 58:   jz      taken=MachLabel(12) not_taken=MachLabel(14) --> jmp 12
Block 12:
  (original IR block: block18)
  (successor: Block 13)
  (instruction range: 59 .. 64)
  Inst 59:   andl    $-8388993, %esi // 2001004
  Inst 60:   movq    %r15/pinned, %rbx // HEAP_BASE
  Inst 61:   addq    %rax, %rbx // 7ffe536a05e0
  Inst 62:   movl    %esi, 0(%rbx) // esi = 2001004, stored
  Inst 63:   jmp     MachLabel(13) -> jmp 13
Block 13:
  (successor: Block 16)
  (instruction range: 64 .. 65)
  Inst 64:   jmp     MachLabel(16) -> jmp 16
Block 14:
  (original IR block: block17)
  (successor: Block 15)
  (instruction range: 65 .. 66)
  Inst 65:   jmp     MachLabel(15)
Block 15:
  (successor: Block 16)
  (instruction range: 66 .. 68)
  Inst 66:   movq    %rbx, %rsi
  Inst 67:   jmp     MachLabel(16)
Block 16:
  (original IR block: block16)
  (successor: Block 23)
  (instruction range: 68 .. 70)
  Inst 68:   movq    %rsi, %rbx 2001004
  Inst 69:   jmp     MachLabel(23) --> jmp 23
Block 17:
  (original IR block: block10)

[message truncated]

Last updated: Dec 23 2024 at 12:05 UTC