Skip to content

Commit

Permalink
no-tramp-crash
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Mar 14, 2024
1 parent f4f585e commit 136a5e0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 42 deletions.
35 changes: 13 additions & 22 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 <destination> or <trampoline stub>
//
// 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) {
Expand All @@ -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);
Expand All @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/nativeInst_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
35 changes: 16 additions & 19 deletions src/hotspot/cpu/riscv/nativeInst_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 136a5e0

Please sign in to comment.