From 136a5e095d6ba4b26fb72695d4ebeb012331456a Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Tue, 12 Mar 2024 16:38:42 +0100 Subject: [PATCH] no-tramp-crash --- .../cpu/riscv/macroAssembler_riscv.cpp | 35 +++++++------------ .../cpu/riscv/macroAssembler_riscv.hpp | 1 + src/hotspot/cpu/riscv/nativeInst_riscv.cpp | 2 +- src/hotspot/cpu/riscv/nativeInst_riscv.hpp | 35 +++++++++---------- 4 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index d01a4ef2663b8..05b95e03fea53 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -849,6 +849,14 @@ void MacroAssembler::li(Register Rd, int64_t imm) { } } +void MacroAssembler::load_link(const address source, Register temp) { + assert(temp != noreg && temp != x0, "expecting a register"); + printf("Trampo ld: %p\n", pc()); + ld(temp, source); + printf("Trampo jalr: %p\n", pc()); + jalr(x1, temp, 0); +} + void MacroAssembler::jump_link(const address dest, Register temp) { assert_cond(dest != nullptr); int64_t distance = dest - pc(); @@ -3526,7 +3534,7 @@ address MacroAssembler::trampoline_call(Address entry) { } #endif relocate(entry.rspec(), [&] { - jump_link(target, t0); + load_link(target, t0); }); postcond(pc() != badAddress); @@ -3583,19 +3591,7 @@ int MacroAssembler::ic_check(int end_alignment) { return uep_offset; } -// Emit a trampoline stub for a call to a target which is too far away. -// -// code sequences: -// -// call-site: -// branch-and-link to or -// -// Related trampoline stub for this call site in the stub section: -// load the call target from the constant pool -// branch (RA still points to the call site above) - -address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset, - address dest) { +address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset, address dest) { // Max stub size: alignment nop, TrampolineStub. address stub = start_a_stub(max_trampoline_stub_size()); if (stub == nullptr) { @@ -3616,17 +3612,12 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset, insts_call_instruction_offset); const int stub_start_offset = offset(); relocate(rh, [&] { - // Now, create the trampoline stub's code: - // - load the call - // - call - Label target; - ld(t0, target); // auipc + ld - jr(t0); // jalr - bind(target); assert(offset() - stub_start_offset == NativeCallTrampolineStub::data_offset, "should be"); assert(offset() % wordSize == 0, "bad alignment"); + printf("Trampo data: %p\n", pc()); emit_int64((int64_t)dest); + emit_int32((int32_t)0xabababababu); }); const address stub_start_addr = addr_at(stub_start_offset); @@ -3639,7 +3630,7 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset, int MacroAssembler::max_trampoline_stub_size() { // Max stub size: alignment nop, TrampolineStub. - return NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size; + return 2 * wordSize; } int MacroAssembler::static_call_stub_size() { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 7c72ebadbfa52..fabcb35d95c29 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -590,6 +590,7 @@ class MacroAssembler: public Assembler { void bgtz(Register Rs, const address dest); private: + void load_link(const address source, Register temp); void jump_link(const address dest, Register temp); void jump_link(const Address &adr, Register temp); public: diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp index c4048f66e0d3e..4a46e9528d71e 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp @@ -121,7 +121,7 @@ bool NativeInstruction::is_li64_at(address instr) { } void NativeCall::verify() { - assert(NativeCall::is_call_at((address)this), "unexpected code at call site"); + assert(NativeCall::is_call_at((address)this), "unexpected code at call site: %p", (address)this); } address NativeCall::destination() const { diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.hpp b/src/hotspot/cpu/riscv/nativeInst_riscv.hpp index 48bbb2b3b181d..34dd4549d4f00 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.hpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.hpp @@ -212,6 +212,15 @@ class NativeInstruction { static bool is_load_pc_relative_at(address branch); static bool is_call_at(address instr) { + const int instr_size = NativeInstruction::instruction_size; + uint32_t top = Assembler::ld_instr(instr); + uint32_t low = Assembler::ld_instr(instr + instr_size); + uint32_t magic = Assembler::ld_instr(instr + (2 * instr_size)); + + printf("===>> %x %x %x <<==\n", top, low, magic); + if (magic == 0xababababu) { + return true; + } if (is_jal_at(instr) || is_jalr_at(instr)) { return true; } @@ -524,8 +533,8 @@ class NativeCallTrampolineStub : public NativeInstruction { enum RISCV_specific_constants { // Refer to function emit_trampoline_stub. - instruction_size = 3 * NativeInstruction::instruction_size + wordSize, // auipc + ld + jr + target address - data_offset = 3 * NativeInstruction::instruction_size, // auipc + ld + jr + instruction_size = 3 * NativeInstruction::instruction_size, // target address + data_offset = 0, }; address destination(nmethod *nm = nullptr) const; @@ -534,25 +543,13 @@ class NativeCallTrampolineStub : public NativeInstruction { }; inline bool is_NativeCallTrampolineStub_at(address addr) { - // Ensure that the stub is exactly - // ld t0, L--->auipc + ld - // jr t0 - // L: - - // judge inst + register + imm - // 1). check the instructions: auipc + ld + jalr - // 2). check if auipc[11:7] == t0 and ld[11:7] == t0 and ld[19:15] == t0 && jr[19:15] == t0 - // 3). check if the offset in ld[31:20] equals the data_offset assert_cond(addr != nullptr); const int instr_size = NativeInstruction::instruction_size; - if (NativeInstruction::is_auipc_at(addr) && - NativeInstruction::is_ld_at(addr + instr_size) && - NativeInstruction::is_jalr_at(addr + 2 * instr_size) && - (NativeInstruction::extract_rd(addr) == x5) && - (NativeInstruction::extract_rd(addr + instr_size) == x5) && - (NativeInstruction::extract_rs1(addr + instr_size) == x5) && - (NativeInstruction::extract_rs1(addr + 2 * instr_size) == x5) && - (Assembler::extract(Assembler::ld_instr(addr + 4), 31, 20) == NativeCallTrampolineStub::data_offset)) { + uint32_t top = Assembler::ld_instr(addr); + uint32_t low = Assembler::ld_instr(addr + instr_size); + uint32_t magic = Assembler::ld_instr(addr + (2 * instr_size)); + printf("===>> %x %x %x <<==\n", top, low, magic); + if (magic == 0xababababu) { return true; } return false;