[from http://mail.openjdk.java.net/pipermail/ppc-aix-port-dev/2016-May/002534.html]
The following test case has been isolated by Hiroshi Horii and generates
the illegal instruction, crashing the JVM on PPC64 LE:
UnalignedUnsafeAccess.java:
http://hastebin.com/raw/uqegukific
$ javac UnalignedUnsafeAccess.java
$ java -Xcomp -Xbatch UnalignedUnsafeAccess
The issue can be reproduced on OpenJDK 8 downstream, OpenJDK 8, and
OpenJDK 9 - hs_err logs:
OpenJDK 9, tag 0be6f4f5d186 jdk-9+120:
http://hastebin.com/raw/ecuhukutur
OpenJDK 8, tag 5aaa43d91c73 tip:
http://hastebin.com/raw/ipohoyafos
OpenJDK 8 downstream:
Ubuntu 16.04 LTS
build 1.8.0_91-8u91-b14-0ubuntu4~16.04.1-b14
http://hastebin.com/raw/yetizebofo
RHEL 7.2:
build 1.8.0_91-b14
http://hastebin.com/raw/irequfawaw
The crash happens when an illegal instruction - 0xea2f0013 - is executed.
The backtrace shows:
Stack: [0x00003fff56030000,0x00003fff56430000], sp=0x00003fff5642b8d0, free space=4078k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x162104] loadI2LNode::emit(CodeBuffer&, PhaseRegAlloc*) const+0x194
V [libjvm.so+0x8ece28] Compile::fill_buffer(CodeBuffer*, unsigned int*)+0x4e8
V [libjvm.so+0x368e08] Compile::Code_Gen()+0x3c8
V [libjvm.so+0x369e04] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool)+0xf64
V [libjvm.so+0x271380] C2Compiler::compile_method(ciEnv*, ciMethod*, int)+0x1f0
V [libjvm.so+0x3785a4] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xd54
V [libjvm.so+0x379dc8] CompileBroker::compiler_thread_loop()+0x488
V [libjvm.so+0xa5de90] compiler_thread_entry(JavaThread*, Thread*)+0x20
V [libjvm.so+0xa690c8] JavaThread::thread_main_inner()+0x178
V [libjvm.so+0x8c8c10] java_start(Thread*)+0x170
C [libpthread.so.0+0x833c] start_thread+0xfc
C [libc.so.6+0x12b014] clone+0xe4
loadI2LNode class is generated according to the following ADL code in
ppc.ad file:
instruct loadI2L(iRegLdst dst, memory mem) %{
match(Set dst (ConvI2L (LoadI mem)));
predicate(_kids[0]->_leaf->as_Load()->is_unordered());
ins_cost(MEMORY_REF_COST);
format %{ "LWA $dst, $mem \t// loadI2L" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_lwa);
int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
__ lwa($dst$$Register, Idisp, $mem$$base$$Register);
%}
ins_pipe(pipe_class_memory);
%}
So the generated illegal instruction comes from:
lwa 17,17,15 (DS-form: lwa RT, DS, RA)
As DS field must always be 4-byte aligned (i.e. DS field is always
concatenated with 0b00), 17 as DS (middle 17 value) is illegal,
generating the illegal instruction in question:
11101010000000000000000000000010: LWA
00000010001000000000000000000000: 17
00000000000000000000000000010001: 17
00000000000011110000000000000000: 15
--------------------------------
11101010001011110000000000010011: 0xEA2F0013 => Illegal instruction
The following change is proposed to fix the issue and deals with the
unaligned displacements:
OpenJDK 9 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/9
OpenJDK 8 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/8
The following test case has been isolated by Hiroshi Horii and generates
the illegal instruction, crashing the JVM on PPC64 LE:
UnalignedUnsafeAccess.java:
http://hastebin.com/raw/uqegukific
$ javac UnalignedUnsafeAccess.java
$ java -Xcomp -Xbatch UnalignedUnsafeAccess
The issue can be reproduced on OpenJDK 8 downstream, OpenJDK 8, and
OpenJDK 9 - hs_err logs:
OpenJDK 9, tag 0be6f4f5d186 jdk-9+120:
http://hastebin.com/raw/ecuhukutur
OpenJDK 8, tag 5aaa43d91c73 tip:
http://hastebin.com/raw/ipohoyafos
OpenJDK 8 downstream:
Ubuntu 16.04 LTS
build 1.8.0_91-8u91-b14-0ubuntu4~16.04.1-b14
http://hastebin.com/raw/yetizebofo
RHEL 7.2:
build 1.8.0_91-b14
http://hastebin.com/raw/irequfawaw
The crash happens when an illegal instruction - 0xea2f0013 - is executed.
The backtrace shows:
Stack: [0x00003fff56030000,0x00003fff56430000], sp=0x00003fff5642b8d0, free space=4078k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x162104] loadI2LNode::emit(CodeBuffer&, PhaseRegAlloc*) const+0x194
V [libjvm.so+0x8ece28] Compile::fill_buffer(CodeBuffer*, unsigned int*)+0x4e8
V [libjvm.so+0x368e08] Compile::Code_Gen()+0x3c8
V [libjvm.so+0x369e04] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool)+0xf64
V [libjvm.so+0x271380] C2Compiler::compile_method(ciEnv*, ciMethod*, int)+0x1f0
V [libjvm.so+0x3785a4] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xd54
V [libjvm.so+0x379dc8] CompileBroker::compiler_thread_loop()+0x488
V [libjvm.so+0xa5de90] compiler_thread_entry(JavaThread*, Thread*)+0x20
V [libjvm.so+0xa690c8] JavaThread::thread_main_inner()+0x178
V [libjvm.so+0x8c8c10] java_start(Thread*)+0x170
C [libpthread.so.0+0x833c] start_thread+0xfc
C [libc.so.6+0x12b014] clone+0xe4
loadI2LNode class is generated according to the following ADL code in
ppc.ad file:
instruct loadI2L(iRegLdst dst, memory mem) %{
match(Set dst (ConvI2L (LoadI mem)));
predicate(_kids[0]->_leaf->as_Load()->is_unordered());
ins_cost(MEMORY_REF_COST);
format %{ "LWA $dst, $mem \t// loadI2L" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_lwa);
int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
__ lwa($dst$$Register, Idisp, $mem$$base$$Register);
%}
ins_pipe(pipe_class_memory);
%}
So the generated illegal instruction comes from:
lwa 17,17,15 (DS-form: lwa RT, DS, RA)
As DS field must always be 4-byte aligned (i.e. DS field is always
concatenated with 0b00), 17 as DS (middle 17 value) is illegal,
generating the illegal instruction in question:
11101010000000000000000000000010: LWA
00000010001000000000000000000000: 17
00000000000000000000000000010001: 17
00000000000011110000000000000000: 15
--------------------------------
11101010001011110000000000010011: 0xEA2F0013 => Illegal instruction
The following change is proposed to fix the issue and deals with the
unaligned displacements:
OpenJDK 9 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/9
OpenJDK 8 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/8
- duplicates
-
JDK-8158260 PPC64: unaligned Unsafe.getInt can lead to the generation of illegal instructions
- Closed