Skip to content

Commit

Permalink
Add i686 target; Fix dummy jump entry eliminated by linker
Browse files Browse the repository at this point in the history
Evian-Zhang committed Jul 24, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 1c3d9ab commit 5f1127d
Showing 5 changed files with 214 additions and 89 deletions.
20 changes: 15 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -10,11 +10,8 @@ env:
CARGO_TERM_COLOR: always

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
build-test-x86_64-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build all features
@@ -24,6 +21,19 @@ jobs:
- name: Run tests
run: cargo test --verbose

build-test-i686-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install i686 target toolchain
run: rustup target add i686-unknown-linux-gnu
- name: Build all features
run: cargo build --verbose --all-features --target i686-unknown-linux-gnu
- name: Build no_std
run: cargo build --verbose --no-default-features --target i686-unknown-linux-gnu
- name: Run tests
run: cargo test --verbose --target i686-unknown-linux-gnu

rustfmt:
name: Rustfmt
runs-on: ${{ matrix.os }}
11 changes: 11 additions & 0 deletions src/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Arch-specific implementations
#[cfg(target_arch = "x86_64")]
mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::*;

#[cfg(target_arch = "x86")]
mod x86;
#[cfg(target_arch = "x86")]
pub use x86::*;
81 changes: 81 additions & 0 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! x86 arch-sepcific implementations
use crate::{JumpEntry, JumpLabelType};

/// Length of jump instruction to be replaced
pub const ARCH_JUMP_INS_LENGTH: usize = 5;

/// New instruction generated according to jump label type and jump entry
#[inline(always)]
pub fn arch_jump_entry_instruction(
jump_label_type: JumpLabelType,
jump_entry: &JumpEntry,
) -> [u8; ARCH_JUMP_INS_LENGTH] {
match jump_label_type {
JumpLabelType::Jmp => {
let relative_addr =
(jump_entry.target_addr() - (jump_entry.code_addr() + ARCH_JUMP_INS_LENGTH)) as u32;
let [a, b, c, d] = relative_addr.to_ne_bytes();
[0xe9, a, b, c, d]
}
JumpLabelType::Nop => [0x3e, 0x8d, 0x74, 0x26, 0x00],
}
}

/// With given branch as likely branch, initialize the instruction here as a 5-byte NOP instruction
#[doc(hidden)]
#[macro_export]
macro_rules! arch_static_key_init_nop_with_given_branch_likely {
($key:path, $branch:expr) => {'my_label: {
::core::arch::asm!(
r#"
2:
.byte 0x3e,0x8d,0x74,0x26,0x00
.pushsection __static_keys, "awR"
.balign 4
.long 2b - .
.long {0} - .
.long {1} + {2} - .
.popsection
"#,
label {
break 'my_label !$branch;
},
sym $key,
const $branch as usize,
);

// This branch will be adjcent to the NOP/JMP instruction
break 'my_label $branch;
}};
}

// The `0x8d,0x76,0x00` is a 3-byte NOP, which is to make sure the `jmp {0}` is at least 5 bytes long.
/// With given branch as likely branch, initialize the instruction here as JMP instruction
#[doc(hidden)]
#[macro_export]
macro_rules! arch_static_key_init_jmp_with_given_branch_likely {
($key:path, $branch:expr) => {'my_label: {
::core::arch::asm!(
r#"
2:
jmp {0}
.byte 0x8d,0x76,0x00
.pushsection __static_keys, "awR"
.balign 4
.long 2b - .
.long {0} - .
.long {1} + {2} - .
.popsection
"#,
label {
break 'my_label !$branch;
},
sym $key,
const $branch as usize,
);

// This branch will be adjcent to the NOP/JMP instruction
break 'my_label $branch;
}};
}
81 changes: 81 additions & 0 deletions src/arch/x86_64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! x86_64 arch-sepcific implementations
use crate::{JumpEntry, JumpLabelType};

/// Length of jump instruction to be replaced
pub const ARCH_JUMP_INS_LENGTH: usize = 5;

/// New instruction generated according to jump label type and jump entry
#[inline(always)]
pub fn arch_jump_entry_instruction(
jump_label_type: JumpLabelType,
jump_entry: &JumpEntry,
) -> [u8; ARCH_JUMP_INS_LENGTH] {
match jump_label_type {
JumpLabelType::Jmp => {
let relative_addr =
(jump_entry.target_addr() - (jump_entry.code_addr() + ARCH_JUMP_INS_LENGTH)) as u32;
let [a, b, c, d] = relative_addr.to_ne_bytes();
[0xe9, a, b, c, d]
}
JumpLabelType::Nop => [0x0f, 0x1f, 0x44, 0x00, 0x00],
}
}

/// With given branch as likely branch, initialize the instruction here as a 5-byte NOP instruction
#[doc(hidden)]
#[macro_export]
macro_rules! arch_static_key_init_nop_with_given_branch_likely {
($key:path, $branch:expr) => {'my_label: {
::core::arch::asm!(
r#"
2:
.byte 0x0f,0x1f,0x44,0x00,0x00
.pushsection __static_keys, "awR"
.balign 8
.quad 2b - .
.quad {0} - .
.quad {1} + {2} - .
.popsection
"#,
label {
break 'my_label !$branch;
},
sym $key,
const $branch as usize,
);

// This branch will be adjcent to the NOP/JMP instruction
break 'my_label $branch;
}};
}

// The `0x0f,0x1f,0x00` is a 3-byte NOP, which is to make sure the `jmp {0}` is at least 5 bytes long.
/// With given branch as likely branch, initialize the instruction here as JMP instruction
#[doc(hidden)]
#[macro_export]
macro_rules! arch_static_key_init_jmp_with_given_branch_likely {
($key:path, $branch:expr) => {'my_label: {
::core::arch::asm!(
r#"
2:
jmp {0}
.byte 0x0f,0x1f,0x00
.pushsection __static_keys, "awR"
.balign 8
.quad 2b - .
.quad {0} - .
.quad {1} + {2} - .
.popsection
"#,
label {
break 'my_label !$branch;
},
sym $key,
const $branch as usize,
);

// This branch will be adjcent to the NOP/JMP instruction
break 'my_label $branch;
}};
}
Loading

0 comments on commit 5f1127d

Please sign in to comment.