You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug in JIT Code generation with aborts beam #11419
On x86-64, BeamModuleAssembler::emit_is_in_range passes RET as the spill register to the sub/cmp helpers. When the range width does not fit in a signed 32-bit immediate, those helpers
materialize the constant with mov_imm(RET, val), clobbering RET. The enclosing preserve_cache(...) declares only ARG1 as clobbered, so the register cache still believes RET
holds the source BEAM register. The next instruction fetches the operand from RET and reads the
range constant instead of the actual value.
The result is a guard-checked integer that silently becomes a constant. Depending on what consumes
it, this is either a wrong result or heap corruption with a VM abort.
The BEAM code produced by the compiler is correct â this is purely JIT code generation. The bug
therefore does not show up in the shell, since erl_eval never goes through the JIT.
Instead f/1 returns the same constant for every input, and g/1 aborts the VM.
Note that 2147483646 =:= 34359738336 bsr 4, i.e. the untagged range-width constant that is_in_range materializes into RET.
Affected versions
Reproduced on x86-64 Linux:
OTP
ERTS
27
15.2.7.6
27
15.2.7.11
28
16.4.0.4
29
17.0.4
Not tested: OTP 26 and earlier, and the aarch64 JIT. jit/arm/instr_common.cpp has a similarly
shaped emit_is_in_range, so aarch64 is probably worth checking as well.
Activity
erts: Fix bug in `is_in_range` instruction for x86 JIT
Merge branch 'isabell/erts/fix/erlangGH-11419/OTP-20278' into maint
Merge branch 'isabell/erts/fix/erlangGH-11419/OTP-20278' into maint-29
Merge branch 'isabell/erts/fix/erlangGH-11419/OTP-20278' into maint-28
Merge branch 'isabell/erts/fix/erlangGH-11419/OTP-20278' into maint-27