Skip to content

Commit fbc05fe

Browse files
committed
Detect ELF-32 at runtime, rather than compile time.
1 parent 5cb4ed6 commit fbc05fe

File tree

3 files changed

+84
-29
lines changed

3 files changed

+84
-29
lines changed

Cargo.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ name = "multiboot2"
33
version = "0.3.2"
44
authors = ["Philipp Oppermann <[email protected]>", "Calvin Lee <[email protected]>"]
55
license = "MIT/Apache-2.0"
6-
description = "An experimental Multiboot 2 crate for ELF-64 kernels."
6+
description = "An experimental Multiboot 2 crate for ELF-64/32 kernels."
77

88
[dependencies.bitflags]
99
version = "0.4.0"
1010
features = ["no_std"]
11-
12-
[features]
13-
elf32 = []

src/elf_sections.rs

Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,22 @@ pub struct ElfSectionIter {
5050
current_section: *const u8,
5151
remaining_sections: u32,
5252
entry_size: u32,
53-
string_section: *const ElfSectionInner,
53+
string_section: *const u8,
5454
}
5555

5656
impl Iterator for ElfSectionIter {
5757
type Item = ElfSection;
58+
5859
fn next(&mut self) -> Option<ElfSection> {
5960
if self.remaining_sections == 0 {
6061
return None;
6162
}
6263

6364
loop {
6465
let section = ElfSection {
65-
inner: self.current_section as *const ElfSectionInner,
66+
inner: self.current_section,
6667
string_section: self.string_section,
68+
entry_size: self.entry_size,
6769
};
6870

6971
self.current_section = unsafe { self.current_section.offset(self.entry_size as isize) };
@@ -77,14 +79,14 @@ impl Iterator for ElfSectionIter {
7779
}
7880

7981
pub struct ElfSection {
80-
inner: *const ElfSectionInner,
81-
string_section: *const ElfSectionInner,
82+
inner: *const u8,
83+
string_section: *const u8,
84+
entry_size: u32,
8285
}
8386

84-
#[cfg(feature = "elf32")]
8587
#[derive(Debug)]
8688
#[repr(C)]
87-
struct ElfSectionInner {
89+
struct ElfSectionInner32 {
8890
name_index: u32,
8991
typ: u32,
9092
flags: u32,
@@ -97,10 +99,9 @@ struct ElfSectionInner {
9799
entry_size: u32,
98100
}
99101

100-
#[cfg(not(feature = "elf32"))]
101102
#[derive(Debug)]
102103
#[repr(C)]
103-
struct ElfSectionInner {
104+
struct ElfSectionInner64 {
104105
name_index: u32,
105106
typ: u32,
106107
flags: u64,
@@ -115,7 +116,7 @@ struct ElfSectionInner {
115116

116117
impl ElfSection {
117118
pub fn section_type(&self) -> ElfSectionType {
118-
match self.get().typ {
119+
match self.get().typ() {
119120
0 => ElfSectionType::Unused,
120121
1 => ElfSectionType::ProgramSection,
121122
2 => ElfSectionType::LinkerSymbolTable,
@@ -135,14 +136,14 @@ impl ElfSection {
135136
}
136137

137138
pub fn section_type_raw(&self) -> u32 {
138-
self.get().typ
139+
self.get().typ()
139140
}
140141

141142
pub fn name(&self) -> &str {
142143
use core::{str, slice};
143144

144145
let name_ptr = unsafe {
145-
self.string_table().offset(self.get().name_index as isize)
146+
self.string_table().offset(self.get().name_index() as isize)
146147
};
147148
let strlen = {
148149
let mut len = 0;
@@ -156,31 +157,95 @@ impl ElfSection {
156157
}
157158

158159
pub fn start_address(&self) -> usize {
159-
self.get().addr as usize
160+
self.get().addr()
160161
}
161162

162163
pub fn end_address(&self) -> usize {
163-
(self.get().addr + self.get().size) as usize
164+
self.get().addr() + self.get().size()
164165
}
165166

166167
pub fn size(&self) -> usize {
167-
self.get().size as usize
168+
self.get().size()
168169
}
169170

170171
pub fn flags(&self) -> ElfSectionFlags {
171-
ElfSectionFlags::from_bits_truncate(self.get().flags)
172+
ElfSectionFlags::from_bits_truncate(self.get().flags())
172173
}
173174

174175
pub fn is_allocated(&self) -> bool {
175176
self.flags().contains(ELF_SECTION_ALLOCATED)
176177
}
177178

178179
fn get(&self) -> &ElfSectionInner {
179-
unsafe { &*self.inner }
180+
match self.entry_size {
181+
40 => unsafe { &*(self.inner as *const ElfSectionInner32) },
182+
64 => unsafe { &*(self.inner as *const ElfSectionInner64) },
183+
_ => panic!(),
184+
}
180185
}
181186

182187
unsafe fn string_table(&self) -> *const u8 {
183-
(*self.string_section).addr as *const _
188+
match self.entry_size {
189+
40 => (*(self.string_section as *const ElfSectionInner32)).addr as *const _,
190+
64 => (*(self.string_section as *const ElfSectionInner64)).addr as *const _,
191+
_ => panic!(),
192+
}
193+
}
194+
}
195+
196+
trait ElfSectionInner {
197+
fn name_index(&self) -> u32;
198+
199+
fn typ(&self) -> u32;
200+
201+
fn flags(&self) -> u32;
202+
203+
fn addr(&self) -> usize;
204+
205+
fn size(&self) -> usize;
206+
}
207+
208+
impl ElfSectionInner for ElfSectionInner32 {
209+
fn name_index(&self) -> u32 {
210+
self.name_index
211+
}
212+
213+
fn typ(&self) -> u32 {
214+
self.typ
215+
}
216+
217+
fn flags(&self) -> u32 {
218+
self.flags
219+
}
220+
221+
fn addr(&self) -> usize {
222+
self.addr as usize
223+
}
224+
225+
fn size(&self) -> usize {
226+
self.size as usize
227+
}
228+
}
229+
230+
impl ElfSectionInner for ElfSectionInner64 {
231+
fn name_index(&self) -> u32 {
232+
self.name_index
233+
}
234+
235+
fn typ(&self) -> u32 {
236+
self.typ
237+
}
238+
239+
fn flags(&self) -> u32 {
240+
self.flags as u32
241+
}
242+
243+
fn addr(&self) -> usize {
244+
self.addr as usize
245+
}
246+
247+
fn size(&self) -> usize {
248+
self.size as usize
184249
}
185250
}
186251

@@ -203,14 +268,8 @@ pub enum ElfSectionType {
203268
ProcessorSpecific = 0x7000_0000,
204269
}
205270

206-
#[cfg(feature = "elf32")]
207-
type ElfSectionFlagsType = u32;
208-
209-
#[cfg(not(feature = "elf32"))]
210-
type ElfSectionFlagsType = u64;
211-
212271
bitflags! {
213-
flags ElfSectionFlags: ElfSectionFlagsType {
272+
flags ElfSectionFlags: u32 {
214273
const ELF_SECTION_WRITABLE = 0x1,
215274
const ELF_SECTION_ALLOCATED = 0x2,
216275
const ELF_SECTION_EXECUTABLE = 0x4,

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ mod tests {
234234
assert!(bi.command_line_tag().is_none());
235235
}
236236

237-
#[cfg(not(feature = "elf32"))]
238237
#[test]
239238
fn grub2() {
240239
let mut bytes: [u8; 960] = [

0 commit comments

Comments
 (0)