From be60cccbf9b1a58eb0b866006bf9262c9cd36643 Mon Sep 17 00:00:00 2001 From: Christopher Cole Date: Sun, 30 Oct 2022 14:26:07 -0700 Subject: [PATCH] Add to_str feature which exports to_str and Display impls for gabi constants This has a few motivations: * Move the big blocks of code dedicated to providing human readable strings for gabi constants out of the way. This code can be long and distracting from the actual parsing functionality. * Allow users to opt out of this functionality if they don't need it. The big blocks of &'static str definitions can add a fair amount to the resulting library size. For users who are trying to optimize for library size, these to_str methods are often unneeded. * The to_str method's Option return value allows users to decide how they want to display unknown values. --- Cargo.toml | 3 ++- src/lib.rs | 3 +++ src/symbol.rs | 43 ----------------------------- src/to_str.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 src/to_str.rs diff --git a/Cargo.toml b/Cargo.toml index 1b5f947..ed00105 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,6 @@ name = "elf" [dependencies] [features] -default = ["std"] +default = ["std", "to_str"] std = [] +to_str = [] diff --git a/src/lib.rs b/src/lib.rs index e8a1d4b..4f40b7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,9 @@ pub mod segment; pub mod string_table; pub mod symbol; +#[cfg(feature = "to_str")] +pub mod to_str; + mod parse; pub use file::File; diff --git a/src/symbol.rs b/src/symbol.rs index ffaa3dc..2808a16 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -134,55 +134,12 @@ impl core::fmt::Display for Symbol { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct SymbolType(pub u8); -impl core::fmt::Display for SymbolType { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - let str = match self.0 { - gabi::STT_NOTYPE => "STT_NOTYPE", - gabi::STT_OBJECT => "STT_OBJECT", - gabi::STT_FUNC => "STT_FUNC", - gabi::STT_SECTION => "STT_SECTION", - gabi::STT_FILE => "STT_FILE", - gabi::STT_COMMON => "STT_COMMON", - gabi::STT_TLS => "STT_TLS", - gabi::STT_GNU_IFUNC => "STT_GNU_IFUNC", - _ => "Unknown", - }; - write!(f, "{}", str) - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct SymbolBind(pub u8); -impl core::fmt::Display for SymbolBind { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - let str = match self.0 { - gabi::STB_LOCAL => "STB_LOCAL", - gabi::STB_GLOBAL => "STB_GLOBAL", - gabi::STB_WEAK => "STB_WEAK", - gabi::STB_GNU_UNIQUE => "STB_GNU_UNIQUE", - _ => "Unknown", - }; - write!(f, "{}", str) - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct SymbolVis(pub u8); -impl core::fmt::Display for SymbolVis { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - let str = match self.0 { - gabi::STV_DEFAULT => "STV_DEFAULT", - gabi::STV_INTERNAL => "STV_INTERNAL", - gabi::STV_HIDDEN => "STV_HIDDEN", - gabi::STV_PROTECTED => "STV_PROTECTED", - _ => "Unknown", - }; - write!(f, "{}", str) - } -} - #[cfg(test)] mod table_tests { use super::*; diff --git a/src/to_str.rs b/src/to_str.rs new file mode 100644 index 0000000..58b29a0 --- /dev/null +++ b/src/to_str.rs @@ -0,0 +1,75 @@ +use crate::gabi; +use crate::symbol::{SymbolBind, SymbolType, SymbolVis}; + +pub fn st_symtype_to_str(st_symtype: u8) -> Option<&'static str> { + match st_symtype { + gabi::STT_NOTYPE => Some("STT_NOTYPE"), + gabi::STT_OBJECT => Some("STT_OBJECT"), + gabi::STT_FUNC => Some("STT_FUNC"), + gabi::STT_SECTION => Some("STT_SECTION"), + gabi::STT_FILE => Some("STT_FILE"), + gabi::STT_COMMON => Some("STT_COMMON"), + gabi::STT_TLS => Some("STT_TLS"), + gabi::STT_GNU_IFUNC => Some("STT_GNU_IFUNC"), + _ => None, + } +} + +impl core::fmt::Display for SymbolType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match st_symtype_to_str(self.0) { + Some(s) => { + write!(f, "{s}") + } + None => { + write!(f, "{}", format!("st_symtype({})", self.0)) + } + } + } +} + +pub fn st_bind_to_str(st_bind: u8) -> Option<&'static str> { + match st_bind { + gabi::STB_LOCAL => Some("STB_LOCAL"), + gabi::STB_GLOBAL => Some("STB_GLOBAL"), + gabi::STB_WEAK => Some("STB_WEAK"), + gabi::STB_GNU_UNIQUE => Some("STB_GNU_UNIQUE"), + _ => None, + } +} + +impl core::fmt::Display for SymbolBind { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match st_bind_to_str(self.0) { + Some(s) => { + write!(f, "{s}") + } + None => { + write!(f, "{}", format!("st_bind({})", self.0)) + } + } + } +} + +pub fn st_vis_to_str(st_vis: u8) -> Option<&'static str> { + match st_vis { + gabi::STV_DEFAULT => Some("STV_DEFAULT"), + gabi::STV_INTERNAL => Some("STV_INTERNAL"), + gabi::STV_HIDDEN => Some("STV_HIDDEN"), + gabi::STV_PROTECTED => Some("STV_PROTECTED"), + _ => None, + } +} + +impl core::fmt::Display for SymbolVis { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match st_vis_to_str(self.0) { + Some(s) => { + write!(f, "{s}") + } + None => { + write!(f, "{}", format!("st_vis({})", self.0)) + } + } + } +}