1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use super::{Address, Error, Encoding, Index, Entry}; #[derive(Clone, Debug, Eq, PartialEq)] pub enum SymbolBinding { Local, Global, Weak, OsSpecific(u8), ProcessorSpecific(u8), Unknown(u8), } #[derive(Clone, Debug, Eq, PartialEq)] pub enum SymbolType { Nothing, Object, Function, Section, File, OsSpecific(u8), ProcessorSpecific(u8), Unknown(u8), } #[derive(Clone, Debug, Eq, PartialEq)] pub struct SymbolInfo { pub binding: SymbolBinding, pub ty: SymbolType, } impl From<u8> for SymbolInfo { fn from(v: u8) -> Self { SymbolInfo { binding: match (v & 0xf0) / 0x10 { 0x00 => SymbolBinding::Local, 0x01 => SymbolBinding::Global, 0x02 => SymbolBinding::Weak, t @ 0x0a..=0x0c => SymbolBinding::OsSpecific(t - 0x0a), t @ 0x0d..=0x0f => SymbolBinding::ProcessorSpecific(t - 0x0d), t => SymbolBinding::Unknown(t), }, ty: match v & 0x0f { 0x00 => SymbolType::Nothing, 0x01 => SymbolType::Object, 0x02 => SymbolType::Function, 0x03 => SymbolType::Section, 0x04 => SymbolType::File, t @ 0x0a..=0x0c => SymbolType::OsSpecific(t - 0x0a), t @ 0x0d..=0x0f => SymbolType::ProcessorSpecific(t - 0x0d), t => SymbolType::Unknown(t), }, } } } impl From<SymbolInfo> for u8 { fn from(v: SymbolInfo) -> Self { let SymbolInfo { binding, ty } = v; let high = match binding { SymbolBinding::Local => 0x00, SymbolBinding::Global => 0x01, SymbolBinding::Weak => 0x02, SymbolBinding::OsSpecific(t) => t + 0x0a, SymbolBinding::ProcessorSpecific(t) => t + 0x0d, SymbolBinding::Unknown(t) => t, }; let low = match ty { SymbolType::Nothing => 0x00, SymbolType::Object => 0x01, SymbolType::Function => 0x02, SymbolType::Section => 0x03, SymbolType::File => 0x04, SymbolType::OsSpecific(t) => t + 0x0a, SymbolType::ProcessorSpecific(t) => t + 0x0d, SymbolType::Unknown(t) => t, }; high * 0x10 + low } } #[derive(Clone, Debug, Eq, PartialEq)] pub struct SymbolEntry { pub name: u32, pub info: SymbolInfo, pub reserved: u8, pub section_index: Index, pub value: Address, pub size: u64, } impl Entry for SymbolEntry { type Error = Error; const SIZE: usize = 0x18; fn new(slice: &[u8], encoding: Encoding) -> Result<Self, Self::Error> { if slice.len() < Self::SIZE { return Err(Error::SliceTooShort); } Ok(SymbolEntry { name: read_int!(&slice[0x00..], &encoding, u32), info: slice[0x04].into(), reserved: slice[0x05], section_index: read_int!(&slice[0x06..], &encoding, u16).into(), value: read_int!(&slice[0x08..], &encoding, u64), size: read_int!(&slice[0x10..], &encoding, u64), }) } }