Skip to content

Commit

Permalink
gate HandlerFunc behind target_arch = "x86{_64}"
Browse files Browse the repository at this point in the history
rustc is phasing out allowing the "x86-interrupt" ABI on non-x86
targets. Using "x86-interrupt" on a non-x86 target currently causes a
warning, but this will become a hard error in a future version.

Previously, if `abi_x86_interrupt` was enabled (it's enabled by default
), we used it in a pointer type for the declaration of the `HandlerFunc`-
family of types and used a private empty tuple if `abi_x86_interrupt`
wasn't enabled. This patch changes the cfg gate to only use the
"x86-interrupt" abi on x86 targets. This is technically a breaking
change, but I'd like to argue that we shouldn't treat it as such:
The danger with treating this as a breaking change is that we can't
release this fix as a patch update and so once rustc eventually treats
this as an error, we might not yet have released the next breaking
version leaving our users with not published fix.
My hope is that there is no one using `HandlerFunc` on a non-x86 target.
Even today, declaring a function (not just a function pointer) with the
"x86-interrupt" abi on a non-x86 target causes an error, so it's
unlikely that this will affect real code. It's technically possible to
create a `HandlerFunc` on a non-x86 target by using transmute, but,
again my hope is that no one is actually doing that. I'd also like to
point out that the only use of a `HandlerFunc` on a non-x86 target
would be to call set_handler_fn and any such calls could simply be
replaced by calls to set_handler_addr.
  • Loading branch information
Freax13 committed Oct 21, 2024
1 parent 323d46c commit 0b5476e
Showing 1 changed file with 44 additions and 11 deletions.
55 changes: 44 additions & 11 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,52 +712,82 @@ impl<T> PartialEq for Entry<T> {
/// A handler function for an interrupt or an exception without error code.
///
/// This type alias is only usable with the `abi_x86_interrupt` feature enabled.
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
pub type HandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame);
/// This type is not usable without the `abi_x86_interrupt` feature.
#[cfg(not(feature = "abi_x86_interrupt"))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
)))]
#[derive(Copy, Clone, Debug)]
pub struct HandlerFunc(());

/// A handler function for an exception that pushes an error code.
///
/// This type alias is only usable with the `abi_x86_interrupt` feature enabled.
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
pub type HandlerFuncWithErrCode = extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64);
/// This type is not usable without the `abi_x86_interrupt` feature.
#[cfg(not(feature = "abi_x86_interrupt"))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
)))]
#[derive(Copy, Clone, Debug)]
pub struct HandlerFuncWithErrCode(());

/// A page fault handler function that pushes a page fault error code.
///
/// This type alias is only usable with the `abi_x86_interrupt` feature enabled.
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
pub type PageFaultHandlerFunc =
extern "x86-interrupt" fn(InterruptStackFrame, error_code: PageFaultErrorCode);
/// This type is not usable without the `abi_x86_interrupt` feature.
#[cfg(not(feature = "abi_x86_interrupt"))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
)))]
#[derive(Copy, Clone, Debug)]
pub struct PageFaultHandlerFunc(());

/// A handler function that must not return, e.g. for a machine check exception.
///
/// This type alias is only usable with the `abi_x86_interrupt` feature enabled.
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
pub type DivergingHandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame) -> !;
/// This type is not usable without the `abi_x86_interrupt` feature.
#[cfg(not(feature = "abi_x86_interrupt"))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
)))]
#[derive(Copy, Clone, Debug)]
pub struct DivergingHandlerFunc(());

/// A handler function with an error code that must not return, e.g. for a double fault exception.
///
/// This type alias is only usable with the `abi_x86_interrupt` feature enabled.
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
pub type DivergingHandlerFuncWithErrCode =
extern "x86-interrupt" fn(InterruptStackFrame, error_code: u64) -> !;
/// This type is not usable without the `abi_x86_interrupt` feature.
#[cfg(not(feature = "abi_x86_interrupt"))]
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
)))]
#[derive(Copy, Clone, Debug)]
pub struct DivergingHandlerFuncWithErrCode(());

Expand Down Expand Up @@ -853,7 +883,10 @@ pub unsafe trait HandlerFuncType {

macro_rules! impl_handler_func_type {
($f:ty) => {
#[cfg(feature = "abi_x86_interrupt")]
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "abi_x86_interrupt"
))]
unsafe impl HandlerFuncType for $f {
#[inline]
fn to_virt_addr(self) -> VirtAddr {
Expand Down

0 comments on commit 0b5476e

Please sign in to comment.