mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
actually understand this jmp address bug
This commit is contained in:
parent
99873f948d
commit
a8c8834a3c
3 changed files with 20 additions and 43 deletions
|
@ -1116,27 +1116,8 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
todo!("jump offsets over 27 bits for AArch64: {:#x}", offset);
|
||||
}
|
||||
|
||||
buf.len()
|
||||
}
|
||||
|
||||
/// Updates a jump instruction to a new offset and returns the number of bytes written.
|
||||
fn update_jmp_imm32_offset(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
jmp_location: u64,
|
||||
base_offset: u64,
|
||||
target_offset: u64,
|
||||
) {
|
||||
let old_buf_len = buf.len();
|
||||
|
||||
// write the jmp at the back of buf
|
||||
let jmp_offset = target_offset as i32 - base_offset as i32 + 4;
|
||||
Self::jmp_imm32(buf, jmp_offset);
|
||||
|
||||
// move the new jmp instruction into position
|
||||
buf.copy_within(old_buf_len.., jmp_location as usize);
|
||||
|
||||
// wipe the jmp we created at the end
|
||||
buf.truncate(old_buf_len)
|
||||
// on aarch64, jumps are calculated from the start of the jmp instruction
|
||||
buf.len() - 4
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -1172,7 +1153,8 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
todo!("jump offsets over 20 bits for AArch64: {:#x}", offset);
|
||||
}
|
||||
|
||||
buf.len()
|
||||
// on aarch64, jumps are calculated from the start of the jmp instruction
|
||||
buf.len() - 4
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -263,7 +263,19 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
jmp_location: u64,
|
||||
base_offset: u64,
|
||||
target_offset: u64,
|
||||
);
|
||||
) {
|
||||
let old_buf_len = buf.len();
|
||||
|
||||
// write the jmp at the back of buf
|
||||
let jmp_offset = target_offset as i32 - base_offset as i32;
|
||||
Self::jmp_imm32(buf, jmp_offset);
|
||||
|
||||
// move the new jmp instruction into position
|
||||
buf.copy_within(old_buf_len.., jmp_location as usize);
|
||||
|
||||
// wipe the jmp we created at the end
|
||||
buf.truncate(old_buf_len)
|
||||
}
|
||||
|
||||
fn tail_call(buf: &mut Vec<'_, u8>) -> u64;
|
||||
|
||||
|
|
|
@ -2111,29 +2111,11 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
#[inline(always)]
|
||||
fn jmp_imm32(buf: &mut Vec<'_, u8>, offset: i32) -> usize {
|
||||
jmp_imm32(buf, offset);
|
||||
|
||||
// on x86_64, jumps are calculated from the end of the jmp instruction
|
||||
buf.len()
|
||||
}
|
||||
|
||||
/// Updates a jump instruction to a new offset and returns the number of bytes written.
|
||||
fn update_jmp_imm32_offset(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
jmp_location: u64,
|
||||
base_offset: u64,
|
||||
target_offset: u64,
|
||||
) {
|
||||
let old_buf_len = buf.len();
|
||||
|
||||
// write the jmp at the back of buf
|
||||
let jmp_offset = target_offset as i32 - base_offset as i32;
|
||||
Self::jmp_imm32(buf, jmp_offset);
|
||||
|
||||
// move the new jmp instruction into position
|
||||
buf.copy_within(old_buf_len.., jmp_location as usize);
|
||||
|
||||
// wipe the jmp we created at the end
|
||||
buf.truncate(old_buf_len)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn tail_call(buf: &mut Vec<'_, u8>) -> u64 {
|
||||
Self::jmp_imm32(buf, 0);
|
||||
|
@ -2164,6 +2146,7 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
|
||||
jne_imm32(buf, offset);
|
||||
|
||||
// on x86_64, jumps are calculated from the end of the jmp instruction
|
||||
buf.len()
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue