8245986: AArch64: Provide information when hitting a HaltNode

Reviewed-by: adinn
This commit is contained in:
Andrew Haley 2020-05-28 12:49:27 -04:00
parent 6f4f6a2a59
commit 339d52600b
6 changed files with 26 additions and 24 deletions

@ -15255,7 +15255,7 @@ instruct ShouldNotReachHere() %{
ins_encode %{
if (is_reachable()) {
__ dcps1(0xdead + 1);
__ stop(_halt_reason);
}
%}

@ -60,12 +60,10 @@
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
#define STOP(error) stop(error)
#else
#define BLOCK_COMMENT(str) block_comment(str)
#define STOP(error) block_comment(error); stop(error)
#endif
#define STOP(str) stop(str);
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
// Patch any kind of instruction; there may be several instructions.
@ -2223,22 +2221,9 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
}
void MacroAssembler::stop(const char* msg) {
address ip = pc();
pusha();
mov(c_rarg0, (address)msg);
mov(c_rarg1, (address)ip);
mov(c_rarg2, sp);
mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
blr(c_rarg3);
hlt(0);
}
void MacroAssembler::warn(const char* msg) {
pusha();
mov(c_rarg0, (address)msg);
mov(lr, CAST_FROM_FN_PTR(address, warning));
blr(lr);
popa();
BLOCK_COMMENT(msg);
dcps1(0xdeae);
emit_int64((uintptr_t)msg);
}
void MacroAssembler::unimplemented(const char* what) {

@ -980,9 +980,6 @@ public:
// prints msg, dumps registers and stops execution
void stop(const char* msg);
// prints msg and continues
void warn(const char* msg);
static void debug64(char* msg, int64_t pc, int64_t regs[]);
void untested() { stop("untested"); }

@ -462,6 +462,10 @@ void NativeIllegalInstruction::insert(address code_pos) {
*(juint*)code_pos = 0xd4bbd5a1; // dcps1 #0xdead
}
bool NativeInstruction::is_stop() {
return uint_at(0) == 0xd4bbd5c1; // dcps1 #0xdeae
}
//-------------------------------------------------------------------
// MT-safe inserting of a jump over a jump or a nop (used by

@ -76,6 +76,7 @@ class NativeInstruction {
bool is_movz();
bool is_movk();
bool is_sigill_zombie_not_entrant();
bool is_stop();
protected:
address addr_at(int offset) const { return address(this) + offset; }

@ -381,6 +381,21 @@ JVM_handle_linux_signal(int sig,
}
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
} else if (sig == SIGILL && nativeInstruction_at(pc)->is_stop()) {
// Pull a pointer to the error message out of the instruction
// stream.
const uint64_t *detail_msg_ptr
= (uint64_t*)(pc + NativeInstruction::instruction_size);
const char *detail_msg = (const char *)*detail_msg_ptr;
const char *msg = "stop";
if (TraceTraps) {
tty->print_cr("trap: %s: (SIGILL)", msg);
}
va_list detail_args;
VMError::report_and_die(INTERNAL_ERROR, msg, detail_msg, detail_args, thread,
pc, info, ucVoid, NULL, 0, 0);
va_end(detail_args);
}
else
@ -505,7 +520,7 @@ void os::print_context(outputStream *st, const void *context) {
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
print_instructions(st, pc, sizeof(char));
print_instructions(st, pc, 4/*native instruction size*/);
st->cr();
}