matcha/tock: tar_loader changes for spiflash seL4 elfloader

- pad header to 512 bytes
- new api's for accessing name & header fields
- copy_File api for in-memory copy of a file's contents

Change-Id: I6da1d06607b3b0350403e5e9699d2d8f6c74399e
diff --git a/utils/src/tar_loader.rs b/utils/src/tar_loader.rs
index 176d9e8..10a3024 100644
--- a/utils/src/tar_loader.rs
+++ b/utils/src/tar_loader.rs
@@ -1,6 +1,7 @@
 // Trivial tar loader.
 
 use core::mem::transmute;
+use core::ptr;
 use matcha_hal::dprintf;
 
 const EFLASH_START: u32 = 0x44000000;
@@ -25,7 +26,7 @@
     devmajor: [u8; 8],   /* 329 */
     devminor: [u8; 8],   /* 337 */
     prefix: [u8; 155],   /* 345 */
-                         /* 500 */
+    reserved: [u8; 12],  /* 512 */
 }
 
 impl Default for TarHeader {
@@ -47,10 +48,25 @@
             devmajor: [0; 8],
             devminor: [0; 8],
             prefix: [0; 155],
+            reserved: [0; 12],
         };
     }
 }
 
+impl TarHeader {
+    pub fn from_bytes(b: &mut [u8]) -> TarHeader {
+        unsafe { ptr::read(b.as_ptr() as *const TarHeader) }
+    }
+
+    pub fn name(&self) -> &str {
+        core::str::from_utf8(&self.name).unwrap()
+    }
+
+    pub fn size(&self) -> u32 {
+        parse_octal(&self.size)
+    }
+}
+
 fn parse_octal(text: &[u8]) -> u32 {
     let mut n: u32 = 0;
     for x in text.iter() {
@@ -80,3 +96,13 @@
     dprintf!("Could not find tar entry for '{}'\n", name);
     return (0, 0);
 }
+
+// TODO(sleffler): rethink api, e.g. supply a range for bounds check
+pub unsafe fn copy_file(name: &str, offset: u32) -> bool {
+    let (cursor, size) = find_file(name);
+    if size == 0 {
+        return false;
+    }
+    ptr::copy_nonoverlapping::<u8>(transmute(cursor), transmute(offset), size as usize);
+    true
+}