summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs12
-rw-r--r--src/structs.rs95
2 files changed, 98 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs
index 7a189bf..3033ece 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,10 +16,18 @@ impl Elf {
             header
         }
     }
-} 
+}
+
+// readelf behavior here
+impl std::fmt::Display for Elf {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        formatter.write_str("ELF Header:\n");
+        formatter.write_fmt(format_args!("{}", self.header))
+    }
+}
 
 fn main() {
     let data = include_bytes!("../elf");
     let elf = Elf::new(&data[..]);
-    println!("{:?}", elf);
+    println!("{}", elf);
 }
diff --git a/src/structs.rs b/src/structs.rs
index c055350..f5eb7ea 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -23,10 +23,30 @@ pub struct ElfIdent {
 	pub _unused: [u8; 7],
 }
 
+impl std::fmt::Display for ElfIdent {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        formatter.write_str("Magic:\t");
+        
+        for b in unsafe {*(std::ptr::addr_of!(self) as *const [u8; 16])} {
+            formatter.pad(&format!("{:02x?} ", b));
+        }
+
+        formatter.write_fmt(format_args!("\nClass:\t{:?}", self.class));
+        formatter.write_fmt(format_args!("\nData:\t{}", self.data));
+        formatter.write_fmt(format_args!("\nVersion:\t{} ({})", self.version, match self.version {
+			0 => "invalid",
+			1 => "current",
+			2_u8..=u8::MAX => todo!(), // need to cover all cases
+		}));
+        formatter.write_fmt(format_args!("\nOS/ABI:\t{}", self.OSABI));
+        formatter.write_fmt(format_args!("\nABI Verscion:\t{}", self.ABIVersion))
+    }
+}
+
 // https://man7.org/linux/man-pages/man5/elf.5.html
 // https://wiki.osdev.org/ELF
 // https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
-#[repr(C, packed)]
+#[repr(C)]
 #[derive(Debug)]
 pub struct ElfHeader {
 	pub ident: ElfIdent,
@@ -72,6 +92,25 @@ pub struct ElfHeader {
 	pub shstrndx: u16,
 }
 
+impl std::fmt::Display for ElfHeader {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        formatter.write_fmt(format_args!("{}", self.ident));
+        formatter.write_fmt(format_args!("\nType:\t{}", self.r#type));
+        formatter.write_fmt(format_args!("\nMachine:\t{}", self.machine));
+        formatter.write_fmt(format_args!("\nVersion:\t{:#02x?}", self.version));
+        formatter.write_fmt(format_args!("\nEntry point address:\t{:#x?}", self.entry));
+        formatter.write_fmt(format_args!("\nStart of program headers:\t{} (bytes into file)", self.phoff));
+        formatter.write_fmt(format_args!("\nStart of section headers:\t{} (bytes into file)", self.shoff));
+        formatter.write_fmt(format_args!("\nFlags:\t{:#x?}", self.flags));
+        formatter.write_fmt(format_args!("\nSize of this header:\t{} (bytes)", self.ehsize));
+        formatter.write_fmt(format_args!("\nSize of program headers:\t{} (bytes)", self.phentsize));
+        formatter.write_fmt(format_args!("\nNumber of program headers:\t{}", self.phnum));
+        formatter.write_fmt(format_args!("\nSize of section headers:\t{} (bytes)", self.shentsize));
+        formatter.write_fmt(format_args!("\nNumber of section headers:\t{}", self.shnum));
+        formatter.write_fmt(format_args!("\nSection header string table index:\t{}", self.shstrndx))
+    }
+}
+
 #[derive(Debug, Copy, Clone)]
 #[repr(u16)]
 pub enum Type {
@@ -82,13 +121,36 @@ pub enum Type {
 	Core = 4,
 }
 
+impl std::fmt::Display for Type {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+			Type::None => formatter.write_str("NONE (None)"),
+			Type::Rel => formatter.write_str("REL (Relocatable file)"),
+			Type::Exec => formatter.write_str("EXEC (Executable file)"),
+			Type::Dyn => formatter.write_str("DYN (Shared object file)"),
+			Type::Core => formatter.write_str("CORE (Core file)"),
+		}
+    }
+}
+
 #[derive(Debug, Copy, Clone)]
 #[repr(u16)]
 pub enum Machine {
+	// there are many many many more, im just gonna do x86
+	// https://github.com/bminor/binutils-gdb/blob/master/binutils/readelf.c#L2746
 	None = 1,
 	X86_64 = 62,
 }
 
+impl std::fmt::Display for Machine {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+			Machine::None => formatter.write_str("None"),
+			Machine::X86_64 => formatter.write_str("Advanced Micro Devices X86-64"),
+		}
+    }
+}
+
 
 #[derive(Debug, Copy, Clone)]
 #[repr(u8)]
@@ -102,18 +164,37 @@ pub enum Class {
 pub enum OSABI {
 	None = 0x00,
 	SystemV = 0x01,
-	HPUX = 0x02,
-	Solaris = 0x03,
-	IRIX = 0x04,
-	FreeBSD = 0x05,
-	TRU64 = 0x06,
-	ARM = 0x07,
+	// HPUX = 0x02,
+	// Solaris = 0x03,
+	// IRIX = 0x04,
+	// FreeBSD = 0x05,
+	// TRU64 = 0x06,
+	// ARM = 0x07,
 	Standalone = 0x08,
 }
 
+impl std::fmt::Display for OSABI {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+			OSABI::None => formatter.write_str("UNIX - System V"),
+			OSABI::SystemV => formatter.write_str("UNIX - System V"),
+			OSABI::Standalone => formatter.write_str("Standalone"),
+		}
+    }
+}
+
 #[derive(Debug, Copy, Clone)]
 #[repr(u8)]
 pub enum Endian {
 	Little = 1,
 	Big = 2,
+}
+
+impl std::fmt::Display for Endian {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+			Endian::Little => formatter.write_str("2's complement, little endian"),
+			Endian::Big => formatter.write_str("1's complement, big endian"),
+		}
+    }
 }
\ No newline at end of file