Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cranelift/codegen/src/binemit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub enum Reloc {
Aarch64TlsDescCall,

/// AArch64 GOT Page
/// Set the immediate value of an ADRP to bits 32:12 of X; check that –232 <= X < 232
/// Set the immediate value of an ADRP to bits 32:12 of X; check that –2^32 <= X < 2^32
/// This is equivalent to `R_AARCH64_ADR_GOT_PAGE` (311) in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#static-aarch64-relocations)
Aarch64AdrGotPage21,

Expand Down
29 changes: 29 additions & 0 deletions cranelift/jit/src/compiled_blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,35 @@ impl CompiledBlob {
let imm26 = (diff as u32) << chop >> chop;
unsafe { modify_inst32(iptr, |inst| inst | imm26) };
}
Reloc::Aarch64AdrGotPage21 => {
// Set the immediate value of an ADRP to bits [32:12] of X; check that –2^32 <= X < 2^32
assert_eq!(addend, 0, "addend affects the address looked up in get_got_entry, which is currently only called with a symbol");
let what = get_got_entry(name);
let what_page = (what as usize) & !0xfff;
let at_page = (at as usize) & !0xfff;
let pcrel = (what_page as isize).checked_sub(at_page as isize).unwrap();
assert!(
(-1 << 32) <= pcrel && pcrel < (1 << 32),
"can't reach GOT page with ±4GB `adrp` instruction"
);
let val = pcrel >> 12;

let immlo = ((val as u32) & 0b11) << 29;
let immhi = (((val as u32) >> 2) & &0x7ffff) << 5;
let mask = !((0x7ffff << 5) | (0b11 << 29));
unsafe { modify_inst32(at as *mut u32, |adrp| (adrp & mask) | immlo | immhi) };
}
Reloc::Aarch64Ld64GotLo12Nc => {
// Set the LD/ST immediate field to bits 11:3 of X. No overflow check; check that X&7 = 0
assert_eq!(addend, 0);
let base = get_got_entry(name);
let what = base as u32;
assert_eq!(what & 0b111, 0);
let val = what >> 3;
let imm9 = (val & 0x1ff) << 10;
let mask = !(0x1ff << 10);
unsafe { modify_inst32(at as *mut u32, |ldr| (ldr & mask) | imm9) };
}
Reloc::RiscvCallPlt => {
// A R_RISCV_CALL_PLT relocation expects auipc+jalr instruction pair.
// It is the equivalent of two relocations:
Expand Down