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.
This commit is contained in:
Christopher Cole 2022-10-30 14:26:07 -07:00
parent b73c9ba515
commit be60cccbf9
No known key found for this signature in database
GPG Key ID: 0AC856975983E9DB
4 changed files with 80 additions and 44 deletions

View File

@ -17,5 +17,6 @@ name = "elf"
[dependencies]
[features]
default = ["std"]
default = ["std", "to_str"]
std = []
to_str = []

View File

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

View File

@ -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::*;

75
src/to_str.rs Normal file
View File

@ -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))
}
}
}
}