This seems an easy question, but I can't confirm on my own: what happens if an outer struct are #[repr(C)]
, but at least one inner field in not? Is the outer struct not #[repr(C)]
?
I think the answer is no. The outer struct is not #[repr(C)]
as per
The intention is that if one has a set of C struct declarations and a corresponding set of Rust struct declarations, all of which are tagged with
#[repr(C)]
, then the layout of those structs will all be identical. Note that this setup implies that none of the structs in question can contain any#[repr(Rust)]
structs (or Rust tuples), as those would have no corresponding C struct declaration -- as#[repr(Rust)]
types have undefined layout, you cannot safely declare their layout in a C program.
/// Trap Context
#[repr(C)]
pub struct TrapContext {
/// general regs[0..31]
pub x: [usize; 32],
/// CSR sstatusβ
β
β
β
β
β
pub sstatus: Sstatus,
/// CSR sepc
pub sepc: usize,
}
where Sstatus is not tagged with repr(C)
, it's an implicit repr(Rust)
instead: sstatus.rs - source
Is it safe to read a block of memory (34*8 bytes) and treat it as *mut TrapContext
? (Not safe if the answer to the above question is no IMO)
// linker.ld
.section .text
.globl __alltraps
.globl __restore
.align 2
__alltraps:
csrrw sp, sscratch, sp
# now sp->kernel stack, sscratch->user stack
# allocate a TrapContext on kernel stack
addi sp, sp, -34*8
# save general-purpose registers
...
# set input argument of trap_handler(cx: &mut TrapContext)
mv a0, sp
call trap_handler
// Rust
#[no_mangle]
/// handle an interrupt, exception, or system call from user space
pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext { ... }