8283326: Implement SafeFetch statically
Reviewed-by: dholmes, mdoerr, akozlov, lucy
This commit is contained in:
parent
bb7c97bddf
commit
bdf8a2a205
@ -3986,46 +3986,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry,
|
||||
address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
//
|
||||
// arguments:
|
||||
// c_rarg0 = adr
|
||||
// c_rarg1 = errValue
|
||||
//
|
||||
// result:
|
||||
// PPC_RET = *adr or errValue
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ pc();
|
||||
|
||||
// Load *adr into c_rarg1, may fault.
|
||||
*fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// int32_t
|
||||
__ ldrw(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
__ ldr(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// return errValue or *adr
|
||||
*continuation_pc = __ pc();
|
||||
__ mov(r0, c_rarg1);
|
||||
__ ret(lr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments:
|
||||
*
|
||||
@ -7488,14 +7448,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
|
||||
StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
|
||||
&StubRoutines::_safefetchN_fault_pc,
|
||||
&StubRoutines::_safefetchN_continuation_pc);
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -2837,46 +2837,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry, address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
//
|
||||
// arguments:
|
||||
// R0 = adr
|
||||
// R1 = errValue
|
||||
//
|
||||
// result:
|
||||
// R0 = *adr or errValue
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ pc();
|
||||
|
||||
// Load *adr into c_rarg2, may fault.
|
||||
*fault_pc = __ pc();
|
||||
|
||||
switch (size) {
|
||||
case 4: // int32_t
|
||||
__ ldr_s32(R1, Address(R0));
|
||||
break;
|
||||
|
||||
case 8: // int64_t
|
||||
Unimplemented();
|
||||
break;
|
||||
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// return errValue or *adr
|
||||
*continuation_pc = __ pc();
|
||||
__ mov(R0, R1);
|
||||
__ ret();
|
||||
}
|
||||
|
||||
void generate_arraycopy_stubs() {
|
||||
|
||||
// Note: the disjoint stubs must be generated first, some of
|
||||
@ -3029,16 +2989,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_load_long_entry = generate_atomic_load_long();
|
||||
StubRoutines::_atomic_store_long_entry = generate_atomic_store_long();
|
||||
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
assert (sizeof(int) == wordSize, "32-bit architecture");
|
||||
StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
|
||||
StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
|
||||
StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
|
||||
}
|
||||
|
||||
|
||||
void generate_all() {
|
||||
// Generates all stubs and initializes the entry points
|
||||
|
||||
|
@ -3159,45 +3159,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry, address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
//
|
||||
// arguments:
|
||||
// R3_ARG1 = adr
|
||||
// R4_ARG2 = errValue
|
||||
//
|
||||
// result:
|
||||
// R3_RET = *adr or errValue
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ function_entry();
|
||||
|
||||
// Load *adr into R4_ARG2, may fault.
|
||||
*fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// int32_t, signed extended
|
||||
__ lwa(R4_ARG2, 0, R3_ARG1);
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
__ ld(R4_ARG2, 0, R3_ARG1);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// return errValue or *adr
|
||||
*continuation_pc = __ pc();
|
||||
__ mr(R3_RET, R4_ARG2);
|
||||
__ blr();
|
||||
}
|
||||
|
||||
// Stub for BigInteger::multiplyToLen()
|
||||
//
|
||||
// Arguments:
|
||||
@ -4573,14 +4534,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_crc32c_table_addr = StubRoutines::ppc::generate_crc_constants(REVERSE_CRC32C_POLY);
|
||||
StubRoutines::_updateBytesCRC32C = generate_CRC32_updateBytes(true);
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
|
||||
&StubRoutines::_safefetchN_fault_pc,
|
||||
&StubRoutines::_safefetchN_continuation_pc);
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -2196,46 +2196,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry,
|
||||
address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue)
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue)
|
||||
//
|
||||
// arguments:
|
||||
// c_rarg0 = adr
|
||||
// c_rarg1 = errValue
|
||||
//
|
||||
// result:
|
||||
// PPC_RET = *adr or errValue
|
||||
assert_cond(entry != NULL && fault_pc != NULL && continuation_pc != NULL);
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ pc();
|
||||
|
||||
// Load *adr into c_rarg1, may fault.
|
||||
*fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// int32_t
|
||||
__ lw(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
__ ld(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// return errValue or *adr
|
||||
*continuation_pc = __ pc();
|
||||
__ mv(x10, c_rarg1);
|
||||
__ ret();
|
||||
}
|
||||
|
||||
// code for comparing 16 bytes of strings with same encoding
|
||||
void compare_string_16_bytes_same(Label &DIFF1, Label &DIFF2) {
|
||||
const Register result = x10, str1 = x11, cnt1 = x12, str2 = x13, tmp1 = x28, tmp2 = x29, tmp4 = x7, tmp5 = x31;
|
||||
@ -3767,13 +3727,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
generate_throw_exception("delayed StackOverflowError throw_exception",
|
||||
CAST_FROM_FN_PTR(address,
|
||||
SharedRuntime::throw_delayed_StackOverflowError));
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
|
||||
&StubRoutines::_safefetchN_fault_pc,
|
||||
&StubRoutines::_safefetchN_continuation_pc);
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -1458,44 +1458,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy (true, "arrayof_oop_arraycopy_uninit", true);
|
||||
}
|
||||
|
||||
void generate_safefetch(const char* name, int size, address* entry, address* fault_pc, address* continuation_pc) {
|
||||
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
//
|
||||
// arguments:
|
||||
// Z_ARG1 = adr
|
||||
// Z_ARG2 = errValue
|
||||
//
|
||||
// result:
|
||||
// Z_RET = *adr or errValue
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// entry point
|
||||
// Load *adr into Z_ARG2, may fault.
|
||||
*entry = *fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// Sign extended int32_t.
|
||||
__ z_lgf(Z_ARG2, 0, Z_ARG1);
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
__ z_lg(Z_ARG2, 0, Z_ARG1);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// Return errValue or *adr.
|
||||
*continuation_pc = __ pc();
|
||||
__ z_lgr(Z_RET, Z_ARG2);
|
||||
__ z_br(Z_R14);
|
||||
|
||||
}
|
||||
|
||||
// Call interface for AES_encryptBlock, AES_decryptBlock stubs.
|
||||
//
|
||||
// Z_ARG1 - source data block. Ptr to leftmost byte to be processed.
|
||||
@ -2338,10 +2300,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// Comapct string intrinsics: Translate table for string inflate intrinsic. Used by trot instruction.
|
||||
StubRoutines::zarch::_trot_table_addr = (address)StubRoutines::zarch::_trot_table;
|
||||
|
||||
// safefetch stubs
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, &StubRoutines::_safefetch32_continuation_pc);
|
||||
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, &StubRoutines::_safefetchN_fault_pc, &StubRoutines::_safefetchN_continuation_pc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3653,40 +3653,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry,
|
||||
address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ pc();
|
||||
|
||||
__ movl(rax, Address(rsp, 0x8));
|
||||
__ movl(rcx, Address(rsp, 0x4));
|
||||
// Load *adr into eax, may fault.
|
||||
*fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// int32_t
|
||||
__ movl(rax, Address(rcx, 0));
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
Unimplemented();
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// Return errValue or *adr.
|
||||
*continuation_pc = __ pc();
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
address generate_method_entry_barrier() {
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier");
|
||||
@ -3985,14 +3951,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_dtan = generate_libmTan();
|
||||
}
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
|
||||
StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
|
||||
StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -3836,46 +3836,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
void generate_safefetch(const char* name, int size, address* entry,
|
||||
address* fault_pc, address* continuation_pc) {
|
||||
// safefetch signatures:
|
||||
// int SafeFetch32(int* adr, int errValue);
|
||||
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
|
||||
//
|
||||
// arguments:
|
||||
// c_rarg0 = adr
|
||||
// c_rarg1 = errValue
|
||||
//
|
||||
// result:
|
||||
// PPC_RET = *adr or errValue
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
|
||||
// Entry point, pc or function descriptor.
|
||||
*entry = __ pc();
|
||||
|
||||
// Load *adr into c_rarg1, may fault.
|
||||
*fault_pc = __ pc();
|
||||
switch (size) {
|
||||
case 4:
|
||||
// int32_t
|
||||
__ movl(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
case 8:
|
||||
// int64_t
|
||||
__ movq(c_rarg1, Address(c_rarg0, 0));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// return errValue or *adr
|
||||
*continuation_pc = __ pc();
|
||||
__ movq(rax, c_rarg1);
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
// This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
|
||||
// to hide instruction latency
|
||||
//
|
||||
@ -7672,14 +7632,6 @@ address generate_avx_ghash_processBlocks() {
|
||||
StubRoutines::_dtan = generate_libmTan();
|
||||
}
|
||||
}
|
||||
|
||||
// Safefetch stubs.
|
||||
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
|
||||
&StubRoutines::_safefetch32_fault_pc,
|
||||
&StubRoutines::_safefetch32_continuation_pc);
|
||||
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
|
||||
&StubRoutines::_safefetchN_fault_pc,
|
||||
&StubRoutines::_safefetchN_continuation_pc);
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -43,18 +43,6 @@
|
||||
#include "opto/runtime.hpp"
|
||||
#endif
|
||||
|
||||
// For SafeFetch we need POSIX tls and setjmp
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
static pthread_key_t g_jmpbuf_key;
|
||||
|
||||
// return the currently active jump buffer for this thread
|
||||
// - if there is any, NULL otherwise. Called from
|
||||
// zero signal handlers.
|
||||
extern sigjmp_buf* get_jmp_buf_for_continuation() {
|
||||
return (sigjmp_buf*) pthread_getspecific(g_jmpbuf_key);
|
||||
}
|
||||
|
||||
// Declaration and definition of StubGenerator (no .hpp file).
|
||||
// For a more detailed description of the stub routine structure
|
||||
// see the comment in stubRoutines.hpp
|
||||
@ -188,57 +176,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_oop_arraycopy;
|
||||
}
|
||||
|
||||
static int SafeFetch32(int *adr, int errValue) {
|
||||
|
||||
// set up a jump buffer; anchor the pointer to the jump buffer in tls; then
|
||||
// do the pointer access. If pointer is invalid, we crash; in signal
|
||||
// handler, we retrieve pointer to jmp buffer from tls, and jump back.
|
||||
//
|
||||
// Note: the jump buffer itself - which can get pretty large depending on
|
||||
// the architecture - lives on the stack and that is fine, because we will
|
||||
// not rewind the stack: either we crash, in which case signal handler
|
||||
// frame is below us, or we don't crash, in which case it does not matter.
|
||||
sigjmp_buf jb;
|
||||
if (sigsetjmp(jb, 1)) {
|
||||
// we crashed. clean up tls and return default value.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
return errValue;
|
||||
} else {
|
||||
// preparation phase
|
||||
pthread_setspecific(g_jmpbuf_key, &jb);
|
||||
}
|
||||
|
||||
int value = errValue;
|
||||
value = *adr;
|
||||
|
||||
// all went well. clean tls.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
|
||||
|
||||
sigjmp_buf jb;
|
||||
if (sigsetjmp(jb, 1)) {
|
||||
// we crashed. clean up tls and return default value.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
return errValue;
|
||||
} else {
|
||||
// preparation phase
|
||||
pthread_setspecific(g_jmpbuf_key, &jb);
|
||||
}
|
||||
|
||||
intptr_t value = errValue;
|
||||
value = *adr;
|
||||
|
||||
// all went well. clean tls.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
void generate_initial() {
|
||||
// Generates all stubs and initializes the entry points
|
||||
|
||||
@ -285,15 +222,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// arraycopy stubs used by compilers
|
||||
generate_arraycopy_stubs();
|
||||
|
||||
// Safefetch stubs.
|
||||
pthread_key_create(&g_jmpbuf_key, NULL);
|
||||
StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32);
|
||||
StubRoutines::_safefetch32_fault_pc = NULL;
|
||||
StubRoutines::_safefetch32_continuation_pc = NULL;
|
||||
|
||||
StubRoutines::_safefetchN_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetchN);
|
||||
StubRoutines::_safefetchN_fault_pc = NULL;
|
||||
StubRoutines::_safefetchN_continuation_pc = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/statSampler.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
@ -2005,36 +2005,33 @@ static bool checked_mprotect(char* addr, size_t size, int prot) {
|
||||
//
|
||||
if (!os::Aix::xpg_sus_mode()) {
|
||||
|
||||
if (CanUseSafeFetch32()) {
|
||||
const bool read_protected =
|
||||
(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
|
||||
SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
|
||||
|
||||
const bool read_protected =
|
||||
(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
|
||||
SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
|
||||
if (prot & PROT_READ) {
|
||||
rc = !read_protected;
|
||||
} else {
|
||||
rc = read_protected;
|
||||
}
|
||||
|
||||
if (prot & PROT_READ) {
|
||||
rc = !read_protected;
|
||||
} else {
|
||||
rc = read_protected;
|
||||
}
|
||||
if (!rc) {
|
||||
if (os::Aix::on_pase()) {
|
||||
// There is an issue on older PASE systems where mprotect() will return success but the
|
||||
// memory will not be protected.
|
||||
// This has nothing to do with the problem of using mproect() on SPEC1170 incompatible
|
||||
// machines; we only see it rarely, when using mprotect() to protect the guard page of
|
||||
// a stack. It is an OS error.
|
||||
//
|
||||
// A valid strategy is just to try again. This usually works. :-/
|
||||
|
||||
if (!rc) {
|
||||
if (os::Aix::on_pase()) {
|
||||
// There is an issue on older PASE systems where mprotect() will return success but the
|
||||
// memory will not be protected.
|
||||
// This has nothing to do with the problem of using mproect() on SPEC1170 incompatible
|
||||
// machines; we only see it rarely, when using mprotect() to protect the guard page of
|
||||
// a stack. It is an OS error.
|
||||
//
|
||||
// A valid strategy is just to try again. This usually works. :-/
|
||||
|
||||
::usleep(1000);
|
||||
Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
|
||||
if (::mprotect(addr, size, prot) == 0) {
|
||||
const bool read_protected_2 =
|
||||
(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
|
||||
SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
|
||||
rc = true;
|
||||
}
|
||||
::usleep(1000);
|
||||
Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
|
||||
if (::mprotect(addr, size, prot) == 0) {
|
||||
const bool read_protected_2 =
|
||||
(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
|
||||
SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
106
src/hotspot/os/posix/safefetch_sigjmp.cpp
Normal file
106
src/hotspot/os/posix/safefetch_sigjmp.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#ifdef SAFEFETCH_METHOD_SIGSETJMP
|
||||
|
||||
// For SafeFetch we need POSIX TLS and sigsetjmp/longjmp.
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
static pthread_key_t g_jmpbuf_key;
|
||||
|
||||
struct InitTLSKey { InitTLSKey() { pthread_key_create(&g_jmpbuf_key, NULL); } };
|
||||
static InitTLSKey g_init_tly_key;
|
||||
|
||||
// Handle safefetch, sigsetjmp style:
|
||||
//
|
||||
// If a safefetch jump had been established and the sig qualifies, we
|
||||
// jump back to the established jump point (and hence out of signal handling).
|
||||
//
|
||||
// Note that this function will never return for safefetch faults. We just
|
||||
// keep the prototype the same as other handle_safefetch() versions to keep
|
||||
// caller sites simple.
|
||||
bool handle_safefetch(int sig, address ignored1, void* ignored2) {
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
// Retrieve jump buffer pointer from TLS. If not NULL, it means we set the
|
||||
// jump buffer and this is indeed a SafeFetch fault.
|
||||
// Note signal safety: pthread_getspecific is not safe for signal handler
|
||||
// usage, but in practice it works and we have done this in the JVM for many
|
||||
// years (via Thread::current_or_null_safe()).
|
||||
sigjmp_buf* const jb = (sigjmp_buf*) pthread_getspecific(g_jmpbuf_key);
|
||||
if (jb) {
|
||||
siglongjmp(*jb, 1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static bool _SafeFetchXX_internal(const T *adr, T* result) {
|
||||
|
||||
T n = 0;
|
||||
|
||||
// Set up a jump buffer. Anchor its pointer in TLS. Then read from the unsafe address.
|
||||
// If that address was invalid, we fault, and in the signal handler we will jump back
|
||||
// to the jump point.
|
||||
sigjmp_buf jb;
|
||||
if (sigsetjmp(jb, 1) != 0) {
|
||||
// We faulted. Reset TLS slot, then return.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Anchor jump buffer in TLS
|
||||
pthread_setspecific(g_jmpbuf_key, &jb);
|
||||
|
||||
// unsafe access
|
||||
n = *adr;
|
||||
|
||||
// Still here... All went well, adr was valid.
|
||||
// Reset TLS slot, then return result.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
*result = n;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
int SafeFetch32_impl(int *adr, int errValue) {
|
||||
int result;
|
||||
return _SafeFetchXX_internal<int>(adr, &result) ? result : errValue;
|
||||
}
|
||||
|
||||
intptr_t SafeFetchN_impl(intptr_t *adr, intptr_t errValue) {
|
||||
intptr_t result;
|
||||
return _SafeFetchXX_internal<intptr_t>(adr, &result) ? result : errValue;
|
||||
}
|
||||
|
||||
#endif // SAFEFETCH_METHOD_SIGSETJMP
|
44
src/hotspot/os/posix/safefetch_sigjmp.hpp
Normal file
44
src/hotspot/os/posix/safefetch_sigjmp.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_POSIX_SAFEFETCH_SIGJMP_HPP
|
||||
#define OS_POSIX_SAFEFETCH_SIGJMP_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// On Posix platforms that don't do anything better - or cannot, like Zero -
|
||||
// SafeFetch is implemented using setjmp/longjmp. That is reliable and portable,
|
||||
// but slower than other methods, and needs more thread stack (the sigjmp buffer
|
||||
// lives on the thread stack).
|
||||
|
||||
int SafeFetch32_impl(int* adr, int errValue);
|
||||
intptr_t SafeFetchN_impl(intptr_t* adr, intptr_t errValue);
|
||||
|
||||
// Handle safefetch, sigsetjmp style. Only call from signal handler.
|
||||
// If a safefetch jump had been established and the sig qualifies, we
|
||||
// jump back to the established jump point (and hence out of signal handling).
|
||||
bool handle_safefetch(int sig, address pc, void* context);
|
||||
|
||||
#endif // OS_POSIX_SAFEFETCH_SIGJMP_HPP
|
65
src/hotspot/os/posix/safefetch_static_posix.cpp
Normal file
65
src/hotspot/os/posix/safefetch_static_posix.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#ifdef SAFEFETCH_METHOD_STATIC_ASSEMBLY
|
||||
|
||||
// SafeFetch handling, static assembly style:
|
||||
//
|
||||
// SafeFetch32 and SafeFetchN are implemented via static assembly
|
||||
// and live in os_cpu/xx_xx/safefetch_xx_xx.S
|
||||
|
||||
extern "C" char _SafeFetch32_continuation[] __attribute__ ((visibility ("hidden")));
|
||||
extern "C" char _SafeFetch32_fault[] __attribute__ ((visibility ("hidden")));
|
||||
|
||||
#ifdef _LP64
|
||||
extern "C" char _SafeFetchN_continuation[] __attribute__ ((visibility ("hidden")));
|
||||
extern "C" char _SafeFetchN_fault[] __attribute__ ((visibility ("hidden")));
|
||||
#endif // _LP64
|
||||
|
||||
bool handle_safefetch(int sig, address pc, void* context) {
|
||||
ucontext_t* uc = (ucontext_t*)context;
|
||||
if ((sig == SIGSEGV || sig == SIGBUS) && uc != NULL) {
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
if (pc == (address)_SafeFetch32_fault) {
|
||||
os::Posix::ucontext_set_pc(uc, (address)_SafeFetch32_continuation);
|
||||
return true;
|
||||
}
|
||||
#ifdef _LP64
|
||||
if (pc == (address)_SafeFetchN_fault) {
|
||||
os::Posix::ucontext_set_pc(uc, (address)_SafeFetchN_continuation);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // SAFEFETCH_METHOD_STATIC_ASSEMBLY
|
@ -32,20 +32,14 @@
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/semaphore.inline.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
|
||||
#ifdef ZERO
|
||||
// See stubGenerator_zero.cpp
|
||||
#include <setjmp.h>
|
||||
extern sigjmp_buf* get_jmp_buf_for_continuation();
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
@ -599,25 +593,26 @@ int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Extract pc from context. Note that for certain signals and certain
|
||||
// architectures the pc in ucontext_t will point *after* the offending
|
||||
// instruction. In those cases, use siginfo si_addr instead.
|
||||
address pc = NULL;
|
||||
if (uc != NULL) {
|
||||
if (S390_ONLY(sig == SIGILL || sig == SIGFPE) NOT_S390(false)) {
|
||||
pc = (address)info->si_addr;
|
||||
} else if (ZERO_ONLY(true) NOT_ZERO(false)) {
|
||||
// Non-arch-specific Zero code does not really know the pc.
|
||||
// This can be alleviated by making arch-specific os::Posix::ucontext_get_pc
|
||||
// available for Zero for known architectures. But for generic Zero
|
||||
// code, it would still remain unknown.
|
||||
pc = NULL;
|
||||
} else {
|
||||
pc = os::Posix::ucontext_get_pc(uc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!signal_was_handled) {
|
||||
// Handle SafeFetch access.
|
||||
#ifndef ZERO
|
||||
if (uc != NULL) {
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||
os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
|
||||
signal_was_handled = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// See JDK-8076185
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
sigjmp_buf* const pjb = get_jmp_buf_for_continuation();
|
||||
if (pjb) {
|
||||
siglongjmp(*pjb, 1);
|
||||
}
|
||||
}
|
||||
#endif // ZERO
|
||||
signal_was_handled = handle_safefetch(sig, pc, uc);
|
||||
}
|
||||
|
||||
// Ignore SIGPIPE and SIGXFSZ (4229104, 6499219).
|
||||
@ -642,22 +637,6 @@ int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,
|
||||
|
||||
// Invoke fatal error handling.
|
||||
if (!signal_was_handled && abort_if_unrecognized) {
|
||||
// Extract pc from context for the error handler to display.
|
||||
address pc = NULL;
|
||||
if (uc != NULL) {
|
||||
// prepare fault pc address for error reporting.
|
||||
if (S390_ONLY(sig == SIGILL || sig == SIGFPE) NOT_S390(false)) {
|
||||
pc = (address)info->si_addr;
|
||||
} else if (ZERO_ONLY(true) NOT_ZERO(false)) {
|
||||
// Non-arch-specific Zero code does not really know the pc.
|
||||
// This can be alleviated by making arch-specific os::Posix::ucontext_get_pc
|
||||
// available for Zero for known architectures. But for generic Zero
|
||||
// code, it would still remain unknown.
|
||||
pc = NULL;
|
||||
} else {
|
||||
pc = os::Posix::ucontext_get_pc(uc);
|
||||
}
|
||||
}
|
||||
// For Zero, we ignore the crash context, because:
|
||||
// a) The crash would be in C++ interpreter code, so context is not really relevant;
|
||||
// b) Generic Zero code would not be able to parse it, so when generic error
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "cds/metaspaceShared.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
@ -67,7 +67,6 @@ static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
|
||||
|
||||
PosixSignals::unblock_error_signals();
|
||||
|
||||
// support safefetch faults in error handling
|
||||
ucontext_t* const uc = (ucontext_t*) ucVoid;
|
||||
address pc = (uc != NULL) ? os::Posix::ucontext_get_pc(uc) : NULL;
|
||||
|
||||
@ -76,9 +75,8 @@ static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
|
||||
pc = (address) info->si_addr;
|
||||
}
|
||||
|
||||
// Needed to make it possible to call SafeFetch.. APIs in error handling.
|
||||
if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
|
||||
os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
|
||||
// Handle safefetch here too, to be able to use SafeFetch() inside the error handler
|
||||
if (handle_safefetch(sig, pc, uc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,12 @@
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/semaphore.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/statSampler.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/threadCritical.hpp"
|
||||
#include "runtime/timer.hpp"
|
||||
@ -2494,11 +2495,6 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
#endif
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
// Handle SafeFetch32 and SafeFetchN exceptions.
|
||||
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||
return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
// Execution protection violation - win32 running on AMD64 only
|
||||
// Handled first to avoid misdiagnosis as a "normal" access violation;
|
||||
|
53
src/hotspot/os/windows/safefetch_windows.hpp
Normal file
53
src/hotspot/os/windows/safefetch_windows.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_WINDOWS_SAFEFETCH_WINDOWS_HPP
|
||||
#define OS_WINDOWS_SAFEFETCH_WINDOWS_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// On windows, we use structured exception handling to implement SafeFetch
|
||||
|
||||
template <class T>
|
||||
inline T SafeFetchXX(const T* adr, T errValue) {
|
||||
T v = 0;
|
||||
__try {
|
||||
v = *adr;
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
v = errValue;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
inline int SafeFetch32_impl(const int* adr, int errValue) {
|
||||
return SafeFetchXX<int>(adr, errValue);
|
||||
}
|
||||
|
||||
inline intptr_t SafeFetchN_impl(const intptr_t* adr, intptr_t errValue) {
|
||||
return SafeFetchXX<intptr_t>(adr, errValue);
|
||||
}
|
||||
|
||||
#endif
|
71
src/hotspot/os_cpu/bsd_aarch64/safefetch_bsd_aarch64.S
Normal file
71
src/hotspot/os_cpu/bsd_aarch64/safefetch_bsd_aarch64.S
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
# Darwin uses _ prefixed global symbols
|
||||
#define SYMBOL(s) _ ## s
|
||||
#define ELF_TYPE(name, description)
|
||||
#else
|
||||
#define SYMBOL(s) s
|
||||
#define ELF_TYPE(name, description) .type name,description
|
||||
#endif
|
||||
|
||||
.global SYMBOL(SafeFetchN_impl)
|
||||
.global SYMBOL(_SafeFetchN_fault)
|
||||
.global SYMBOL(_SafeFetchN_continuation)
|
||||
.global SYMBOL(SafeFetch32_impl)
|
||||
.global SYMBOL(_SafeFetch32_fault)
|
||||
.global SYMBOL(_SafeFetch32_continuation)
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# x0 : address
|
||||
# w1 : defaultval
|
||||
|
||||
# needed to align function start to 4 byte
|
||||
.align 6
|
||||
ELF_TYPE(SafeFetch32_impl,@function)
|
||||
SYMBOL(SafeFetch32_impl):
|
||||
SYMBOL(_SafeFetch32_fault):
|
||||
ldr w0, [x0]
|
||||
ret
|
||||
SYMBOL(_SafeFetch32_continuation):
|
||||
mov x0, x1
|
||||
ret
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# x1 : address
|
||||
# x0 : defaultval
|
||||
|
||||
.align 6
|
||||
ELF_TYPE(SafeFetchN_impl,@function)
|
||||
SYMBOL(SafeFetchN_impl):
|
||||
SYMBOL(_SafeFetchN_fault):
|
||||
ldr x0, [x0]
|
||||
ret
|
||||
SYMBOL(_SafeFetchN_continuation):
|
||||
mov x0, x1
|
||||
ret
|
67
src/hotspot/os_cpu/bsd_x86/safefetch_bsd_x86_64.S
Normal file
67
src/hotspot/os_cpu/bsd_x86/safefetch_bsd_x86_64.S
Normal file
@ -0,0 +1,67 @@
|
||||
#
|
||||
# Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
#ifdef __APPLE__
|
||||
# Darwin uses _ prefixed global symbols
|
||||
#define SYMBOL(s) _ ## s
|
||||
#define ELF_TYPE(name, description)
|
||||
#else
|
||||
#define SYMBOL(s) s
|
||||
#define ELF_TYPE(name, description) .type name,description
|
||||
#endif
|
||||
|
||||
.globl SYMBOL(SafeFetch32_impl)
|
||||
.globl SYMBOL(SafeFetchN_impl)
|
||||
.globl SYMBOL(_SafeFetch32_fault)
|
||||
.globl SYMBOL(_SafeFetchN_fault)
|
||||
.globl SYMBOL(_SafeFetch32_continuation)
|
||||
.globl SYMBOL(_SafeFetchN_continuation)
|
||||
|
||||
.text
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# %rdi : address
|
||||
# %esi : defaultval
|
||||
ELF_TYPE(SafeFetch32_impl,@function)
|
||||
SYMBOL(SafeFetch32_impl:)
|
||||
SYMBOL(_SafeFetch32_fault:)
|
||||
movl (%rdi), %eax
|
||||
ret
|
||||
SYMBOL(_SafeFetch32_continuation:)
|
||||
movl %esi, %eax
|
||||
ret
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# %rdi : address
|
||||
# %rsi : defaultval
|
||||
ELF_TYPE(SafeFetchN_impl,@function)
|
||||
SYMBOL(SafeFetchN_impl:)
|
||||
SYMBOL(_SafeFetchN_fault:)
|
||||
movq (%rdi), %rax
|
||||
ret
|
||||
SYMBOL(_SafeFetchN_continuation:)
|
||||
movq %rsi, %rax
|
||||
ret
|
55
src/hotspot/os_cpu/linux_aarch64/safefetch_linux_aarch64.S
Normal file
55
src/hotspot/os_cpu/linux_aarch64/safefetch_linux_aarch64.S
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl SafeFetchN_impl
|
||||
.globl _SafeFetchN_fault
|
||||
.globl _SafeFetchN_continuation
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# x0 : address
|
||||
# x1 : defaultval
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
ldr w0, [x0]
|
||||
ret
|
||||
_SafeFetch32_continuation:
|
||||
mov x0, x1
|
||||
ret
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# x1 : address
|
||||
# x0 : defaultval
|
||||
SafeFetchN_impl:
|
||||
_SafeFetchN_fault:
|
||||
ldr x0, [x0]
|
||||
ret
|
||||
_SafeFetchN_continuation:
|
||||
mov x0, x1
|
||||
ret
|
40
src/hotspot/os_cpu/linux_arm/safefetch_linux_arm.S
Normal file
40
src/hotspot/os_cpu/linux_arm/safefetch_linux_arm.S
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# r0 : address
|
||||
# r1 : defaultval
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
ldr r0, [r0]
|
||||
bx lr
|
||||
_SafeFetch32_continuation:
|
||||
mov r0, r1
|
||||
bx lr
|
57
src/hotspot/os_cpu/linux_ppc/safefetch_linux_ppc.S
Normal file
57
src/hotspot/os_cpu/linux_ppc/safefetch_linux_ppc.S
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl SafeFetchN_impl
|
||||
.globl _SafeFetchN_fault
|
||||
.globl _SafeFetchN_continuation
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# r3 : address
|
||||
# r4 : defaultval
|
||||
# r3 : retval
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
lwa %r3, 0(%r3)
|
||||
blr
|
||||
_SafeFetch32_continuation:
|
||||
mr %r3, %r4
|
||||
blr
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# r3 : address
|
||||
# r4 : defaultval
|
||||
# r3 : retval
|
||||
SafeFetchN_impl:
|
||||
_SafeFetchN_fault:
|
||||
ld %r3, 0(%r3)
|
||||
blr
|
||||
_SafeFetchN_continuation:
|
||||
mr %r3, %r4
|
||||
blr
|
57
src/hotspot/os_cpu/linux_riscv/safefetch_linux_riscv.S
Normal file
57
src/hotspot/os_cpu/linux_riscv/safefetch_linux_riscv.S
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl SafeFetchN_impl
|
||||
.globl _SafeFetchN_fault
|
||||
.globl _SafeFetchN_continuation
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# x10 (a0) : address
|
||||
# x11 (a1) : defaultval
|
||||
# x10 (a0) : retval
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
lw a0, 0(a0)
|
||||
ret
|
||||
_SafeFetch32_continuation:
|
||||
mv a0, a1
|
||||
ret
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# x10 (a0) : address
|
||||
# x11 (a1) : defaultval
|
||||
# x10 (a0) : retval
|
||||
SafeFetchN_impl:
|
||||
_SafeFetchN_fault:
|
||||
ld a0, 0(a0)
|
||||
ret
|
||||
_SafeFetchN_continuation:
|
||||
mv a0, a1
|
||||
ret
|
57
src/hotspot/os_cpu/linux_s390/safefetch_linux_s390.S
Normal file
57
src/hotspot/os_cpu/linux_s390/safefetch_linux_s390.S
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl SafeFetchN_impl
|
||||
.globl _SafeFetchN_fault
|
||||
.globl _SafeFetchN_continuation
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# r2 : address
|
||||
# r3 : defaultval
|
||||
# r2 : retval
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
lgf %r2, 0(%r2)
|
||||
br %r14
|
||||
_SafeFetch32_continuation:
|
||||
lgr %r2, %r3
|
||||
br %r14
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# r2 : address
|
||||
# r3 : defaultval
|
||||
# r2 : retval
|
||||
SafeFetchN_impl:
|
||||
_SafeFetchN_fault:
|
||||
lg %r2, 0(%r2)
|
||||
br %r14
|
||||
_SafeFetchN_continuation:
|
||||
lgr %r2, %r3
|
||||
br %r14
|
43
src/hotspot/os_cpu/linux_x86/safefetch_linux_x86_32.S
Normal file
43
src/hotspot/os_cpu/linux_x86/safefetch_linux_x86_32.S
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
.globl SafeFetch32_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
|
||||
.text
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# 8(%esp) : default value
|
||||
# 4(%esp) : crash address
|
||||
# 0(%esp) : return pc
|
||||
.type _SafeFetch32_impl,@function
|
||||
SafeFetch32_impl:
|
||||
movl 4(%esp),%ecx # load address from stack
|
||||
_SafeFetch32_fault:
|
||||
movl (%ecx), %eax # load target value, may fault
|
||||
ret
|
||||
_SafeFetch32_continuation:
|
||||
movl 8(%esp),%eax # load default value from stack
|
||||
ret
|
58
src/hotspot/os_cpu/linux_x86/safefetch_linux_x86_64.S
Normal file
58
src/hotspot/os_cpu/linux_x86/safefetch_linux_x86_64.S
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
.globl SafeFetch32_impl
|
||||
.globl SafeFetchN_impl
|
||||
.globl _SafeFetch32_fault
|
||||
.globl _SafeFetchN_fault
|
||||
.globl _SafeFetch32_continuation
|
||||
.globl _SafeFetchN_continuation
|
||||
|
||||
.text
|
||||
|
||||
|
||||
# Support for int SafeFetch32(int* address, int defaultval);
|
||||
#
|
||||
# %rdi : address
|
||||
# %esi : defaultval
|
||||
.type SafeFetch32_impl,@function
|
||||
SafeFetch32_impl:
|
||||
_SafeFetch32_fault:
|
||||
movl (%rdi), %eax # load target value, may fault
|
||||
ret
|
||||
_SafeFetch32_continuation:
|
||||
movl %esi, %eax # return default
|
||||
ret
|
||||
|
||||
# Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval);
|
||||
#
|
||||
# %rdi : address
|
||||
# %rsi : defaultval
|
||||
.type SafeFetchN_impl,@function
|
||||
SafeFetchN_impl:
|
||||
_SafeFetchN_fault:
|
||||
movq (%rdi), %rax # load target value, may fault
|
||||
ret
|
||||
_SafeFetchN_continuation:
|
||||
movq %rsi, %rax # return default
|
||||
ret
|
@ -36,7 +36,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@ -300,7 +300,6 @@ void OopStorage::Block::set_active_index(size_t index) {
|
||||
|
||||
size_t OopStorage::Block::active_index_safe(const Block* block) {
|
||||
STATIC_ASSERT(sizeof(intptr_t) == sizeof(block->_active_index));
|
||||
assert(CanUseSafeFetchN(), "precondition");
|
||||
return SafeFetchN((intptr_t*)&block->_active_index, 0);
|
||||
}
|
||||
|
||||
@ -366,7 +365,6 @@ void OopStorage::Block::delete_block(const Block& block) {
|
||||
// require additional validation of the result.
|
||||
OopStorage::Block*
|
||||
OopStorage::Block::block_for_ptr(const OopStorage* owner, const oop* ptr) {
|
||||
assert(CanUseSafeFetchN(), "precondition");
|
||||
STATIC_ASSERT(_data_pos == 0);
|
||||
// Const-ness of ptr is not related to const-ness of containing block.
|
||||
// Blocks are allocated section-aligned, so get the containing section.
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/safepointMechanism.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
|
@ -54,7 +54,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/threadSMR.hpp"
|
||||
@ -1045,11 +1045,7 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
|
||||
// Check if pointer can be read from (4-byte read access).
|
||||
// Helps to prove validity of a not-NULL pointer.
|
||||
// Returns true in very early stages of VM life when stub is not yet generated.
|
||||
#define SAFEFETCH_DEFAULT true
|
||||
bool os::is_readable_pointer(const void* p) {
|
||||
if (!CanUseSafeFetch32()) {
|
||||
return SAFEFETCH_DEFAULT;
|
||||
}
|
||||
int* const aligned = (int*) align_down((intptr_t)p, 4);
|
||||
int cafebabe = 0xcafebabe; // tester value 1
|
||||
int deadbeef = 0xdeadbeef; // tester value 2
|
||||
|
58
src/hotspot/share/runtime/safefetch.hpp
Normal file
58
src/hotspot/share/runtime/safefetch.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_RUNTIME_SAFEFETCH_HPP
|
||||
#define SHARE_RUNTIME_SAFEFETCH_HPP
|
||||
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
// Safefetch allows to load a value from a location that's not known
|
||||
// to be valid. If the load causes a fault, the error value is returned.
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows uses Structured Exception Handling
|
||||
#include "safefetch_windows.hpp"
|
||||
#elif defined(ZERO) || defined (_AIX)
|
||||
// These platforms implement safefetch via Posix sigsetjmp/longjmp.
|
||||
// This is slower than the other methods and uses more thread stack,
|
||||
// but its safe and portable.
|
||||
#include "safefetch_sigjmp.hpp"
|
||||
#define SAFEFETCH_METHOD_SIGSETJMP
|
||||
#else
|
||||
// All other platforms use static assembly
|
||||
#include "safefetch_static.hpp"
|
||||
#define SAFEFETCH_METHOD_STATIC_ASSEMBLY
|
||||
#endif
|
||||
|
||||
|
||||
inline int SafeFetch32(int* adr, int errValue) {
|
||||
return SafeFetch32_impl(adr, errValue);
|
||||
}
|
||||
|
||||
inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) {
|
||||
return SafeFetchN_impl(adr, errValue);
|
||||
}
|
||||
|
||||
#endif // SHARE_RUNTIME_SAFEFETCH_HPP
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_RUNTIME_SAFEFETCH_INLINE_HPP
|
||||
#define SHARE_RUNTIME_SAFEFETCH_INLINE_HPP
|
||||
|
||||
// No safefetch.hpp
|
||||
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/threadWXSetters.inline.hpp"
|
||||
|
||||
// Safefetch allows to load a value from a location that's not known
|
||||
// to be valid. If the load causes a fault, the error value is returned.
|
||||
inline int SafeFetch32(int* adr, int errValue) {
|
||||
assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated");
|
||||
#if defined(__APPLE__) && defined(AARCH64)
|
||||
Thread* thread = Thread::current_or_null_safe();
|
||||
assert(thread != NULL, "required for W^X management");
|
||||
ThreadWXEnable wx(WXExec, thread);
|
||||
#endif // __APPLE__ && AARCH64
|
||||
return StubRoutines::SafeFetch32_stub()(adr, errValue);
|
||||
}
|
||||
|
||||
inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) {
|
||||
assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated");
|
||||
#if defined(__APPLE__) && defined(AARCH64)
|
||||
Thread* thread = Thread::current_or_null_safe();
|
||||
assert(thread != NULL, "required for W^X management");
|
||||
ThreadWXEnable wx(WXExec, thread);
|
||||
#endif // __APPLE__ && AARCH64
|
||||
return StubRoutines::SafeFetchN_stub()(adr, errValue);
|
||||
}
|
||||
|
||||
// returns true if SafeFetch32 and SafeFetchN can be used safely (stubroutines are already generated)
|
||||
inline bool CanUseSafeFetch32() {
|
||||
#if defined (__APPLE__) && defined(AARCH64)
|
||||
if (Thread::current_or_null_safe() == NULL) { // workaround for JDK-8282475
|
||||
return false;
|
||||
}
|
||||
#endif // __APPLE__ && AARCH64
|
||||
return StubRoutines::SafeFetch32_stub() ? true : false;
|
||||
}
|
||||
|
||||
inline bool CanUseSafeFetchN() {
|
||||
#if defined (__APPLE__) && defined(AARCH64)
|
||||
if (Thread::current_or_null_safe() == NULL) {
|
||||
return false;
|
||||
}
|
||||
#endif // __APPLE__ && AARCH64
|
||||
return StubRoutines::SafeFetchN_stub() ? true : false;
|
||||
}
|
||||
|
||||
#endif // SHARE_RUNTIME_SAFEFETCH_INLINE_HPP
|
43
src/hotspot/share/runtime/safefetch_static.hpp
Normal file
43
src/hotspot/share/runtime/safefetch_static.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_RUNTIME_SAFEFETCH_STATIC_HPP
|
||||
#define SHARE_RUNTIME_SAFEFETCH_STATIC_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
extern "C" int SafeFetch32_impl(int* adr, int errValue);
|
||||
|
||||
#ifdef _LP64
|
||||
extern "C" intptr_t SafeFetchN_impl(intptr_t* adr, intptr_t errValue);
|
||||
#else
|
||||
inline intptr_t SafeFetchN_impl(intptr_t* adr, intptr_t errValue) {
|
||||
return SafeFetch32_impl(adr, errValue);
|
||||
}
|
||||
#endif // _LP64
|
||||
|
||||
bool handle_safefetch(int sig, address pc, void* context);
|
||||
|
||||
#endif // SHARE_RUNTIME_SAFEFETCH_STATIC_HPP
|
@ -31,8 +31,8 @@
|
||||
#include "prims/vectorSupport.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/timerTrace.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
#ifdef COMPILER2
|
||||
@ -168,13 +168,6 @@ address StubRoutines::_dlibm_reduce_pi04l = NULL;
|
||||
address StubRoutines::_dlibm_tan_cot_huge = NULL;
|
||||
address StubRoutines::_dtan = NULL;
|
||||
|
||||
address StubRoutines::_safefetch32_entry = NULL;
|
||||
address StubRoutines::_safefetch32_fault_pc = NULL;
|
||||
address StubRoutines::_safefetch32_continuation_pc = NULL;
|
||||
address StubRoutines::_safefetchN_entry = NULL;
|
||||
address StubRoutines::_safefetchN_fault_pc = NULL;
|
||||
address StubRoutines::_safefetchN_continuation_pc = NULL;
|
||||
|
||||
address StubRoutines::_vector_f_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP] = {{NULL}, {NULL}};
|
||||
address StubRoutines::_vector_d_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP] = {{NULL}, {NULL}};
|
||||
|
||||
|
@ -250,14 +250,6 @@ class StubRoutines: AllStatic {
|
||||
static address _dlibm_tan_cot_huge;
|
||||
static address _dtan;
|
||||
|
||||
// Safefetch stubs.
|
||||
static address _safefetch32_entry;
|
||||
static address _safefetch32_fault_pc;
|
||||
static address _safefetch32_continuation_pc;
|
||||
static address _safefetchN_entry;
|
||||
static address _safefetchN_fault_pc;
|
||||
static address _safefetchN_continuation_pc;
|
||||
|
||||
// Vector Math Routines
|
||||
static address _vector_f_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP];
|
||||
static address _vector_d_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP];
|
||||
@ -428,34 +420,6 @@ class StubRoutines: AllStatic {
|
||||
|
||||
static address select_fill_function(BasicType t, bool aligned, const char* &name);
|
||||
|
||||
//
|
||||
// Safefetch stub support
|
||||
//
|
||||
|
||||
typedef int (*SafeFetch32Stub)(int* adr, int errValue);
|
||||
typedef intptr_t (*SafeFetchNStub) (intptr_t* adr, intptr_t errValue);
|
||||
|
||||
static SafeFetch32Stub SafeFetch32_stub() { return CAST_TO_FN_PTR(SafeFetch32Stub, _safefetch32_entry); }
|
||||
static SafeFetchNStub SafeFetchN_stub() { return CAST_TO_FN_PTR(SafeFetchNStub, _safefetchN_entry); }
|
||||
|
||||
static bool is_safefetch_fault(address pc) {
|
||||
return pc != NULL &&
|
||||
(pc == _safefetch32_fault_pc ||
|
||||
pc == _safefetchN_fault_pc);
|
||||
}
|
||||
|
||||
static address continuation_for_safefetch_fault(address pc) {
|
||||
assert(_safefetch32_continuation_pc != NULL &&
|
||||
_safefetchN_continuation_pc != NULL,
|
||||
"not initialized");
|
||||
|
||||
if (pc == _safefetch32_fault_pc) return _safefetch32_continuation_pc;
|
||||
if (pc == _safefetchN_fault_pc) return _safefetchN_continuation_pc;
|
||||
|
||||
ShouldNotReachHere();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Default versions of the above arraycopy functions for platforms which do
|
||||
// not have specialized versions
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "services/mallocSiteTable.hpp"
|
||||
#include "services/mallocTracker.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@ -293,7 +293,7 @@ void* MallocTracker::record_free(void* memblock) {
|
||||
// signals popping up, e.g. when writing an hs_err file.
|
||||
bool MallocTracker::print_pointer_information(const void* p, outputStream* st) {
|
||||
assert(MemTracker::enabled(), "NMT must be enabled");
|
||||
if (CanUseSafeFetch32() && os::is_readable_pointer(p)) {
|
||||
if (os::is_readable_pointer(p)) {
|
||||
const NMT_TrackingLevel tracking_level = MemTracker::tracking_level();
|
||||
const MallocHeader* mhdr = malloc_header(p);
|
||||
char msg[256];
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/stackFrameStream.inline.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
@ -597,18 +597,14 @@ void VMError::report(outputStream* st, bool _verbose) {
|
||||
// to test that resetting the signal handler works correctly.
|
||||
if (_verbose && TestSafeFetchInErrorHandler) {
|
||||
st->print_cr("Will test SafeFetch...");
|
||||
if (CanUseSafeFetch32()) {
|
||||
int* const invalid_pointer = (int*)segfault_address;
|
||||
const int x = 0x76543210;
|
||||
int i1 = SafeFetch32(invalid_pointer, x);
|
||||
int i2 = SafeFetch32(invalid_pointer, x);
|
||||
if (i1 == x && i2 == x) {
|
||||
st->print_cr("SafeFetch OK."); // Correctly deflected and returned default pattern
|
||||
} else {
|
||||
st->print_cr("??");
|
||||
}
|
||||
int* const invalid_pointer = (int*)segfault_address;
|
||||
const int x = 0x76543210;
|
||||
int i1 = SafeFetch32(invalid_pointer, x);
|
||||
int i2 = SafeFetch32(invalid_pointer, x);
|
||||
if (i1 == x && i2 == x) {
|
||||
st->print_cr("SafeFetch OK."); // Correctly deflected and returned default pattern
|
||||
} else {
|
||||
st->print_cr("not possible; skipped.");
|
||||
st->print_cr("??");
|
||||
}
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
@ -24,33 +24,120 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/safefetch.inline.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/vmOperations.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
#include "unittest.hpp"
|
||||
#include "testutils.hpp"
|
||||
|
||||
static const intptr_t pattern = LP64_ONLY(0xABCDABCDABCDABCDULL) NOT_LP64(0xABCDABCD);
|
||||
static intptr_t* invalid_address = (intptr_t*)VMError::segfault_address;
|
||||
// Note: beyond these tests, there exist additional tests testing that safefetch in error handling
|
||||
// (in the context of signal handling) works, see runtime/ErrorHandling
|
||||
|
||||
TEST_VM(os, safefetch_can_use) {
|
||||
// Once VM initialization is through,
|
||||
// safefetch should work on every platform.
|
||||
ASSERT_TRUE(CanUseSafeFetch32());
|
||||
static const intptr_t patternN = LP64_ONLY(0xABCDABCDABCDABCDULL) NOT_LP64(0xABCDABCD);
|
||||
static const int pattern32 = 0xABCDABCD;
|
||||
|
||||
static intptr_t* const bad_addressN = (intptr_t*) VMError::segfault_address;
|
||||
static int* const bad_address32 = (int*) VMError::segfault_address;
|
||||
|
||||
static intptr_t dataN[3] = { 0, patternN, 0 };
|
||||
static int data32[3] = { 0, pattern32, 0 };
|
||||
static intptr_t* const good_addressN = dataN + 1;
|
||||
static int* const good_address32 = data32 + 1;
|
||||
|
||||
|
||||
void test_safefetchN_positive() {
|
||||
intptr_t a = SafeFetchN(good_addressN, 1);
|
||||
ASSERT_EQ(patternN, a);
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch_positive) {
|
||||
intptr_t v = pattern;
|
||||
intptr_t a = SafeFetchN(&v, 1);
|
||||
ASSERT_EQ(v, a);
|
||||
static void test_safefetch32_positive() {
|
||||
uint64_t a = SafeFetch32(good_address32, 1);
|
||||
ASSERT_EQ((uint64_t)pattern32, a);
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch_negative) {
|
||||
intptr_t a = SafeFetchN(invalid_address, pattern);
|
||||
ASSERT_EQ(pattern, a);
|
||||
a = SafeFetchN(invalid_address, ~pattern);
|
||||
ASSERT_EQ(~pattern, a);
|
||||
static void test_safefetchN_negative() {
|
||||
intptr_t a = SafeFetchN(bad_addressN, 0);
|
||||
ASSERT_EQ(0, a);
|
||||
a = SafeFetchN(bad_addressN, -1);
|
||||
ASSERT_EQ(-1, a);
|
||||
a = SafeFetchN(bad_addressN, ~patternN);
|
||||
ASSERT_EQ(~patternN, a);
|
||||
// Also test NULL, but not on AIX, where NULL is readable
|
||||
#ifndef AIX
|
||||
a = SafeFetchN(NULL, 0);
|
||||
ASSERT_EQ(0, a);
|
||||
a = SafeFetchN(NULL, ~patternN);
|
||||
ASSERT_EQ(~patternN, a);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_safefetch32_negative() {
|
||||
int a = SafeFetch32(bad_address32, 0);
|
||||
ASSERT_EQ(0, a);
|
||||
a = SafeFetch32(bad_address32, -1);
|
||||
ASSERT_EQ(-1, a);
|
||||
a = SafeFetch32(bad_address32, ~pattern32);
|
||||
ASSERT_EQ(~pattern32, a);
|
||||
// Also test NULL, but not on AIX, where NULL is readable
|
||||
#ifndef AIX
|
||||
a = SafeFetch32(NULL, 0);
|
||||
ASSERT_EQ(0, a);
|
||||
a = SafeFetch32(NULL, ~pattern32);
|
||||
ASSERT_EQ(~pattern32, a);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetchN_positive) {
|
||||
test_safefetchN_positive();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch32_positive) {
|
||||
test_safefetch32_positive();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetchN_negative) {
|
||||
test_safefetchN_negative();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch32_negative) {
|
||||
test_safefetch32_negative();
|
||||
}
|
||||
|
||||
// Try with Thread::current being NULL. SafeFetch should work then too.
|
||||
// See JDK-8282475
|
||||
|
||||
class ThreadCurrentNullMark : public StackObj {
|
||||
Thread* _saved;
|
||||
public:
|
||||
ThreadCurrentNullMark() {
|
||||
_saved = Thread::current();
|
||||
Thread::clear_thread_current();
|
||||
}
|
||||
~ThreadCurrentNullMark() {
|
||||
_saved->initialize_thread_current();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_VM(os, safefetchN_positive_current_null) {
|
||||
ThreadCurrentNullMark tcnmark;
|
||||
test_safefetchN_positive();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch32_positive_current_null) {
|
||||
ThreadCurrentNullMark tcnmark;
|
||||
test_safefetch32_positive();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetchN_negative_current_null) {
|
||||
ThreadCurrentNullMark tcnmark;
|
||||
test_safefetchN_negative();
|
||||
}
|
||||
|
||||
TEST_VM(os, safefetch32_negative_current_null) {
|
||||
ThreadCurrentNullMark tcnmark;
|
||||
test_safefetch32_negative();
|
||||
}
|
||||
|
||||
class VM_TestSafeFetchAtSafePoint : public VM_GTestExecuteAtSafepoint {
|
||||
@ -58,10 +145,7 @@ public:
|
||||
void doit() {
|
||||
// Regression test for JDK-8257828
|
||||
// Should not crash.
|
||||
intptr_t a = SafeFetchN(invalid_address, pattern);
|
||||
ASSERT_EQ(pattern, a);
|
||||
a = SafeFetchN(invalid_address, ~pattern);
|
||||
ASSERT_EQ(~pattern, a);
|
||||
test_safefetchN_negative();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user