summary refs log tree commit diff
path: root/kernel_loader
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2017-05-04 13:52:16 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-05-17 19:06:31 -0700
commit9195ec9b239f4fd70c64531e6c4fa00774c49c5f (patch)
treefb27becb53d5b8b65928f96bad1187114a71992b /kernel_loader
parent67030be903bb02e51c7690fa6beb8ce57f0b9fa3 (diff)
downloadcrosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar.gz
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar.bz2
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar.lz
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar.xz
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.tar.zst
crosvm-9195ec9b239f4fd70c64531e6c4fa00774c49c5f.zip
kernel_loader: Add loading of 64 bit elf x86 vmlinux
Change-Id: I2db4beb983e302216949e5de8b250932aa4810b8
Reviewed-on: https://chromium-review.googlesource.com/485019
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: Dylan Reid <dgreid@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'kernel_loader')
-rw-r--r--kernel_loader/Cargo.toml7
-rw-r--r--kernel_loader/src/elf.rs1403
-rw-r--r--kernel_loader/src/lib.rs207
-rw-r--r--kernel_loader/src/test_elf.binbin0 -> 994 bytes
4 files changed, 1617 insertions, 0 deletions
diff --git a/kernel_loader/Cargo.toml b/kernel_loader/Cargo.toml
new file mode 100644
index 0000000..52aeadb
--- /dev/null
+++ b/kernel_loader/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "kernel_loader"
+version = "0.1.0"
+
+[dependencies]
+libc = "*"
+sys_util = { path = "../sys_util" }
diff --git a/kernel_loader/src/elf.rs b/kernel_loader/src/elf.rs
new file mode 100644
index 0000000..e689b87
--- /dev/null
+++ b/kernel_loader/src/elf.rs
@@ -0,0 +1,1403 @@
+/*
+ * automatically generated by rust-bindgen
+ * From upstream linux include/uapi/linux/elf.h at commit:
+ * 806276b7f07a39a1cc3f38bb1ef5c573d4594a38
+ */
+
+#[repr(C)]
+pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
+impl<T> __BindgenUnionField<T> {
+    #[inline]
+    pub fn new() -> Self {
+        __BindgenUnionField(::std::marker::PhantomData)
+    }
+    #[inline]
+    pub unsafe fn as_ref(&self) -> &T {
+        ::std::mem::transmute(self)
+    }
+    #[inline]
+    pub unsafe fn as_mut(&mut self) -> &mut T {
+        ::std::mem::transmute(self)
+    }
+}
+impl<T> ::std::default::Default for __BindgenUnionField<T> {
+    #[inline]
+    fn default() -> Self {
+        Self::new()
+    }
+}
+impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        Self::new()
+    }
+}
+impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
+impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        fmt.write_str("__BindgenUnionField")
+    }
+}
+pub const __BITS_PER_LONG: ::std::os::raw::c_uint = 64;
+pub const __FD_SETSIZE: ::std::os::raw::c_uint = 1024;
+pub const EM_NONE: ::std::os::raw::c_uint = 0;
+pub const EM_M32: ::std::os::raw::c_uint = 1;
+pub const EM_SPARC: ::std::os::raw::c_uint = 2;
+pub const EM_386: ::std::os::raw::c_uint = 3;
+pub const EM_68K: ::std::os::raw::c_uint = 4;
+pub const EM_88K: ::std::os::raw::c_uint = 5;
+pub const EM_486: ::std::os::raw::c_uint = 6;
+pub const EM_860: ::std::os::raw::c_uint = 7;
+pub const EM_MIPS: ::std::os::raw::c_uint = 8;
+pub const EM_MIPS_RS3_LE: ::std::os::raw::c_uint = 10;
+pub const EM_MIPS_RS4_BE: ::std::os::raw::c_uint = 10;
+pub const EM_PARISC: ::std::os::raw::c_uint = 15;
+pub const EM_SPARC32PLUS: ::std::os::raw::c_uint = 18;
+pub const EM_PPC: ::std::os::raw::c_uint = 20;
+pub const EM_PPC64: ::std::os::raw::c_uint = 21;
+pub const EM_SPU: ::std::os::raw::c_uint = 23;
+pub const EM_ARM: ::std::os::raw::c_uint = 40;
+pub const EM_SH: ::std::os::raw::c_uint = 42;
+pub const EM_SPARCV9: ::std::os::raw::c_uint = 43;
+pub const EM_H8_300: ::std::os::raw::c_uint = 46;
+pub const EM_IA_64: ::std::os::raw::c_uint = 50;
+pub const EM_X86_64: ::std::os::raw::c_uint = 62;
+pub const EM_S390: ::std::os::raw::c_uint = 22;
+pub const EM_CRIS: ::std::os::raw::c_uint = 76;
+pub const EM_V850: ::std::os::raw::c_uint = 87;
+pub const EM_M32R: ::std::os::raw::c_uint = 88;
+pub const EM_MN10300: ::std::os::raw::c_uint = 89;
+pub const EM_OPENRISC: ::std::os::raw::c_uint = 92;
+pub const EM_BLACKFIN: ::std::os::raw::c_uint = 106;
+pub const EM_ALTERA_NIOS2: ::std::os::raw::c_uint = 113;
+pub const EM_TI_C6000: ::std::os::raw::c_uint = 140;
+pub const EM_AARCH64: ::std::os::raw::c_uint = 183;
+pub const EM_TILEPRO: ::std::os::raw::c_uint = 188;
+pub const EM_MICROBLAZE: ::std::os::raw::c_uint = 189;
+pub const EM_TILEGX: ::std::os::raw::c_uint = 191;
+pub const EM_FRV: ::std::os::raw::c_uint = 21569;
+pub const EM_AVR32: ::std::os::raw::c_uint = 6317;
+pub const EM_ALPHA: ::std::os::raw::c_uint = 36902;
+pub const EM_CYGNUS_V850: ::std::os::raw::c_uint = 36992;
+pub const EM_CYGNUS_M32R: ::std::os::raw::c_uint = 36929;
+pub const EM_S390_OLD: ::std::os::raw::c_uint = 41872;
+pub const EM_CYGNUS_MN10300: ::std::os::raw::c_uint = 48879;
+pub const PT_NULL: ::std::os::raw::c_uint = 0;
+pub const PT_LOAD: ::std::os::raw::c_uint = 1;
+pub const PT_DYNAMIC: ::std::os::raw::c_uint = 2;
+pub const PT_INTERP: ::std::os::raw::c_uint = 3;
+pub const PT_NOTE: ::std::os::raw::c_uint = 4;
+pub const PT_SHLIB: ::std::os::raw::c_uint = 5;
+pub const PT_PHDR: ::std::os::raw::c_uint = 6;
+pub const PT_TLS: ::std::os::raw::c_uint = 7;
+pub const PT_LOOS: ::std::os::raw::c_uint = 1610612736;
+pub const PT_HIOS: ::std::os::raw::c_uint = 1879048191;
+pub const PT_LOPROC: ::std::os::raw::c_uint = 1879048192;
+pub const PT_HIPROC: ::std::os::raw::c_uint = 2147483647;
+pub const PT_GNU_EH_FRAME: ::std::os::raw::c_uint = 1685382480;
+pub const PT_GNU_STACK: ::std::os::raw::c_uint = 1685382481;
+pub const PN_XNUM: ::std::os::raw::c_uint = 65535;
+pub const ET_NONE: ::std::os::raw::c_uint = 0;
+pub const ET_REL: ::std::os::raw::c_uint = 1;
+pub const ET_EXEC: ::std::os::raw::c_uint = 2;
+pub const ET_DYN: ::std::os::raw::c_uint = 3;
+pub const ET_CORE: ::std::os::raw::c_uint = 4;
+pub const ET_LOPROC: ::std::os::raw::c_uint = 65280;
+pub const ET_HIPROC: ::std::os::raw::c_uint = 65535;
+pub const DT_NULL: ::std::os::raw::c_uint = 0;
+pub const DT_NEEDED: ::std::os::raw::c_uint = 1;
+pub const DT_PLTRELSZ: ::std::os::raw::c_uint = 2;
+pub const DT_PLTGOT: ::std::os::raw::c_uint = 3;
+pub const DT_HASH: ::std::os::raw::c_uint = 4;
+pub const DT_STRTAB: ::std::os::raw::c_uint = 5;
+pub const DT_SYMTAB: ::std::os::raw::c_uint = 6;
+pub const DT_RELA: ::std::os::raw::c_uint = 7;
+pub const DT_RELASZ: ::std::os::raw::c_uint = 8;
+pub const DT_RELAENT: ::std::os::raw::c_uint = 9;
+pub const DT_STRSZ: ::std::os::raw::c_uint = 10;
+pub const DT_SYMENT: ::std::os::raw::c_uint = 11;
+pub const DT_INIT: ::std::os::raw::c_uint = 12;
+pub const DT_FINI: ::std::os::raw::c_uint = 13;
+pub const DT_SONAME: ::std::os::raw::c_uint = 14;
+pub const DT_RPATH: ::std::os::raw::c_uint = 15;
+pub const DT_SYMBOLIC: ::std::os::raw::c_uint = 16;
+pub const DT_REL: ::std::os::raw::c_uint = 17;
+pub const DT_RELSZ: ::std::os::raw::c_uint = 18;
+pub const DT_RELENT: ::std::os::raw::c_uint = 19;
+pub const DT_PLTREL: ::std::os::raw::c_uint = 20;
+pub const DT_DEBUG: ::std::os::raw::c_uint = 21;
+pub const DT_TEXTREL: ::std::os::raw::c_uint = 22;
+pub const DT_JMPREL: ::std::os::raw::c_uint = 23;
+pub const DT_ENCODING: ::std::os::raw::c_uint = 32;
+pub const OLD_DT_LOOS: ::std::os::raw::c_uint = 1610612736;
+pub const DT_LOOS: ::std::os::raw::c_uint = 1610612749;
+pub const DT_HIOS: ::std::os::raw::c_uint = 1879044096;
+pub const DT_VALRNGLO: ::std::os::raw::c_uint = 1879047424;
+pub const DT_VALRNGHI: ::std::os::raw::c_uint = 1879047679;
+pub const DT_ADDRRNGLO: ::std::os::raw::c_uint = 1879047680;
+pub const DT_ADDRRNGHI: ::std::os::raw::c_uint = 1879047935;
+pub const DT_VERSYM: ::std::os::raw::c_uint = 1879048176;
+pub const DT_RELACOUNT: ::std::os::raw::c_uint = 1879048185;
+pub const DT_RELCOUNT: ::std::os::raw::c_uint = 1879048186;
+pub const DT_FLAGS_1: ::std::os::raw::c_uint = 1879048187;
+pub const DT_VERDEF: ::std::os::raw::c_uint = 1879048188;
+pub const DT_VERDEFNUM: ::std::os::raw::c_uint = 1879048189;
+pub const DT_VERNEED: ::std::os::raw::c_uint = 1879048190;
+pub const DT_VERNEEDNUM: ::std::os::raw::c_uint = 1879048191;
+pub const OLD_DT_HIOS: ::std::os::raw::c_uint = 1879048191;
+pub const DT_LOPROC: ::std::os::raw::c_uint = 1879048192;
+pub const DT_HIPROC: ::std::os::raw::c_uint = 2147483647;
+pub const STB_LOCAL: ::std::os::raw::c_uint = 0;
+pub const STB_GLOBAL: ::std::os::raw::c_uint = 1;
+pub const STB_WEAK: ::std::os::raw::c_uint = 2;
+pub const STT_NOTYPE: ::std::os::raw::c_uint = 0;
+pub const STT_OBJECT: ::std::os::raw::c_uint = 1;
+pub const STT_FUNC: ::std::os::raw::c_uint = 2;
+pub const STT_SECTION: ::std::os::raw::c_uint = 3;
+pub const STT_FILE: ::std::os::raw::c_uint = 4;
+pub const STT_COMMON: ::std::os::raw::c_uint = 5;
+pub const STT_TLS: ::std::os::raw::c_uint = 6;
+pub const EI_NIDENT: ::std::os::raw::c_uint = 16;
+pub const PF_R: ::std::os::raw::c_uint = 4;
+pub const PF_W: ::std::os::raw::c_uint = 2;
+pub const PF_X: ::std::os::raw::c_uint = 1;
+pub const SHT_NULL: ::std::os::raw::c_uint = 0;
+pub const SHT_PROGBITS: ::std::os::raw::c_uint = 1;
+pub const SHT_SYMTAB: ::std::os::raw::c_uint = 2;
+pub const SHT_STRTAB: ::std::os::raw::c_uint = 3;
+pub const SHT_RELA: ::std::os::raw::c_uint = 4;
+pub const SHT_HASH: ::std::os::raw::c_uint = 5;
+pub const SHT_DYNAMIC: ::std::os::raw::c_uint = 6;
+pub const SHT_NOTE: ::std::os::raw::c_uint = 7;
+pub const SHT_NOBITS: ::std::os::raw::c_uint = 8;
+pub const SHT_REL: ::std::os::raw::c_uint = 9;
+pub const SHT_SHLIB: ::std::os::raw::c_uint = 10;
+pub const SHT_DYNSYM: ::std::os::raw::c_uint = 11;
+pub const SHT_NUM: ::std::os::raw::c_uint = 12;
+pub const SHT_LOPROC: ::std::os::raw::c_uint = 1879048192;
+pub const SHT_HIPROC: ::std::os::raw::c_uint = 2147483647;
+pub const SHT_LOUSER: ::std::os::raw::c_uint = 2147483648;
+pub const SHT_HIUSER: ::std::os::raw::c_uint = 4294967295;
+pub const SHF_WRITE: ::std::os::raw::c_uint = 1;
+pub const SHF_ALLOC: ::std::os::raw::c_uint = 2;
+pub const SHF_EXECINSTR: ::std::os::raw::c_uint = 4;
+pub const SHF_MASKPROC: ::std::os::raw::c_uint = 4026531840;
+pub const SHN_UNDEF: ::std::os::raw::c_uint = 0;
+pub const SHN_LORESERVE: ::std::os::raw::c_uint = 65280;
+pub const SHN_LOPROC: ::std::os::raw::c_uint = 65280;
+pub const SHN_HIPROC: ::std::os::raw::c_uint = 65311;
+pub const SHN_ABS: ::std::os::raw::c_uint = 65521;
+pub const SHN_COMMON: ::std::os::raw::c_uint = 65522;
+pub const SHN_HIRESERVE: ::std::os::raw::c_uint = 65535;
+pub const EI_MAG0: ::std::os::raw::c_uint = 0;
+pub const EI_MAG1: ::std::os::raw::c_uint = 1;
+pub const EI_MAG2: ::std::os::raw::c_uint = 2;
+pub const EI_MAG3: ::std::os::raw::c_uint = 3;
+pub const EI_CLASS: ::std::os::raw::c_uint = 4;
+pub const EI_DATA: ::std::os::raw::c_uint = 5;
+pub const EI_VERSION: ::std::os::raw::c_uint = 6;
+pub const EI_OSABI: ::std::os::raw::c_uint = 7;
+pub const EI_PAD: ::std::os::raw::c_uint = 8;
+pub const ELFMAG0: ::std::os::raw::c_uint = 127;
+pub const ELFMAG1: u8 = b'E';
+pub const ELFMAG2: u8 = b'L';
+pub const ELFMAG3: u8 = b'F';
+pub const ELFMAG: &'static [u8; 5usize] = b"\x7fELF\x00";
+pub const SELFMAG: ::std::os::raw::c_uint = 4;
+pub const ELFCLASSNONE: ::std::os::raw::c_uint = 0;
+pub const ELFCLASS32: ::std::os::raw::c_uint = 1;
+pub const ELFCLASS64: ::std::os::raw::c_uint = 2;
+pub const ELFCLASSNUM: ::std::os::raw::c_uint = 3;
+pub const ELFDATANONE: ::std::os::raw::c_uint = 0;
+pub const ELFDATA2LSB: ::std::os::raw::c_uint = 1;
+pub const ELFDATA2MSB: ::std::os::raw::c_uint = 2;
+pub const EV_NONE: ::std::os::raw::c_uint = 0;
+pub const EV_CURRENT: ::std::os::raw::c_uint = 1;
+pub const EV_NUM: ::std::os::raw::c_uint = 2;
+pub const ELFOSABI_NONE: ::std::os::raw::c_uint = 0;
+pub const ELFOSABI_LINUX: ::std::os::raw::c_uint = 3;
+pub const ELF_OSABI: ::std::os::raw::c_uint = 0;
+pub const NT_PRSTATUS: ::std::os::raw::c_uint = 1;
+pub const NT_PRFPREG: ::std::os::raw::c_uint = 2;
+pub const NT_PRPSINFO: ::std::os::raw::c_uint = 3;
+pub const NT_TASKSTRUCT: ::std::os::raw::c_uint = 4;
+pub const NT_AUXV: ::std::os::raw::c_uint = 6;
+pub const NT_SIGINFO: ::std::os::raw::c_uint = 1397311305;
+pub const NT_FILE: ::std::os::raw::c_uint = 1179208773;
+pub const NT_PRXFPREG: ::std::os::raw::c_uint = 1189489535;
+pub const NT_PPC_VMX: ::std::os::raw::c_uint = 256;
+pub const NT_PPC_SPE: ::std::os::raw::c_uint = 257;
+pub const NT_PPC_VSX: ::std::os::raw::c_uint = 258;
+pub const NT_386_TLS: ::std::os::raw::c_uint = 512;
+pub const NT_386_IOPERM: ::std::os::raw::c_uint = 513;
+pub const NT_X86_XSTATE: ::std::os::raw::c_uint = 514;
+pub const NT_S390_HIGH_GPRS: ::std::os::raw::c_uint = 768;
+pub const NT_S390_TIMER: ::std::os::raw::c_uint = 769;
+pub const NT_S390_TODCMP: ::std::os::raw::c_uint = 770;
+pub const NT_S390_TODPREG: ::std::os::raw::c_uint = 771;
+pub const NT_S390_CTRS: ::std::os::raw::c_uint = 772;
+pub const NT_S390_PREFIX: ::std::os::raw::c_uint = 773;
+pub const NT_S390_LAST_BREAK: ::std::os::raw::c_uint = 774;
+pub const NT_S390_SYSTEM_CALL: ::std::os::raw::c_uint = 775;
+pub const NT_S390_TDB: ::std::os::raw::c_uint = 776;
+pub const NT_S390_VXRS_LOW: ::std::os::raw::c_uint = 777;
+pub const NT_S390_VXRS_HIGH: ::std::os::raw::c_uint = 778;
+pub const NT_ARM_VFP: ::std::os::raw::c_uint = 1024;
+pub const NT_ARM_TLS: ::std::os::raw::c_uint = 1025;
+pub const NT_ARM_HW_BREAK: ::std::os::raw::c_uint = 1026;
+pub const NT_ARM_HW_WATCH: ::std::os::raw::c_uint = 1027;
+pub const NT_ARM_SYSTEM_CALL: ::std::os::raw::c_uint = 1028;
+pub const NT_METAG_CBUF: ::std::os::raw::c_uint = 1280;
+pub const NT_METAG_RPIPE: ::std::os::raw::c_uint = 1281;
+pub const NT_METAG_TLS: ::std::os::raw::c_uint = 1282;
+pub type __s8 = ::std::os::raw::c_schar;
+pub type __u8 = ::std::os::raw::c_uchar;
+pub type __s16 = ::std::os::raw::c_short;
+pub type __u16 = ::std::os::raw::c_ushort;
+pub type __s32 = ::std::os::raw::c_int;
+pub type __u32 = ::std::os::raw::c_uint;
+pub type __s64 = ::std::os::raw::c_longlong;
+pub type __u64 = ::std::os::raw::c_ulonglong;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct __kernel_fd_set {
+    pub fds_bits: [::std::os::raw::c_ulong; 16usize],
+}
+#[test]
+fn bindgen_test_layout___kernel_fd_set() {
+    assert_eq!(::std::mem::size_of::<__kernel_fd_set>(),
+               128usize,
+               concat!("Size of: ", stringify!(__kernel_fd_set)));
+    assert_eq!(::std::mem::align_of::<__kernel_fd_set>(),
+               8usize,
+               concat!("Alignment of ", stringify!(__kernel_fd_set)));
+    assert_eq!(unsafe { &(*(0 as *const __kernel_fd_set)).fds_bits as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(__kernel_fd_set),
+                       "::",
+                       stringify!(fds_bits)));
+}
+impl Clone for __kernel_fd_set {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type __kernel_sighandler_t =
+    ::std::option::Option<unsafe extern "C" fn(arg1: ::std::os::raw::c_int)>;
+pub type __kernel_key_t = ::std::os::raw::c_int;
+pub type __kernel_mqd_t = ::std::os::raw::c_int;
+pub type __kernel_old_uid_t = ::std::os::raw::c_ushort;
+pub type __kernel_old_gid_t = ::std::os::raw::c_ushort;
+pub type __kernel_old_dev_t = ::std::os::raw::c_ulong;
+pub type __kernel_long_t = ::std::os::raw::c_long;
+pub type __kernel_ulong_t = ::std::os::raw::c_ulong;
+pub type __kernel_ino_t = __kernel_ulong_t;
+pub type __kernel_mode_t = ::std::os::raw::c_uint;
+pub type __kernel_pid_t = ::std::os::raw::c_int;
+pub type __kernel_ipc_pid_t = ::std::os::raw::c_int;
+pub type __kernel_uid_t = ::std::os::raw::c_uint;
+pub type __kernel_gid_t = ::std::os::raw::c_uint;
+pub type __kernel_suseconds_t = __kernel_long_t;
+pub type __kernel_daddr_t = ::std::os::raw::c_int;
+pub type __kernel_uid32_t = ::std::os::raw::c_uint;
+pub type __kernel_gid32_t = ::std::os::raw::c_uint;
+pub type __kernel_size_t = __kernel_ulong_t;
+pub type __kernel_ssize_t = __kernel_long_t;
+pub type __kernel_ptrdiff_t = __kernel_long_t;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct __kernel_fsid_t {
+    pub val: [::std::os::raw::c_int; 2usize],
+}
+#[test]
+fn bindgen_test_layout___kernel_fsid_t() {
+    assert_eq!(::std::mem::size_of::<__kernel_fsid_t>(),
+               8usize,
+               concat!("Size of: ", stringify!(__kernel_fsid_t)));
+    assert_eq!(::std::mem::align_of::<__kernel_fsid_t>(),
+               4usize,
+               concat!("Alignment of ", stringify!(__kernel_fsid_t)));
+    assert_eq!(unsafe { &(*(0 as *const __kernel_fsid_t)).val as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(__kernel_fsid_t),
+                       "::",
+                       stringify!(val)));
+}
+impl Clone for __kernel_fsid_t {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type __kernel_off_t = __kernel_long_t;
+pub type __kernel_loff_t = ::std::os::raw::c_longlong;
+pub type __kernel_time_t = __kernel_long_t;
+pub type __kernel_clock_t = __kernel_long_t;
+pub type __kernel_timer_t = ::std::os::raw::c_int;
+pub type __kernel_clockid_t = ::std::os::raw::c_int;
+pub type __kernel_caddr_t = *mut ::std::os::raw::c_char;
+pub type __kernel_uid16_t = ::std::os::raw::c_ushort;
+pub type __kernel_gid16_t = ::std::os::raw::c_ushort;
+pub type __le16 = __u16;
+pub type __be16 = __u16;
+pub type __le32 = __u32;
+pub type __be32 = __u32;
+pub type __le64 = __u64;
+pub type __be64 = __u64;
+pub type __sum16 = __u16;
+pub type __wsum = __u32;
+pub type Elf32_Addr = __u32;
+pub type Elf32_Half = __u16;
+pub type Elf32_Off = __u32;
+pub type Elf32_Sword = __s32;
+pub type Elf32_Word = __u32;
+pub type Elf64_Addr = __u64;
+pub type Elf64_Half = __u16;
+pub type Elf64_SHalf = __s16;
+pub type Elf64_Off = __u64;
+pub type Elf64_Sword = __s32;
+pub type Elf64_Word = __u32;
+pub type Elf64_Xword = __u64;
+pub type Elf64_Sxword = __s64;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct dynamic {
+    pub d_tag: Elf32_Sword,
+    pub d_un: dynamic__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct dynamic__bindgen_ty_1 {
+    pub d_val: __BindgenUnionField<Elf32_Sword>,
+    pub d_ptr: __BindgenUnionField<Elf32_Addr>,
+    pub bindgen_union_field: u32,
+}
+#[test]
+fn bindgen_test_layout_dynamic__bindgen_ty_1() {
+    assert_eq!(::std::mem::size_of::<dynamic__bindgen_ty_1>(),
+               4usize,
+               concat!("Size of: ", stringify!(dynamic__bindgen_ty_1)));
+    assert_eq!(::std::mem::align_of::<dynamic__bindgen_ty_1>(),
+               4usize,
+               concat!("Alignment of ", stringify!(dynamic__bindgen_ty_1)));
+    assert_eq!(unsafe { &(*(0 as *const dynamic__bindgen_ty_1)).d_val as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(dynamic__bindgen_ty_1),
+                       "::",
+                       stringify!(d_val)));
+    assert_eq!(unsafe { &(*(0 as *const dynamic__bindgen_ty_1)).d_ptr as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(dynamic__bindgen_ty_1),
+                       "::",
+                       stringify!(d_ptr)));
+}
+impl Clone for dynamic__bindgen_ty_1 {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+#[test]
+fn bindgen_test_layout_dynamic() {
+    assert_eq!(::std::mem::size_of::<dynamic>(),
+               8usize,
+               concat!("Size of: ", stringify!(dynamic)));
+    assert_eq!(::std::mem::align_of::<dynamic>(),
+               4usize,
+               concat!("Alignment of ", stringify!(dynamic)));
+    assert_eq!(unsafe { &(*(0 as *const dynamic)).d_tag as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(dynamic),
+                       "::",
+                       stringify!(d_tag)));
+    assert_eq!(unsafe { &(*(0 as *const dynamic)).d_un as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(dynamic),
+                       "::",
+                       stringify!(d_un)));
+}
+impl Clone for dynamic {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Dyn = dynamic;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct Elf64_Dyn {
+    pub d_tag: Elf64_Sxword,
+    pub d_un: Elf64_Dyn__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct Elf64_Dyn__bindgen_ty_1 {
+    pub d_val: __BindgenUnionField<Elf64_Xword>,
+    pub d_ptr: __BindgenUnionField<Elf64_Addr>,
+    pub bindgen_union_field: u64,
+}
+#[test]
+fn bindgen_test_layout_Elf64_Dyn__bindgen_ty_1() {
+    assert_eq!(::std::mem::size_of::<Elf64_Dyn__bindgen_ty_1>(),
+               8usize,
+               concat!("Size of: ", stringify!(Elf64_Dyn__bindgen_ty_1)));
+    assert_eq!(::std::mem::align_of::<Elf64_Dyn__bindgen_ty_1>(),
+               8usize,
+               concat!("Alignment of ", stringify!(Elf64_Dyn__bindgen_ty_1)));
+    assert_eq!(unsafe { &(*(0 as *const Elf64_Dyn__bindgen_ty_1)).d_val as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(Elf64_Dyn__bindgen_ty_1),
+                       "::",
+                       stringify!(d_val)));
+    assert_eq!(unsafe { &(*(0 as *const Elf64_Dyn__bindgen_ty_1)).d_ptr as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(Elf64_Dyn__bindgen_ty_1),
+                       "::",
+                       stringify!(d_ptr)));
+}
+impl Clone for Elf64_Dyn__bindgen_ty_1 {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+#[test]
+fn bindgen_test_layout_Elf64_Dyn() {
+    assert_eq!(::std::mem::size_of::<Elf64_Dyn>(),
+               16usize,
+               concat!("Size of: ", stringify!(Elf64_Dyn)));
+    assert_eq!(::std::mem::align_of::<Elf64_Dyn>(),
+               8usize,
+               concat!("Alignment of ", stringify!(Elf64_Dyn)));
+    assert_eq!(unsafe { &(*(0 as *const Elf64_Dyn)).d_tag as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(Elf64_Dyn),
+                       "::",
+                       stringify!(d_tag)));
+    assert_eq!(unsafe { &(*(0 as *const Elf64_Dyn)).d_un as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(Elf64_Dyn),
+                       "::",
+                       stringify!(d_un)));
+}
+impl Clone for Elf64_Dyn {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_rel {
+    pub r_offset: Elf32_Addr,
+    pub r_info: Elf32_Word,
+}
+#[test]
+fn bindgen_test_layout_elf32_rel() {
+    assert_eq!(::std::mem::size_of::<elf32_rel>(),
+               8usize,
+               concat!("Size of: ", stringify!(elf32_rel)));
+    assert_eq!(::std::mem::align_of::<elf32_rel>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_rel)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_rel)).r_offset as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_rel),
+                       "::",
+                       stringify!(r_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_rel)).r_info as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_rel),
+                       "::",
+                       stringify!(r_info)));
+}
+impl Clone for elf32_rel {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Rel = elf32_rel;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_rel {
+    pub r_offset: Elf64_Addr,
+    pub r_info: Elf64_Xword,
+}
+#[test]
+fn bindgen_test_layout_elf64_rel() {
+    assert_eq!(::std::mem::size_of::<elf64_rel>(),
+               16usize,
+               concat!("Size of: ", stringify!(elf64_rel)));
+    assert_eq!(::std::mem::align_of::<elf64_rel>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_rel)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_rel)).r_offset as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_rel),
+                       "::",
+                       stringify!(r_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_rel)).r_info as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_rel),
+                       "::",
+                       stringify!(r_info)));
+}
+impl Clone for elf64_rel {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Rel = elf64_rel;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_rela {
+    pub r_offset: Elf32_Addr,
+    pub r_info: Elf32_Word,
+    pub r_addend: Elf32_Sword,
+}
+#[test]
+fn bindgen_test_layout_elf32_rela() {
+    assert_eq!(::std::mem::size_of::<elf32_rela>(),
+               12usize,
+               concat!("Size of: ", stringify!(elf32_rela)));
+    assert_eq!(::std::mem::align_of::<elf32_rela>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_rela)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_rela)).r_offset as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_rela),
+                       "::",
+                       stringify!(r_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_rela)).r_info as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_rela),
+                       "::",
+                       stringify!(r_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_rela)).r_addend as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_rela),
+                       "::",
+                       stringify!(r_addend)));
+}
+impl Clone for elf32_rela {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Rela = elf32_rela;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_rela {
+    pub r_offset: Elf64_Addr,
+    pub r_info: Elf64_Xword,
+    pub r_addend: Elf64_Sxword,
+}
+#[test]
+fn bindgen_test_layout_elf64_rela() {
+    assert_eq!(::std::mem::size_of::<elf64_rela>(),
+               24usize,
+               concat!("Size of: ", stringify!(elf64_rela)));
+    assert_eq!(::std::mem::align_of::<elf64_rela>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_rela)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_rela)).r_offset as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_rela),
+                       "::",
+                       stringify!(r_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_rela)).r_info as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_rela),
+                       "::",
+                       stringify!(r_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_rela)).r_addend as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_rela),
+                       "::",
+                       stringify!(r_addend)));
+}
+impl Clone for elf64_rela {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Rela = elf64_rela;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_sym {
+    pub st_name: Elf32_Word,
+    pub st_value: Elf32_Addr,
+    pub st_size: Elf32_Word,
+    pub st_info: ::std::os::raw::c_uchar,
+    pub st_other: ::std::os::raw::c_uchar,
+    pub st_shndx: Elf32_Half,
+}
+#[test]
+fn bindgen_test_layout_elf32_sym() {
+    assert_eq!(::std::mem::size_of::<elf32_sym>(),
+               16usize,
+               concat!("Size of: ", stringify!(elf32_sym)));
+    assert_eq!(::std::mem::align_of::<elf32_sym>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_sym)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_name as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_name)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_value as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_value)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_size as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_size)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_info as *const _ as usize },
+               12usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_other as *const _ as usize },
+               13usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_other)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_sym)).st_shndx as *const _ as usize },
+               14usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_sym),
+                       "::",
+                       stringify!(st_shndx)));
+}
+impl Clone for elf32_sym {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Sym = elf32_sym;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_sym {
+    pub st_name: Elf64_Word,
+    pub st_info: ::std::os::raw::c_uchar,
+    pub st_other: ::std::os::raw::c_uchar,
+    pub st_shndx: Elf64_Half,
+    pub st_value: Elf64_Addr,
+    pub st_size: Elf64_Xword,
+}
+#[test]
+fn bindgen_test_layout_elf64_sym() {
+    assert_eq!(::std::mem::size_of::<elf64_sym>(),
+               24usize,
+               concat!("Size of: ", stringify!(elf64_sym)));
+    assert_eq!(::std::mem::align_of::<elf64_sym>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_sym)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_name as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_name)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_info as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_other as *const _ as usize },
+               5usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_other)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_shndx as *const _ as usize },
+               6usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_shndx)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_value as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_value)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_sym)).st_size as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_sym),
+                       "::",
+                       stringify!(st_size)));
+}
+impl Clone for elf64_sym {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Sym = elf64_sym;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_hdr {
+    pub e_ident: [::std::os::raw::c_uchar; 16usize],
+    pub e_type: Elf32_Half,
+    pub e_machine: Elf32_Half,
+    pub e_version: Elf32_Word,
+    pub e_entry: Elf32_Addr,
+    pub e_phoff: Elf32_Off,
+    pub e_shoff: Elf32_Off,
+    pub e_flags: Elf32_Word,
+    pub e_ehsize: Elf32_Half,
+    pub e_phentsize: Elf32_Half,
+    pub e_phnum: Elf32_Half,
+    pub e_shentsize: Elf32_Half,
+    pub e_shnum: Elf32_Half,
+    pub e_shstrndx: Elf32_Half,
+}
+#[test]
+fn bindgen_test_layout_elf32_hdr() {
+    assert_eq!(::std::mem::size_of::<elf32_hdr>(),
+               52usize,
+               concat!("Size of: ", stringify!(elf32_hdr)));
+    assert_eq!(::std::mem::align_of::<elf32_hdr>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_hdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_ident as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_ident)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_type as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_machine as *const _ as usize },
+               18usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_machine)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_version as *const _ as usize },
+               20usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_version)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_entry as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_entry)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_phoff as *const _ as usize },
+               28usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_phoff)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_shoff as *const _ as usize },
+               32usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_shoff)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_flags as *const _ as usize },
+               36usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_ehsize as *const _ as usize },
+               40usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_ehsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_phentsize as *const _ as usize },
+               42usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_phentsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_phnum as *const _ as usize },
+               44usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_phnum)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_shentsize as *const _ as usize },
+               46usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_shentsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_shnum as *const _ as usize },
+               48usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_shnum)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_hdr)).e_shstrndx as *const _ as usize },
+               50usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_hdr),
+                       "::",
+                       stringify!(e_shstrndx)));
+}
+impl Clone for elf32_hdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Ehdr = elf32_hdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_hdr {
+    pub e_ident: [::std::os::raw::c_uchar; 16usize],
+    pub e_type: Elf64_Half,
+    pub e_machine: Elf64_Half,
+    pub e_version: Elf64_Word,
+    pub e_entry: Elf64_Addr,
+    pub e_phoff: Elf64_Off,
+    pub e_shoff: Elf64_Off,
+    pub e_flags: Elf64_Word,
+    pub e_ehsize: Elf64_Half,
+    pub e_phentsize: Elf64_Half,
+    pub e_phnum: Elf64_Half,
+    pub e_shentsize: Elf64_Half,
+    pub e_shnum: Elf64_Half,
+    pub e_shstrndx: Elf64_Half,
+}
+#[test]
+fn bindgen_test_layout_elf64_hdr() {
+    assert_eq!(::std::mem::size_of::<elf64_hdr>(),
+               64usize,
+               concat!("Size of: ", stringify!(elf64_hdr)));
+    assert_eq!(::std::mem::align_of::<elf64_hdr>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_hdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_ident as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_ident)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_type as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_machine as *const _ as usize },
+               18usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_machine)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_version as *const _ as usize },
+               20usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_version)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_entry as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_entry)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_phoff as *const _ as usize },
+               32usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_phoff)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_shoff as *const _ as usize },
+               40usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_shoff)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_flags as *const _ as usize },
+               48usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_ehsize as *const _ as usize },
+               52usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_ehsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_phentsize as *const _ as usize },
+               54usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_phentsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_phnum as *const _ as usize },
+               56usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_phnum)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_shentsize as *const _ as usize },
+               58usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_shentsize)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_shnum as *const _ as usize },
+               60usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_shnum)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_hdr)).e_shstrndx as *const _ as usize },
+               62usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_hdr),
+                       "::",
+                       stringify!(e_shstrndx)));
+}
+impl Clone for elf64_hdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Ehdr = elf64_hdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_phdr {
+    pub p_type: Elf32_Word,
+    pub p_offset: Elf32_Off,
+    pub p_vaddr: Elf32_Addr,
+    pub p_paddr: Elf32_Addr,
+    pub p_filesz: Elf32_Word,
+    pub p_memsz: Elf32_Word,
+    pub p_flags: Elf32_Word,
+    pub p_align: Elf32_Word,
+}
+#[test]
+fn bindgen_test_layout_elf32_phdr() {
+    assert_eq!(::std::mem::size_of::<elf32_phdr>(),
+               32usize,
+               concat!("Size of: ", stringify!(elf32_phdr)));
+    assert_eq!(::std::mem::align_of::<elf32_phdr>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_phdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_type as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_offset as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_vaddr as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_vaddr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_paddr as *const _ as usize },
+               12usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_paddr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_filesz as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_filesz)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_memsz as *const _ as usize },
+               20usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_memsz)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_flags as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_phdr)).p_align as *const _ as usize },
+               28usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_phdr),
+                       "::",
+                       stringify!(p_align)));
+}
+impl Clone for elf32_phdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Phdr = elf32_phdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_phdr {
+    pub p_type: Elf64_Word,
+    pub p_flags: Elf64_Word,
+    pub p_offset: Elf64_Off,
+    pub p_vaddr: Elf64_Addr,
+    pub p_paddr: Elf64_Addr,
+    pub p_filesz: Elf64_Xword,
+    pub p_memsz: Elf64_Xword,
+    pub p_align: Elf64_Xword,
+}
+#[test]
+fn bindgen_test_layout_elf64_phdr() {
+    assert_eq!(::std::mem::size_of::<elf64_phdr>(),
+               56usize,
+               concat!("Size of: ", stringify!(elf64_phdr)));
+    assert_eq!(::std::mem::align_of::<elf64_phdr>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_phdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_type as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_flags as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_offset as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_vaddr as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_vaddr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_paddr as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_paddr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_filesz as *const _ as usize },
+               32usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_filesz)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_memsz as *const _ as usize },
+               40usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_memsz)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_phdr)).p_align as *const _ as usize },
+               48usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_phdr),
+                       "::",
+                       stringify!(p_align)));
+}
+impl Clone for elf64_phdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Phdr = elf64_phdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_shdr {
+    pub sh_name: Elf32_Word,
+    pub sh_type: Elf32_Word,
+    pub sh_flags: Elf32_Word,
+    pub sh_addr: Elf32_Addr,
+    pub sh_offset: Elf32_Off,
+    pub sh_size: Elf32_Word,
+    pub sh_link: Elf32_Word,
+    pub sh_info: Elf32_Word,
+    pub sh_addralign: Elf32_Word,
+    pub sh_entsize: Elf32_Word,
+}
+#[test]
+fn bindgen_test_layout_elf32_shdr() {
+    assert_eq!(::std::mem::size_of::<elf32_shdr>(),
+               40usize,
+               concat!("Size of: ", stringify!(elf32_shdr)));
+    assert_eq!(::std::mem::align_of::<elf32_shdr>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_shdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_name as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_name)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_type as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_flags as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_addr as *const _ as usize },
+               12usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_addr)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_offset as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_size as *const _ as usize },
+               20usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_size)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_link as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_link)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_info as *const _ as usize },
+               28usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_addralign as *const _ as usize },
+               32usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_addralign)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_shdr)).sh_entsize as *const _ as usize },
+               36usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_shdr),
+                       "::",
+                       stringify!(sh_entsize)));
+}
+impl Clone for elf32_shdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Shdr = elf32_shdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_shdr {
+    pub sh_name: Elf64_Word,
+    pub sh_type: Elf64_Word,
+    pub sh_flags: Elf64_Xword,
+    pub sh_addr: Elf64_Addr,
+    pub sh_offset: Elf64_Off,
+    pub sh_size: Elf64_Xword,
+    pub sh_link: Elf64_Word,
+    pub sh_info: Elf64_Word,
+    pub sh_addralign: Elf64_Xword,
+    pub sh_entsize: Elf64_Xword,
+}
+#[test]
+fn bindgen_test_layout_elf64_shdr() {
+    assert_eq!(::std::mem::size_of::<elf64_shdr>(),
+               64usize,
+               concat!("Size of: ", stringify!(elf64_shdr)));
+    assert_eq!(::std::mem::align_of::<elf64_shdr>(),
+               8usize,
+               concat!("Alignment of ", stringify!(elf64_shdr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_name as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_name)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_type as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_type)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_flags as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_flags)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_addr as *const _ as usize },
+               16usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_addr)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_offset as *const _ as usize },
+               24usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_offset)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_size as *const _ as usize },
+               32usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_size)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_link as *const _ as usize },
+               40usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_link)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_info as *const _ as usize },
+               44usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_info)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_addralign as *const _ as usize },
+               48usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_addralign)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_shdr)).sh_entsize as *const _ as usize },
+               56usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_shdr),
+                       "::",
+                       stringify!(sh_entsize)));
+}
+impl Clone for elf64_shdr {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Shdr = elf64_shdr;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf32_note {
+    pub n_namesz: Elf32_Word,
+    pub n_descsz: Elf32_Word,
+    pub n_type: Elf32_Word,
+}
+#[test]
+fn bindgen_test_layout_elf32_note() {
+    assert_eq!(::std::mem::size_of::<elf32_note>(),
+               12usize,
+               concat!("Size of: ", stringify!(elf32_note)));
+    assert_eq!(::std::mem::align_of::<elf32_note>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf32_note)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_note)).n_namesz as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_note),
+                       "::",
+                       stringify!(n_namesz)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_note)).n_descsz as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_note),
+                       "::",
+                       stringify!(n_descsz)));
+    assert_eq!(unsafe { &(*(0 as *const elf32_note)).n_type as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf32_note),
+                       "::",
+                       stringify!(n_type)));
+}
+impl Clone for elf32_note {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf32_Nhdr = elf32_note;
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct elf64_note {
+    pub n_namesz: Elf64_Word,
+    pub n_descsz: Elf64_Word,
+    pub n_type: Elf64_Word,
+}
+#[test]
+fn bindgen_test_layout_elf64_note() {
+    assert_eq!(::std::mem::size_of::<elf64_note>(),
+               12usize,
+               concat!("Size of: ", stringify!(elf64_note)));
+    assert_eq!(::std::mem::align_of::<elf64_note>(),
+               4usize,
+               concat!("Alignment of ", stringify!(elf64_note)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_note)).n_namesz as *const _ as usize },
+               0usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_note),
+                       "::",
+                       stringify!(n_namesz)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_note)).n_descsz as *const _ as usize },
+               4usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_note),
+                       "::",
+                       stringify!(n_descsz)));
+    assert_eq!(unsafe { &(*(0 as *const elf64_note)).n_type as *const _ as usize },
+               8usize,
+               concat!("Alignment of field: ",
+                       stringify!(elf64_note),
+                       "::",
+                       stringify!(n_type)));
+}
+impl Clone for elf64_note {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+pub type Elf64_Nhdr = elf64_note;
diff --git a/kernel_loader/src/lib.rs b/kernel_loader/src/lib.rs
new file mode 100644
index 0000000..0d88fa5
--- /dev/null
+++ b/kernel_loader/src/lib.rs
@@ -0,0 +1,207 @@
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+extern crate sys_util;
+
+use std::mem;
+use std::ffi::CStr;
+use std::io::{Read, Seek, SeekFrom};
+
+#[allow(dead_code)]
+#[allow(non_camel_case_types)]
+#[allow(non_snake_case)]
+#[allow(non_upper_case_globals)]
+mod elf;
+
+#[derive(Debug, PartialEq)]
+pub enum Error {
+    BigEndianElfOnLittle,
+    CommandLineOverflow,
+    ImagePastRamEnd,
+    InvalidElfMagicNumber,
+    InvalidProgramHeaderSize,
+    InvalidProgramHeaderOffset,
+    ReadElfHeader,
+    ReadKernelImage,
+    ReadProgramHeader,
+    SeekKernelStart,
+    SeekElfStart,
+    SeekProgramHeader,
+}
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Loads a kernel from a vmlinux elf image to a slice
+///
+/// # Arguments
+///
+/// * `guest_mem` - A u8 slice that will be partially overwritten by the kernel.
+/// * `kernel_start` - The offset into `guest_mem` at which to load the kernel.
+/// * `kernel_image` - Input vmlinux image.
+pub fn load_kernel<F>(guest_mem: &mut [u8], kernel_start: usize, kernel_image: &mut F) -> Result<()>
+    where F: Read + Seek
+{
+    let mut ehdr: elf::Elf64_Ehdr = Default::default();
+    kernel_image.seek(SeekFrom::Start(0))
+        .map_err(|_| Error::SeekElfStart)?;
+    unsafe {
+        // read_struct is safe when reading a POD struct.  It can be used and dropped without issue.
+        sys_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
+    }
+
+    // Sanity checks
+    if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8 ||
+       ehdr.e_ident[elf::EI_MAG1 as usize] != elf::ELFMAG1 ||
+       ehdr.e_ident[elf::EI_MAG2 as usize] != elf::ELFMAG2 ||
+       ehdr.e_ident[elf::EI_MAG3 as usize] != elf::ELFMAG3 {
+        return Err(Error::InvalidElfMagicNumber);
+    }
+    if ehdr.e_ident[elf::EI_DATA as usize] != elf::ELFDATA2LSB as u8 {
+        return Err(Error::BigEndianElfOnLittle);
+    }
+    if ehdr.e_phentsize as usize != mem::size_of::<elf::Elf64_Phdr>() {
+        return Err(Error::InvalidProgramHeaderSize);
+    }
+    if (ehdr.e_phoff as usize) < mem::size_of::<elf::Elf64_Ehdr>() {
+        // If the program header is backwards, bail.
+        return Err(Error::InvalidProgramHeaderOffset);
+    }
+
+    kernel_image.seek(SeekFrom::Start(ehdr.e_phoff))
+        .map_err(|_| Error::SeekProgramHeader)?;
+    let phdrs: Vec<elf::Elf64_Phdr> = unsafe {
+        // Reading the structs is safe for a slice of POD structs.
+        sys_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
+            .map_err(|_| Error::ReadProgramHeader)?
+    };
+
+    // Read in each section pointed to by the program headers.
+    for phdr in phdrs.iter() {
+        if (phdr.p_type & elf::PT_LOAD) == 0 || phdr.p_filesz == 0 {
+            continue;
+        }
+
+        let mem_offset = phdr.p_paddr as usize + kernel_start;
+        let mem_end = mem_offset + phdr.p_filesz as usize;
+        if mem_end > guest_mem.len() {
+            return Err(Error::ImagePastRamEnd);
+        }
+        let mut dst = &mut guest_mem[mem_offset..mem_end];
+        kernel_image.seek(SeekFrom::Start(phdr.p_offset))
+            .map_err(|_| Error::SeekKernelStart)?;
+        kernel_image.read_exact(dst)
+            .map_err(|_| Error::ReadKernelImage)?;
+    }
+
+    Ok(())
+}
+
+/// Writes the command line string to the given memory slice.
+///
+/// # Arguments
+///
+/// * `guest_mem` - A u8 slice that will be partially overwritten by the command line.
+/// * `kernel_start` - The offset into `guest_mem` at which to load the command line.
+/// * `cmdline` - The kernel command line.
+pub fn load_cmdline(guest_mem: &mut [u8], offset: usize, cmdline: &CStr) -> Result<()> {
+    let len = cmdline.to_bytes().len();
+    if len <= 0 {
+        return Ok(());
+    }
+
+    let end = offset + len + 1; // Extra for null termination.
+    if end > guest_mem.len() {
+        return Err(Error::CommandLineOverflow);
+    }
+    let cmdline_slice = &mut guest_mem[offset..end];
+    for (i, s) in cmdline_slice.iter_mut().enumerate() {
+        *s = cmdline.to_bytes().get(i).map_or(0, |c| (*c as u8));
+    }
+
+    Ok(())
+}
+
+#[cfg(test)]
+mod test {
+    use std::io::Cursor;
+    use super::*;
+
+    #[test]
+    fn cmdline_overflow() {
+        let mut mem = vec![0; 50];
+        assert_eq!(Err(Error::CommandLineOverflow),
+                   load_cmdline(mem.as_mut_slice(),
+                                45,
+                                CStr::from_bytes_with_nul(b"12345\0").unwrap()));
+    }
+
+    #[test]
+    fn cmdline_write_end() {
+        let mut mem = vec![0; 50];
+        assert_eq!(Ok(()),
+                   load_cmdline(mem.as_mut_slice(),
+                                45,
+                                CStr::from_bytes_with_nul(b"1234\0").unwrap()));
+        assert_eq!(mem[45], '1' as u8);
+        assert_eq!(mem[46], '2' as u8);
+        assert_eq!(mem[47], '3' as u8);
+        assert_eq!(mem[48], '4' as u8);
+        assert_eq!(mem[49], '\0' as u8);
+    }
+
+    // Elf64 image that prints hello world on x86_64.
+    fn make_elf_bin() -> Vec<u8> {
+        let mut v = Vec::new();
+        v.extend_from_slice(include_bytes!("test_elf.bin"));
+        v
+    }
+
+    #[test]
+    fn load_elf() {
+        let image = make_elf_bin();
+        let mut mem = Vec::<u8>::with_capacity(0x8000);
+        unsafe {
+            mem.set_len(0x8000);
+        }
+        assert_eq!(Ok(()),
+                   load_kernel(mem.as_mut_slice(), 0x0, &mut Cursor::new(&image)));
+    }
+
+    #[test]
+    fn bad_magic() {
+        let mut mem = Vec::<u8>::with_capacity(0x8000);
+        unsafe {
+            mem.set_len(0x8000);
+        }
+        let mut bad_image = make_elf_bin();
+        bad_image[0x1] = 0x33;
+        assert_eq!(Err(Error::InvalidElfMagicNumber),
+                   load_kernel(mem.as_mut_slice(), 0x0, &mut Cursor::new(&bad_image)));
+    }
+
+    #[test]
+    fn bad_endian() {
+        // Only little endian is supported
+        let mut mem = Vec::<u8>::with_capacity(0x8000);
+        unsafe {
+            mem.set_len(0x8000);
+        }
+        let mut bad_image = make_elf_bin();
+        bad_image[0x5] = 2;
+        assert_eq!(Err(Error::BigEndianElfOnLittle),
+                   load_kernel(mem.as_mut_slice(), 0x0, &mut Cursor::new(&bad_image)));
+    }
+
+    #[test]
+    fn bad_phoff() {
+        // program header has to be past the end of the elf header
+        let mut mem = Vec::<u8>::with_capacity(0x8000);
+        unsafe {
+            mem.set_len(0x8000);
+        }
+        let mut bad_image = make_elf_bin();
+        bad_image[0x20] = 0x10;
+        assert_eq!(Err(Error::InvalidProgramHeaderOffset),
+                   load_kernel(mem.as_mut_slice(), 0x0, &mut Cursor::new(&bad_image)));
+    }
+}
diff --git a/kernel_loader/src/test_elf.bin b/kernel_loader/src/test_elf.bin
new file mode 100644
index 0000000..74eac6e
--- /dev/null
+++ b/kernel_loader/src/test_elf.bin
Binary files differ