|
@@ -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,
|