浏览代码

Detect ELF-32 at runtime, rather than compile time.

Ahmed Charles 8 年之前
父节点
当前提交
fbc05fed1c
共有 3 个文件被更改,包括 84 次插入29 次删除
  1. 1 4
      Cargo.toml
  2. 83 24
      src/elf_sections.rs
  3. 0 1
      src/lib.rs

+ 1 - 4
Cargo.toml

@@ -3,11 +3,8 @@ name = "multiboot2"
 version = "0.3.2"
 authors = ["Philipp Oppermann <dev@phil-opp.com>", "Calvin Lee <cyrus296@gmail.com>"]
 license = "MIT/Apache-2.0"
-description = "An experimental Multiboot 2 crate for ELF-64 kernels."
+description = "An experimental Multiboot 2 crate for ELF-64/32 kernels."
 
 [dependencies.bitflags]
 version = "0.4.0"
 features = ["no_std"]
-
-[features]
-elf32 = []

+ 83 - 24
src/elf_sections.rs

@@ -50,11 +50,12 @@ pub struct ElfSectionIter {
     current_section: *const u8,
     remaining_sections: u32,
     entry_size: u32,
-    string_section: *const ElfSectionInner,
+    string_section: *const u8,
 }
 
 impl Iterator for ElfSectionIter {
     type Item = ElfSection;
+
     fn next(&mut self) -> Option<ElfSection> {
         if self.remaining_sections == 0 {
             return None;
@@ -62,8 +63,9 @@ impl Iterator for ElfSectionIter {
 
         loop {
             let section = ElfSection {
-                inner: self.current_section as *const ElfSectionInner,
+                inner: self.current_section,
                 string_section: self.string_section,
+                entry_size: self.entry_size,
             };
 
             self.current_section = unsafe { self.current_section.offset(self.entry_size as isize) };
@@ -77,14 +79,14 @@ impl Iterator for ElfSectionIter {
 }
 
 pub struct ElfSection {
-    inner: *const ElfSectionInner,
-    string_section: *const ElfSectionInner,
+    inner: *const u8,
+    string_section: *const u8,
+    entry_size: u32,
 }
 
-#[cfg(feature = "elf32")]
 #[derive(Debug)]
 #[repr(C)]
-struct ElfSectionInner {
+struct ElfSectionInner32 {
     name_index: u32,
     typ: u32,
     flags: u32,
@@ -97,10 +99,9 @@ struct ElfSectionInner {
     entry_size: u32,
 }
 
-#[cfg(not(feature = "elf32"))]
 #[derive(Debug)]
 #[repr(C)]
-struct ElfSectionInner {
+struct ElfSectionInner64 {
     name_index: u32,
     typ: u32,
     flags: u64,
@@ -115,7 +116,7 @@ struct ElfSectionInner {
 
 impl ElfSection {
     pub fn section_type(&self) -> ElfSectionType {
-        match self.get().typ {
+        match self.get().typ() {
             0 => ElfSectionType::Unused,
             1 => ElfSectionType::ProgramSection,
             2 => ElfSectionType::LinkerSymbolTable,
@@ -135,14 +136,14 @@ impl ElfSection {
     }
 
     pub fn section_type_raw(&self) -> u32 {
-        self.get().typ
+        self.get().typ()
     }
 
     pub fn name(&self) -> &str {
         use core::{str, slice};
 
         let name_ptr = unsafe {
-            self.string_table().offset(self.get().name_index as isize)
+            self.string_table().offset(self.get().name_index() as isize)
         };
         let strlen = {
             let mut len = 0;
@@ -156,19 +157,19 @@ impl ElfSection {
     }
 
     pub fn start_address(&self) -> usize {
-        self.get().addr as usize
+        self.get().addr()
     }
 
     pub fn end_address(&self) -> usize {
-        (self.get().addr + self.get().size) as usize
+        self.get().addr() + self.get().size()
     }
 
     pub fn size(&self) -> usize {
-        self.get().size as usize
+        self.get().size()
     }
 
     pub fn flags(&self) -> ElfSectionFlags {
-        ElfSectionFlags::from_bits_truncate(self.get().flags)
+        ElfSectionFlags::from_bits_truncate(self.get().flags())
     }
 
     pub fn is_allocated(&self) -> bool {
@@ -176,11 +177,75 @@ impl ElfSection {
     }
 
     fn get(&self) -> &ElfSectionInner {
-        unsafe { &*self.inner }
+        match self.entry_size {
+            40 => unsafe { &*(self.inner as *const ElfSectionInner32) },
+            64 => unsafe { &*(self.inner as *const ElfSectionInner64) },
+            _ => panic!(),
+        }
     }
 
     unsafe fn string_table(&self) -> *const u8 {
-        (*self.string_section).addr as *const _
+        match self.entry_size {
+            40 => (*(self.string_section as *const ElfSectionInner32)).addr as *const _,
+            64 => (*(self.string_section as *const ElfSectionInner64)).addr as *const _,
+            _ => panic!(),
+        }
+    }
+}
+
+trait ElfSectionInner {
+    fn name_index(&self) -> u32;
+
+    fn typ(&self) -> u32;
+
+    fn flags(&self) -> u32;
+
+    fn addr(&self) -> usize;
+
+    fn size(&self) -> usize;
+}
+
+impl ElfSectionInner for ElfSectionInner32 {
+    fn name_index(&self) -> u32 {
+        self.name_index
+    }
+
+    fn typ(&self) -> u32 {
+        self.typ
+    }
+
+    fn flags(&self) -> u32 {
+        self.flags
+    }
+
+    fn addr(&self) -> usize {
+        self.addr as usize
+    }
+
+    fn size(&self) -> usize {
+        self.size as usize
+    }
+}
+
+impl ElfSectionInner for ElfSectionInner64 {
+    fn name_index(&self) -> u32 {
+        self.name_index
+    }
+
+    fn typ(&self) -> u32 {
+        self.typ
+    }
+
+    fn flags(&self) -> u32 {
+        self.flags as u32
+    }
+
+    fn addr(&self) -> usize {
+        self.addr as usize
+    }
+
+    fn size(&self) -> usize {
+        self.size as usize
     }
 }
 
@@ -203,14 +268,8 @@ pub enum ElfSectionType {
     ProcessorSpecific = 0x7000_0000,
 }
 
-#[cfg(feature = "elf32")]
-type ElfSectionFlagsType = u32;
-
-#[cfg(not(feature = "elf32"))]
-type ElfSectionFlagsType = u64;
-
 bitflags! {
-    flags ElfSectionFlags: ElfSectionFlagsType {
+    flags ElfSectionFlags: u32 {
         const ELF_SECTION_WRITABLE = 0x1,
         const ELF_SECTION_ALLOCATED = 0x2,
         const ELF_SECTION_EXECUTABLE = 0x4,

+ 0 - 1
src/lib.rs

@@ -234,7 +234,6 @@ mod tests {
         assert!(bi.command_line_tag().is_none());
     }
 
-    #[cfg(not(feature = "elf32"))]
     #[test]
     fn grub2() {
         let mut bytes: [u8; 960] = [