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 18, 2024
1 parent e9c9649 commit fd367b8
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 45 deletions.
38 changes: 15 additions & 23 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 @@ -3539,7 +3547,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 @@ -3596,19 +3604,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 @@ -3629,17 +3625,13 @@ 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");
"%ld - %ld == %ld : should be", (long)offset(), (long)stub_start_offset, (long)NativeCallTrampolineStub::data_offset);
assert(offset() % wordSize == 0, "bad alignment");
printf("Trampo data: %p\n", pc());
emit_int64((int64_t)dest);
emit_int32((int32_t)0xabababababu);
emit_int32((int32_t)0xdcdcdcdcdcu);
});

const address stub_start_addr = addr_at(stub_start_offset);
Expand All @@ -3652,7 +3644,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
30 changes: 9 additions & 21 deletions src/hotspot/cpu/riscv/nativeInst_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,10 @@ inline NativeCall* nativeCall_at(address addr);
class NativeCall: public NativeInstruction {
public:
enum RISCV_specific_constants {
instruction_size = 4,
instruction_size = NativeInstruction::instruction_size,
instruction_offset = 0,
displacement_offset = 0,
return_address_offset = 4
return_address_offset = NativeInstruction::instruction_size
};

address instruction_address() const { return addr_at(instruction_offset); }
Expand Down Expand Up @@ -524,8 +524,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 = 2 * wordSize,
data_offset = 0 * wordSize
};

address destination(nmethod *nm = nullptr) const;
Expand All @@ -534,25 +534,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 fd367b8

Please sign in to comment.