diff --git a/src/runtime/src/kernel.rs b/src/runtime/src/kernel.rs index a156826..46c6197 100644 --- a/src/runtime/src/kernel.rs +++ b/src/runtime/src/kernel.rs @@ -81,6 +81,45 @@ extern fn rpc_send_async(service: u32, tag: &CSlice<u8>, data: *const *const ()) rpc_send_common(true, service, tag, data); } +unsafe fn attribute_writeback(typeinfo: *const ()) { + struct Attr { + offset: usize, + tag: CSlice<'static, u8>, + name: CSlice<'static, u8> + } + + struct Type { + attributes: *const *const Attr, + objects: *const *const () + } + + let mut tys = typeinfo as *const *const Type; + while !(*tys).is_null() { + let ty = *tys; + tys = tys.offset(1); + + let mut objects = (*ty).objects; + while !(*objects).is_null() { + let object = *objects; + objects = objects.offset(1); + + let mut attributes = (*ty).attributes; + while !(*attributes).is_null() { + let attribute = *attributes; + attributes = attributes.offset(1); + + if (*attribute).tag.len() > 0 { + rpc_send_async(0, &(*attribute).tag, [ + &object as *const _ as *const (), + &(*attribute).name as *const _ as *const (), + (object as usize + (*attribute).offset) as *const () + ].as_ptr()); + } + } + } + } +} + extern fn rpc_recv(slot: *mut ()) -> usize { let core1_rx: &mut sync_channel::Receiver<Message> = unsafe { mem::transmute(KERNEL_CHANNEL_0TO1) }; let core1_tx: &mut sync_channel::Sender<Message> = unsafe { mem::transmute(KERNEL_CHANNEL_1TO0) }; @@ -174,6 +213,7 @@ pub fn main_core1() { let mut core1_rx = core1_rx.unwrap(); let mut current_modinit: Option<u32> = None; + let mut current_typeinfo: Option<u32> = None; loop { let message = core1_rx.recv(); match *message { @@ -190,6 +230,7 @@ pub fn main_core1() { } let __modinit__ = library.lookup(b"__modinit__").unwrap(); current_modinit = Some(__modinit__); + current_typeinfo = library.lookup(b"typeinfo"); debug!("kernel loaded"); core1_tx.send(Message::LoadCompleted); }, @@ -206,6 +247,9 @@ pub fn main_core1() { KERNEL_CHANNEL_0TO1 = mem::transmute(&mut core1_rx); KERNEL_CHANNEL_1TO0 = mem::transmute(&mut core1_tx); (mem::transmute::<u32, fn()>(__modinit__))(); + if let Some(typeinfo) = current_typeinfo { + attribute_writeback(typeinfo as *const ()); + } KERNEL_CHANNEL_0TO1 = ptr::null_mut(); KERNEL_CHANNEL_1TO0 = ptr::null_mut(); }