ADDITIONAL SYSTEM INFORMATION :
32-bit ARM Debian 13 Docker container running inside of a 64-bit ARM Debian 13 device which has a 64-bit ARM CPU that is compatible on a hardware level with running both 32-bit ARM and 64-bit ARM binaries,
which has `uname -a` output `Linux 1185996bc235 6.12.48+deb13-arm64 #1 SMP Debian 6.12.48-1 (2025-09-20) armv8l GNU/Linux`,
`free -h` output
```
total used free shared buff/cache available
Mem: 15Gi 1.1Gi 2.4Gi 104Mi 12Gi 14Gi
Swap: 976Mi 0B 976Mi
```
`df -h` output
```
Filesystem Size Used Avail Use% Mounted on
overlay 117G 45G 67G 40% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/sda2 117G 45G 67G 40% /etc/hosts
tmpfs 7.8G 0 7.8G 0% /proc/acpi
tmpfs 7.8G 0 7.8G 0% /sys/firmware
```
and `nproc` output `32`.
Boot JDK for build is package `openjdk-21-jdk` 21.0.9+10-Debian-1 from `sudo apt install openjdk-21-jdk` in 32-bit ARM Debian 13
Clang is version 1:19.0-63 19.1.7 from `sudo apt install clang` in 32-bit ARM hard float (`armhf`) Debian 13
A DESCRIPTION OF THE PROBLEM :
OpenJDK 21 fails to build with Clang on 32-bit ARM Debian 13 GNU/Linux with several assembly-related errors in several files, `os_linux_arm.cpp`, `linux_arm_32.S` and `icache_arm.cpp`, which look like this:
```
/root/jdk21u/src/hotspot/cpu/arm/icache_arm.cpp:34:27: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'address' (aka 'unsigned char *')
34 | __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
| ^~~~
7 warnings and 1 error generated.
```
and if working around those assembly-related errors is attempted, using this patch, which was originally written by Duy Tran Khanh,
```
diff --git a/src/hotspot/cpu/arm/icache_arm.cpp b/src/hotspot/cpu/arm/icache_arm.cpp
index 61fcb8a3580..93d2ad4f494 100644
--- a/src/hotspot/cpu/arm/icache_arm.cpp
+++ b/src/hotspot/cpu/arm/icache_arm.cpp
@@ -31,7 +31,7 @@
static int icache_flush(address addr, int lines, int magic) {
- __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
+ __builtin___clear_cache((char*) addr, (char*) (addr + (lines << ICache::log2_line_size)));
return magic;
}
diff --git a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
index eb560d8f0c7..be8da136ba2 100644
--- a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
+++ b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
@@ -88,7 +88,7 @@ dw_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt dw_f2b_loop_32
dw_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq disjoint_words_finish
cmp r2, #16
blt disjoint_words_small
@@ -136,7 +136,7 @@ cw_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cw_f2b_loop_32
cw_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_words_finish
cmp r2, #16
blt conjoint_words_small
@@ -169,7 +169,7 @@ cw_b2f_loop_32:
stmdb to!, {r3-r9,ip}
bgt cw_b2f_loop_32
cw_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_words_finish
cmp r2, #16
blt cw_b2f_copy_small
@@ -221,7 +221,7 @@ cs_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cs_f2b_loop_32
cs_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_shorts_finish
movs r6, r2, lsr #3
.align 3
@@ -237,11 +237,11 @@ cs_f2b_4:
beq conjoint_shorts_finish
cmp r2, #4
ldrh r3, [from], #2
- ldrgeh r4, [from], #2
- ldrgth r5, [from], #2
+ ldrhge r4, [from], #2
+ ldrhgt r5, [from], #2
strh r3, [to], #2
- strgeh r4, [to], #2
- strgth r5, [to], #2
+ strhge r4, [to], #2
+ strhgt r5, [to], #2
b conjoint_shorts_finish
# Destination not aligned
@@ -299,11 +299,11 @@ cs_f2b_4_u:
beq conjoint_shorts_finish
cmp r2, #4
ldrh r3, [from], #2
- ldrgeh r4, [from], #2
- ldrgth r5, [from], #2
+ ldrhge r4, [from], #2
+ ldrhgt r5, [from], #2
strh r3, [to], #2
- strgeh r4, [to], #2
- strgth r5, [to], #2
+ strhge r4, [to], #2
+ strhgt r5, [to], #2
b conjoint_shorts_finish
# Src and dest overlap, copy in a descending order
@@ -326,7 +326,7 @@ cs_b2f_loop_32:
stmdb to!, {r3-r9,ip}
bgt cs_b2f_loop_32
cs_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_shorts_finish
cmp r2, #24
blt cs_b2f_16
@@ -352,11 +352,11 @@ cs_b2f_8:
cs_b2f_all_copy:
cmp r2, #4
ldrh r3, [from, #-2]!
- ldrgeh r4, [from, #-2]!
- ldrgth r5, [from, #-2]!
+ ldrhge r4, [from, #-2]!
+ ldrhgt r5, [from, #-2]!
strh r3, [to, #-2]!
- strgeh r4, [to, #-2]!
- strgth r5, [to, #-2]!
+ strhge r4, [to, #-2]!
+ strhgt r5, [to, #-2]!
b conjoint_shorts_finish
# Destination not aligned
@@ -391,7 +391,7 @@ cs_b2f_16_loop_u:
bgt cs_b2f_16_loop_u
beq conjoint_shorts_finish
cs_b2f_16_loop_u_finished:
- addlts r2, #16
+ addslt r2, #16
ldr r3, [from]
cmp r2, #10
blt cs_b2f_2_u_loop
@@ -454,7 +454,7 @@ cl_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cl_f2b_loop_32
cl_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_longs_finish
conjoint_longs_small:
cmp r2, #16
@@ -487,7 +487,7 @@ cl_b2f_loop_32:
stmdb to!, {r3 - r9, ip}
bgt cl_b2f_loop_32
cl_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_longs_finish
cmp r2, #16
blt cl_b2f_copy_8
diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
index 3726aca8a5d..bedb719651f 100644
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
@@ -433,8 +433,8 @@ void os::setup_fpu() {
#if !defined(__SOFTFP__) && defined(__VFP_FP__)
// Turn on IEEE-754 compliant VFP mode
__asm__ volatile (
- "mov %%r0, #0;"
- "fmxr fpscr, %%r0"
+ "mov r0, #0;"
+ "fmxr fpscr, r0"
: /* no output */ : /* no input */ : "r0"
);
#endif
```
then the build appears to progress further, but eventually fails with an additional error which looks like this:
```
Optimizing the exploded image
Error occurred during initialization of VM
java.lang.StackOverflowError
at java.lang.String.<clinit>(java.base/String.java:226)
```
It is suspected there are possibly more problems that could occur at runtime if the compilation of OpenJDK 21 for 32-bit ARM GNU/Linux using Clang compiler were eventually successful, which would not occur in a build of OpenJDK for 32-bit ARM GNU/Linux that was built using GCC compiler, but it is difficult to reach the point of testing to check for those runtime problems because of the errors before that point that only occur when attempting to build using Clang compiler.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install and set up the 32-bit ARM hard float (`armhf`) release of Debian 13 GNU/Linux on a compatible device
2. Install `build-essential`, `openjdk-21-jdk` and `clang` in it
3. Download the source code of OpenJDK 21.0.9 from https://github.com/openjdk/jdk21u/archive/refs/tags/jdk-21.0.9-ga.tar.gz and extract it
4. Change directory to the source code folder and run these commands to attempt to build OpenJDK natively for 32-bit ARM GNU/Linux using Clang compiler:
```
export CC=clang CXX=clang++
./configure --with-toolchain-type=clang --disable-warnings-as-errors --disable-precompiled-headers --with-extra-cflags="-DARM" --with-extra-cxxflags="-DARM"
make
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successful build of OpenJDK 21 natively for 32-bit ARM GNU/Linux on a 32-bit ARM GNU/Linux device using Clang, and also successful running of the resulting build produced by Clang on 32-bit ARM GNU/Linux devices without any runtime errors
ACTUAL -
First error seen with unmodified source code:
```
/root/jdk21u/src/hotspot/cpu/arm/icache_arm.cpp:34:27: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'address' (aka 'unsigned char *')
34 | __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
| ^~~~
7 warnings and 1 error generated.
```
Error that I have not been able to progress past after attempting to progress by modifying the source code:
```
Optimizing the exploded image
Error occurred during initialization of VM
java.lang.StackOverflowError
at java.lang.String.<clinit>(java.base/String.java:226)
```
---------- BEGIN SOURCE ----------
uname -m # ensure that it shows either 'armv8l' (indicates 64-bit ARM Linux kernel running in 32-bit ARM hard float backwards compatibility mode) or 'armv7l' (indicates a purely 32-bit ARM hard float Linux kernel)
export CC=clang CXX=clang++
./configure --with-toolchain-type=clang --disable-warnings-as-errors --disable-precompiled-headers --with-extra-cflags="-DARM" --with-extra-cxxflags="-DARM"
make
---------- END SOURCE ----------
32-bit ARM Debian 13 Docker container running inside of a 64-bit ARM Debian 13 device which has a 64-bit ARM CPU that is compatible on a hardware level with running both 32-bit ARM and 64-bit ARM binaries,
which has `uname -a` output `Linux 1185996bc235 6.12.48+deb13-arm64 #1 SMP Debian 6.12.48-1 (2025-09-20) armv8l GNU/Linux`,
`free -h` output
```
total used free shared buff/cache available
Mem: 15Gi 1.1Gi 2.4Gi 104Mi 12Gi 14Gi
Swap: 976Mi 0B 976Mi
```
`df -h` output
```
Filesystem Size Used Avail Use% Mounted on
overlay 117G 45G 67G 40% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/sda2 117G 45G 67G 40% /etc/hosts
tmpfs 7.8G 0 7.8G 0% /proc/acpi
tmpfs 7.8G 0 7.8G 0% /sys/firmware
```
and `nproc` output `32`.
Boot JDK for build is package `openjdk-21-jdk` 21.0.9+10-Debian-1 from `sudo apt install openjdk-21-jdk` in 32-bit ARM Debian 13
Clang is version 1:19.0-63 19.1.7 from `sudo apt install clang` in 32-bit ARM hard float (`armhf`) Debian 13
A DESCRIPTION OF THE PROBLEM :
OpenJDK 21 fails to build with Clang on 32-bit ARM Debian 13 GNU/Linux with several assembly-related errors in several files, `os_linux_arm.cpp`, `linux_arm_32.S` and `icache_arm.cpp`, which look like this:
```
/root/jdk21u/src/hotspot/cpu/arm/icache_arm.cpp:34:27: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'address' (aka 'unsigned char *')
34 | __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
| ^~~~
7 warnings and 1 error generated.
```
and if working around those assembly-related errors is attempted, using this patch, which was originally written by Duy Tran Khanh,
```
diff --git a/src/hotspot/cpu/arm/icache_arm.cpp b/src/hotspot/cpu/arm/icache_arm.cpp
index 61fcb8a3580..93d2ad4f494 100644
--- a/src/hotspot/cpu/arm/icache_arm.cpp
+++ b/src/hotspot/cpu/arm/icache_arm.cpp
@@ -31,7 +31,7 @@
static int icache_flush(address addr, int lines, int magic) {
- __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
+ __builtin___clear_cache((char*) addr, (char*) (addr + (lines << ICache::log2_line_size)));
return magic;
}
diff --git a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
index eb560d8f0c7..be8da136ba2 100644
--- a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
+++ b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
@@ -88,7 +88,7 @@ dw_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt dw_f2b_loop_32
dw_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq disjoint_words_finish
cmp r2, #16
blt disjoint_words_small
@@ -136,7 +136,7 @@ cw_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cw_f2b_loop_32
cw_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_words_finish
cmp r2, #16
blt conjoint_words_small
@@ -169,7 +169,7 @@ cw_b2f_loop_32:
stmdb to!, {r3-r9,ip}
bgt cw_b2f_loop_32
cw_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_words_finish
cmp r2, #16
blt cw_b2f_copy_small
@@ -221,7 +221,7 @@ cs_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cs_f2b_loop_32
cs_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_shorts_finish
movs r6, r2, lsr #3
.align 3
@@ -237,11 +237,11 @@ cs_f2b_4:
beq conjoint_shorts_finish
cmp r2, #4
ldrh r3, [from], #2
- ldrgeh r4, [from], #2
- ldrgth r5, [from], #2
+ ldrhge r4, [from], #2
+ ldrhgt r5, [from], #2
strh r3, [to], #2
- strgeh r4, [to], #2
- strgth r5, [to], #2
+ strhge r4, [to], #2
+ strhgt r5, [to], #2
b conjoint_shorts_finish
# Destination not aligned
@@ -299,11 +299,11 @@ cs_f2b_4_u:
beq conjoint_shorts_finish
cmp r2, #4
ldrh r3, [from], #2
- ldrgeh r4, [from], #2
- ldrgth r5, [from], #2
+ ldrhge r4, [from], #2
+ ldrhgt r5, [from], #2
strh r3, [to], #2
- strgeh r4, [to], #2
- strgth r5, [to], #2
+ strhge r4, [to], #2
+ strhgt r5, [to], #2
b conjoint_shorts_finish
# Src and dest overlap, copy in a descending order
@@ -326,7 +326,7 @@ cs_b2f_loop_32:
stmdb to!, {r3-r9,ip}
bgt cs_b2f_loop_32
cs_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_shorts_finish
cmp r2, #24
blt cs_b2f_16
@@ -352,11 +352,11 @@ cs_b2f_8:
cs_b2f_all_copy:
cmp r2, #4
ldrh r3, [from, #-2]!
- ldrgeh r4, [from, #-2]!
- ldrgth r5, [from, #-2]!
+ ldrhge r4, [from, #-2]!
+ ldrhgt r5, [from, #-2]!
strh r3, [to, #-2]!
- strgeh r4, [to, #-2]!
- strgth r5, [to, #-2]!
+ strhge r4, [to, #-2]!
+ strhgt r5, [to, #-2]!
b conjoint_shorts_finish
# Destination not aligned
@@ -391,7 +391,7 @@ cs_b2f_16_loop_u:
bgt cs_b2f_16_loop_u
beq conjoint_shorts_finish
cs_b2f_16_loop_u_finished:
- addlts r2, #16
+ addslt r2, #16
ldr r3, [from]
cmp r2, #10
blt cs_b2f_2_u_loop
@@ -454,7 +454,7 @@ cl_f2b_loop_32:
stmia to!, {r3 - r9, ip}
bgt cl_f2b_loop_32
cl_f2b_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_longs_finish
conjoint_longs_small:
cmp r2, #16
@@ -487,7 +487,7 @@ cl_b2f_loop_32:
stmdb to!, {r3 - r9, ip}
bgt cl_b2f_loop_32
cl_b2f_loop_32_finish:
- addlts r2, #32
+ addslt r2, #32
beq conjoint_longs_finish
cmp r2, #16
blt cl_b2f_copy_8
diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
index 3726aca8a5d..bedb719651f 100644
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
@@ -433,8 +433,8 @@ void os::setup_fpu() {
#if !defined(__SOFTFP__) && defined(__VFP_FP__)
// Turn on IEEE-754 compliant VFP mode
__asm__ volatile (
- "mov %%r0, #0;"
- "fmxr fpscr, %%r0"
+ "mov r0, #0;"
+ "fmxr fpscr, r0"
: /* no output */ : /* no input */ : "r0"
);
#endif
```
then the build appears to progress further, but eventually fails with an additional error which looks like this:
```
Optimizing the exploded image
Error occurred during initialization of VM
java.lang.StackOverflowError
at java.lang.String.<clinit>(java.base/String.java:226)
```
It is suspected there are possibly more problems that could occur at runtime if the compilation of OpenJDK 21 for 32-bit ARM GNU/Linux using Clang compiler were eventually successful, which would not occur in a build of OpenJDK for 32-bit ARM GNU/Linux that was built using GCC compiler, but it is difficult to reach the point of testing to check for those runtime problems because of the errors before that point that only occur when attempting to build using Clang compiler.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install and set up the 32-bit ARM hard float (`armhf`) release of Debian 13 GNU/Linux on a compatible device
2. Install `build-essential`, `openjdk-21-jdk` and `clang` in it
3. Download the source code of OpenJDK 21.0.9 from https://github.com/openjdk/jdk21u/archive/refs/tags/jdk-21.0.9-ga.tar.gz and extract it
4. Change directory to the source code folder and run these commands to attempt to build OpenJDK natively for 32-bit ARM GNU/Linux using Clang compiler:
```
export CC=clang CXX=clang++
./configure --with-toolchain-type=clang --disable-warnings-as-errors --disable-precompiled-headers --with-extra-cflags="-DARM" --with-extra-cxxflags="-DARM"
make
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successful build of OpenJDK 21 natively for 32-bit ARM GNU/Linux on a 32-bit ARM GNU/Linux device using Clang, and also successful running of the resulting build produced by Clang on 32-bit ARM GNU/Linux devices without any runtime errors
ACTUAL -
First error seen with unmodified source code:
```
/root/jdk21u/src/hotspot/cpu/arm/icache_arm.cpp:34:27: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'address' (aka 'unsigned char *')
34 | __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
| ^~~~
7 warnings and 1 error generated.
```
Error that I have not been able to progress past after attempting to progress by modifying the source code:
```
Optimizing the exploded image
Error occurred during initialization of VM
java.lang.StackOverflowError
at java.lang.String.<clinit>(java.base/String.java:226)
```
---------- BEGIN SOURCE ----------
uname -m # ensure that it shows either 'armv8l' (indicates 64-bit ARM Linux kernel running in 32-bit ARM hard float backwards compatibility mode) or 'armv7l' (indicates a purely 32-bit ARM hard float Linux kernel)
export CC=clang CXX=clang++
./configure --with-toolchain-type=clang --disable-warnings-as-errors --disable-precompiled-headers --with-extra-cflags="-DARM" --with-extra-cxxflags="-DARM"
make
---------- END SOURCE ----------