Skip to content

Commit 62dcb12

Browse files
authored
Merge branch 'openjdk:master' into backport-mrserb-fdc11a15-master
2 parents 514e66f + dfc0276 commit 62dcb12

File tree

91 files changed

+5340
-666
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+5340
-666
lines changed

.github/workflows/build-cross-compile.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,33 @@ jobs:
6060
gnu-arch: aarch64
6161
debian-arch: arm64
6262
debian-repository: https://httpredir.debian.org/debian/
63-
debian-version: bookworm
63+
debian-version: trixie
6464
tolerate-sysroot-errors: false
6565
- target-cpu: arm
6666
gnu-arch: arm
6767
debian-arch: armhf
6868
debian-repository: https://httpredir.debian.org/debian/
69-
debian-version: bookworm
69+
debian-version: trixie
7070
tolerate-sysroot-errors: false
7171
gnu-abi: eabihf
7272
- target-cpu: s390x
7373
gnu-arch: s390x
7474
debian-arch: s390x
7575
debian-repository: https://httpredir.debian.org/debian/
76-
debian-version: bookworm
76+
debian-version: trixie
7777
tolerate-sysroot-errors: false
7878
- target-cpu: ppc64le
7979
gnu-arch: powerpc64le
8080
debian-arch: ppc64el
8181
debian-repository: https://httpredir.debian.org/debian/
82-
debian-version: bookworm
82+
debian-version: trixie
8383
tolerate-sysroot-errors: false
8484
- target-cpu: riscv64
8585
gnu-arch: riscv64
8686
debian-arch: riscv64
8787
debian-repository: https://httpredir.debian.org/debian/
88-
debian-version: sid
89-
tolerate-sysroot-errors: true
88+
debian-version: trixie
89+
tolerate-sysroot-errors: false
9090

9191
steps:
9292
- name: 'Checkout the JDK source'

doc/building.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ <h3 id="linux">Linux</h3>
476476
<p>The basic tooling is provided as part of the core operating system,
477477
but you will most likely need to install developer packages.</p>
478478
<p>For apt-based distributions (Debian, Ubuntu, etc), try this:</p>
479-
<pre><code>sudo apt-get install build-essential</code></pre>
479+
<pre><code>sudo apt-get install build-essential autoconf</code></pre>
480480
<p>For rpm-based distributions (Fedora, Red Hat, etc), try this:</p>
481481
<pre><code>sudo yum groupinstall &quot;Development Tools&quot;</code></pre>
482482
<p>For Alpine Linux, aside from basic tooling, install the GNU versions

doc/building.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ will most likely need to install developer packages.
289289

290290
For apt-based distributions (Debian, Ubuntu, etc), try this:
291291
```
292-
sudo apt-get install build-essential
292+
sudo apt-get install build-essential autoconf
293293
```
294294

295295
For rpm-based distributions (Fedora, Red Hat, etc), try this:

src/hotspot/os/aix/os_aix.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
3+
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -1160,21 +1160,24 @@ static void* dll_load_library(const char *filename, int *eno, char *ebuf, int eb
11601160
// If filename matches <name>.so, and loading fails, repeat with <name>.a.
11611161
void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
11621162
void* result = nullptr;
1163-
char* const file_path = strdup(filename);
1164-
char* const pointer_to_dot = strrchr(file_path, '.');
11651163
const char old_extension[] = ".so";
11661164
const char new_extension[] = ".a";
1167-
STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension));
11681165
// First try to load the existing file.
1169-
int eno=0;
1166+
int eno = 0;
11701167
result = dll_load_library(filename, &eno, ebuf, ebuflen);
1171-
// If the load fails,we try to reload by changing the extension to .a for .so files only.
1168+
// If the load fails, we try to reload by changing the extension to .a for .so files only.
11721169
// Shared object in .so format dont have braces, hence they get removed for archives with members.
1173-
if (result == nullptr && eno == ENOENT && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) {
1174-
snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension);
1175-
result = dll_load_library(file_path, &eno, ebuf, ebuflen);
1170+
if (result == nullptr && eno == ENOENT) {
1171+
const char* pointer_to_dot = strrchr(filename, '.');
1172+
if (pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) {
1173+
STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension));
1174+
char* tmp_path = os::strdup(filename);
1175+
size_t prefix_size = pointer_delta(pointer_to_dot, filename, 1);
1176+
os::snprintf(tmp_path + prefix_size, sizeof(old_extension), "%s", new_extension);
1177+
result = dll_load_library(tmp_path, &eno, ebuf, ebuflen);
1178+
os::free(tmp_path);
1179+
}
11761180
}
1177-
FREE_C_HEAP_ARRAY(char, file_path);
11781181
return result;
11791182
}
11801183

src/hotspot/share/memory/guardedMemory.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
#include "memory/guardedMemory.hpp"
2828
#include "runtime/os.hpp"
2929

30-
void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
30+
void* GuardedMemory::wrap_copy(const void* ptr, const size_t len,
31+
const void* tag, const void* tag2) {
3132
size_t total_sz = GuardedMemory::get_total_size(len);
3233
void* outerp = os::malloc(total_sz, mtInternal);
3334
if (outerp != nullptr) {
34-
GuardedMemory guarded(outerp, len, tag);
35+
GuardedMemory guarded(outerp, len, tag, tag2);
3536
void* innerp = guarded.get_user_ptr();
3637
if (ptr != nullptr) {
3738
memcpy(innerp, ptr, len);
@@ -60,8 +61,8 @@ void GuardedMemory::print_on(outputStream* st) const {
6061
return;
6162
}
6263
st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
63-
" tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
64-
p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
64+
" tag=" PTR_FORMAT "tag2=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
65+
p2i(this), p2i(_base_addr), p2i(get_tag()), p2i(get_tag2()), get_user_size(), p2i(get_user_ptr()));
6566

6667
Guard* guard = get_head_guard();
6768
st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));

src/hotspot/share/memory/guardedMemory.hpp

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
2626
#define SHARE_MEMORY_GUARDEDMEMORY_HPP
2727

2828
#include "memory/allocation.hpp"
29+
#include "runtime/os.hpp"
2930
#include "utilities/globalDefinitions.hpp"
3031

3132
/**
@@ -41,15 +42,19 @@
4142
* |Offset | Content | Description |
4243
* |------------------------------------------------------------
4344
* |base_addr | 0xABABABABABABABAB | Head guard |
44-
* |+16 | <size_t:user_size> | User data size |
45-
* |+sizeof(uintptr_t) | <tag> | Tag word |
45+
* |+GUARD_SIZE | <size_t:user_size> | User data size |
46+
* |+sizeof(size_t) | <tag> | Tag word |
47+
* |+sizeof(void*) | <tag2> | Tag word |
48+
* |+sizeof(void*) | <pad bytes> | Padding |
4649
* |+sizeof(void*) | 0xF1 <user_data> ( | User data |
4750
* |+user_size | 0xABABABABABABABAB | Tail guard |
4851
* -------------------------------------------------------------
4952
*
5053
* Where:
5154
* - guard padding uses "badResourceValue" (0xAB)
52-
* - tag word is general purpose
55+
* - tag word and tag2 word are general purpose
56+
* - padding is inserted as-needed by the compiler to ensure
57+
* the user data is aligned on a 16-byte boundary
5358
* - user data
5459
* -- initially padded with "uninitBlockPad" (0xF1),
5560
* -- to "freeBlockPad" (0xBA), when freed
@@ -111,6 +116,10 @@ class GuardedMemory : StackObj { // Wrapper on stack
111116
}
112117

113118
bool verify() const {
119+
// We may not be able to dereference directly.
120+
if (!os::is_readable_range((const void*) _guard, (const void*) (_guard + GUARD_SIZE))) {
121+
return false;
122+
}
114123
u_char* c = (u_char*) _guard;
115124
u_char* end = c + GUARD_SIZE;
116125
while (c < end) {
@@ -126,24 +135,30 @@ class GuardedMemory : StackObj { // Wrapper on stack
126135

127136
/**
128137
* Header guard and size
138+
*
139+
* NB: the size and placement of the GuardHeader must be such that the
140+
* user-ptr is maximally aligned i.e. 16-byte alignment for x86 ABI for
141+
* stack alignment and use of vector (xmm) instructions. We use alignas
142+
* to achieve this.
129143
*/
130-
class GuardHeader : Guard {
144+
class alignas(16) GuardHeader : Guard {
131145
friend class GuardedMemory;
132146
protected:
133-
// Take care in modifying fields here, will effect alignment
134-
// e.g. x86 ABI 16 byte stack alignment
135147
union {
136148
uintptr_t __unused_full_word1;
137149
size_t _user_size;
138150
};
139151
void* _tag;
152+
void* _tag2;
140153
public:
141154
void set_user_size(const size_t usz) { _user_size = usz; }
142155
size_t get_user_size() const { return _user_size; }
143156

144157
void set_tag(const void* tag) { _tag = (void*) tag; }
145158
void* get_tag() const { return _tag; }
146159

160+
void set_tag2(const void* tag2) { _tag2 = (void*) tag2; }
161+
void* get_tag2() const { return _tag2; }
147162
}; // GuardedMemory::GuardHeader
148163

149164
// Guarded Memory...
@@ -162,9 +177,11 @@ class GuardedMemory : StackObj { // Wrapper on stack
162177
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
163178
* @param user_size the size of the user data to be wrapped.
164179
* @param tag optional general purpose tag.
180+
* @param tag2 optional second general purpose tag.
165181
*/
166-
GuardedMemory(void* base_ptr, const size_t user_size, const void* tag = nullptr) {
167-
wrap_with_guards(base_ptr, user_size, tag);
182+
GuardedMemory(void* base_ptr, const size_t user_size,
183+
const void* tag = nullptr, const void* tag2 = nullptr) {
184+
wrap_with_guards(base_ptr, user_size, tag, tag2);
168185
}
169186

170187
/**
@@ -189,16 +206,19 @@ class GuardedMemory : StackObj { // Wrapper on stack
189206
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
190207
* @param user_size the size of the user data to be wrapped.
191208
* @param tag optional general purpose tag.
209+
* @param tag2 optional second general purpose tag.
192210
*
193211
* @return user data pointer (inner pointer to supplied "base_ptr").
194212
*/
195-
void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = nullptr) {
213+
void* wrap_with_guards(void* base_ptr, size_t user_size,
214+
const void* tag = nullptr, const void* tag2 = nullptr) {
196215
assert(base_ptr != nullptr, "Attempt to wrap null with memory guard");
197216
_base_addr = (u_char*)base_ptr;
198217
get_head_guard()->build();
199218
get_head_guard()->set_user_size(user_size);
200219
get_tail_guard()->build();
201220
set_tag(tag);
221+
set_tag2(tag2);
202222
set_user_bytes(uninitBlockPad);
203223
assert(verify_guards(), "Expected valid memory guards");
204224
return get_user_ptr();
@@ -230,6 +250,20 @@ class GuardedMemory : StackObj { // Wrapper on stack
230250
*/
231251
void* get_tag() const { return get_head_guard()->get_tag(); }
232252

253+
/**
254+
* Set the second general purpose tag.
255+
*
256+
* @param tag general purpose tag.
257+
*/
258+
void set_tag2(const void* tag) { get_head_guard()->set_tag2(tag); }
259+
260+
/**
261+
* Return the second general purpose tag.
262+
*
263+
* @return the second general purpose tag, defaults to null.
264+
*/
265+
void* get_tag2() const { return get_head_guard()->get_tag2(); }
266+
233267
/**
234268
* Return the size of the user data.
235269
*
@@ -302,10 +336,12 @@ class GuardedMemory : StackObj { // Wrapper on stack
302336
* @param ptr the memory to be copied
303337
* @param len the length of the copy
304338
* @param tag optional general purpose tag (see GuardedMemory::get_tag())
339+
* @param tag2 optional general purpose tag (see GuardedMemory::get_tag2())
305340
*
306341
* @return guarded wrapped memory pointer to the user area, or null if OOM.
307342
*/
308-
static void* wrap_copy(const void* p, const size_t len, const void* tag = nullptr);
343+
static void* wrap_copy(const void* p, const size_t len,
344+
const void* tag = nullptr, const void* tag2 = nullptr);
309345

310346
/**
311347
* Free wrapped copy.

src/hotspot/share/prims/jniCheck.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -351,24 +351,33 @@ check_is_obj_array(JavaThread* thr, jarray jArray) {
351351
}
352352
}
353353

354+
// Arbitrary (but well-known) tag for GetStringChars
355+
const void* STRING_TAG = (void*)0x47114711;
356+
357+
// Arbitrary (but well-known) tag for GetStringUTFChars
358+
const void* STRING_UTF_TAG = (void*) 0x48124812;
359+
360+
// Arbitrary (but well-known) tag for GetPrimitiveArrayCritical
361+
const void* CRITICAL_TAG = (void*)0x49134913;
362+
354363
/*
355364
* Copy and wrap array elements for bounds checking.
356365
* Remember the original elements (GuardedMemory::get_tag())
357366
*/
358367
static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
359-
void* orig_elements) {
368+
void* orig_elements, jboolean is_critical = JNI_FALSE) {
360369
void* result;
361370
IN_VM(
362371
oop a = JNIHandles::resolve_non_null(array);
363372
size_t len = arrayOop(a)->length() <<
364373
TypeArrayKlass::cast(a->klass())->log2_element_size();
365-
result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
374+
result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements, is_critical ? CRITICAL_TAG : nullptr);
366375
)
367376
return result;
368377
}
369378

370379
static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
371-
void* obj, void* carray, size_t* rsz) {
380+
void* obj, void* carray, size_t* rsz, jboolean is_critical) {
372381
if (carray == nullptr) {
373382
tty->print_cr("%s: elements vector null" PTR_FORMAT, fn_name, p2i(obj));
374383
NativeReportJNIFatalError(thr, "Elements vector null");
@@ -387,6 +396,29 @@ static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
387396
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
388397
NativeReportJNIFatalError(thr, err_msg("%s: unrecognized elements", fn_name));
389398
}
399+
if (orig_result == STRING_TAG || orig_result == STRING_UTF_TAG) {
400+
bool was_utf = orig_result == STRING_UTF_TAG;
401+
tty->print_cr("%s: called on something allocated by %s",
402+
fn_name, was_utf ? "GetStringUTFChars" : "GetStringChars");
403+
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
404+
NativeReportJNIFatalError(thr, err_msg("%s called on something allocated by %s",
405+
fn_name, was_utf ? "GetStringUTFChars" : "GetStringChars"));
406+
}
407+
408+
if (is_critical && (guarded.get_tag2() != CRITICAL_TAG)) {
409+
tty->print_cr("%s: called on something not allocated by GetPrimitiveArrayCritical", fn_name);
410+
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
411+
NativeReportJNIFatalError(thr, err_msg("%s called on something not allocated by GetPrimitiveArrayCritical",
412+
fn_name));
413+
}
414+
415+
if (!is_critical && (guarded.get_tag2() == CRITICAL_TAG)) {
416+
tty->print_cr("%s: called on something allocated by GetPrimitiveArrayCritical", fn_name);
417+
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
418+
NativeReportJNIFatalError(thr, err_msg("%s called on something allocated by GetPrimitiveArrayCritical",
419+
fn_name));
420+
}
421+
390422
if (rsz != nullptr) {
391423
*rsz = guarded.get_user_size();
392424
}
@@ -396,7 +428,7 @@ static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
396428
static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name,
397429
void* obj, void* carray, jint mode, jboolean is_critical) {
398430
size_t sz;
399-
void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
431+
void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz, is_critical);
400432
switch (mode) {
401433
case 0:
402434
memcpy(orig_result, carray, sz);
@@ -1431,9 +1463,6 @@ JNI_ENTRY_CHECKED(jsize,
14311463
return result;
14321464
JNI_END
14331465

1434-
// Arbitrary (but well-known) tag
1435-
const void* STRING_TAG = (void*)0x47114711;
1436-
14371466
JNI_ENTRY_CHECKED(const jchar *,
14381467
checked_jni_GetStringChars(JNIEnv *env,
14391468
jstring str,
@@ -1515,9 +1544,6 @@ JNI_ENTRY_CHECKED(jsize,
15151544
return result;
15161545
JNI_END
15171546

1518-
// Arbitrary (but well-known) tag - different than GetStringChars
1519-
const void* STRING_UTF_TAG = (void*) 0x48124812;
1520-
15211547
JNI_ENTRY_CHECKED(const char *,
15221548
checked_jni_GetStringUTFChars(JNIEnv *env,
15231549
jstring str,
@@ -1839,7 +1865,7 @@ JNI_ENTRY_CHECKED(void *,
18391865
)
18401866
void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
18411867
if (result != nullptr) {
1842-
result = check_jni_wrap_copy_array(thr, array, result);
1868+
result = check_jni_wrap_copy_array(thr, array, result, JNI_TRUE);
18431869
}
18441870
functionExit(thr);
18451871
return result;

0 commit comments

Comments
 (0)