Skip to content

Commit

Permalink
Use SegmentSelector in InterruptStackFrame (rust-osdev#263)
Browse files Browse the repository at this point in the history
This makes the value easier to use and slightly improves the `Debug`
implementation. Also, change the `InterruptStackFrame` to
`#[repr(transparent)]`. It doesn't really matter but makes it clear that
`InterruptStackFrame` and `InterruptStackFrameValue` are ABI compatible.

Note that this now makes `InterruptStackFrameValue`s imposible to
construct, but that seems fine.

Signed-off-by: Joe Richey <joerichey@google.com>
  • Loading branch information
josephlr committed Jul 18, 2021
1 parent 288f3f9 commit 0c1bd39
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,10 +849,8 @@ impl EntryOptions {
/// This wrapper type ensures that no accidental modification of the interrupt stack frame
/// occurs, which can cause undefined behavior (see the [`as_mut`](InterruptStackFrame::as_mut)
/// method for more information).
#[repr(C)]
pub struct InterruptStackFrame {
value: InterruptStackFrameValue,
}
#[repr(transparent)]
pub struct InterruptStackFrame(InterruptStackFrameValue);

impl InterruptStackFrame {
/// Gives mutable access to the contents of the interrupt stack frame.
Expand All @@ -871,7 +869,7 @@ impl InterruptStackFrame {
/// officially supported by LLVM's x86 interrupt calling convention.
#[inline]
pub unsafe fn as_mut(&mut self) -> Volatile<&mut InterruptStackFrameValue> {
Volatile::new(&mut self.value)
Volatile::new(&mut self.0)
}
}

Expand All @@ -880,14 +878,14 @@ impl Deref for InterruptStackFrame {

#[inline]
fn deref(&self) -> &Self::Target {
&self.value
&self.0
}
}

impl fmt::Debug for InterruptStackFrame {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
self.0.fmt(f)
}
}

Expand All @@ -901,14 +899,16 @@ pub struct InterruptStackFrameValue {
/// this value points to the faulting instruction, so that the instruction is restarted on
/// return. See the documentation of the [`InterruptDescriptorTable`] fields for more details.
pub instruction_pointer: VirtAddr,
/// The code segment selector, padded with zeros.
pub code_segment: u64,
/// The code segment selector at the time of the interrupt.
pub code_segment: SegmentSelector,
_reserved1: [u8; 6],
/// The flags register before the interrupt handler was invoked.
pub cpu_flags: u64,
/// The stack pointer at the time of the interrupt.
pub stack_pointer: VirtAddr,
/// The stack segment descriptor at the time of the interrupt (often zero in 64-bit mode).
pub stack_segment: u64,
pub stack_segment: SegmentSelector,
_reserved2: [u8; 6],
}

impl fmt::Debug for InterruptStackFrameValue {
Expand Down Expand Up @@ -1042,6 +1042,8 @@ mod test {
use core::mem::size_of;
assert_eq!(size_of::<Entry<HandlerFunc>>(), 16);
assert_eq!(size_of::<InterruptDescriptorTable>(), 256 * 16);
assert_eq!(size_of::<InterruptStackFrame>(), 40);
assert_eq!(size_of::<InterruptStackFrameValue>(), 40);
}

#[test]
Expand Down

0 comments on commit 0c1bd39

Please sign in to comment.