diff options
author | Dylan Reid <dgreid@chromium.org> | 2017-05-04 13:52:16 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-05-17 19:06:31 -0700 |
commit | 9195ec9b239f4fd70c64531e6c4fa00774c49c5f (patch) | |
tree | fb27becb53d5b8b65928f96bad1187114a71992b /kernel_loader | |
parent | 67030be903bb02e51c7690fa6beb8ce57f0b9fa3 (diff) | |
download | crosvm-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.toml | 7 | ||||
-rw-r--r-- | kernel_loader/src/elf.rs | 1403 | ||||
-rw-r--r-- | kernel_loader/src/lib.rs | 207 | ||||
-rw-r--r-- | kernel_loader/src/test_elf.bin | bin | 0 -> 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 |