1use crate::util::{opt_u32, read_str, read_u32le, read_u8};
2use std::fmt::{self, Display, Formatter};
3use std::io::{self, Read};
4
5#[derive(Debug)]
7pub struct Symbol {
8 name: Vec<u8>,
9 visibility: SymbolVisibility,
10}
11impl Symbol {
12 pub(crate) fn read_from(mut input: impl Read) -> Result<Self, io::Error> {
13 let name = read_str(&mut input)?;
14 let visibility = SymbolVisibility::read_from(input)?;
15 Ok(Self { name, visibility })
16 }
17
18 pub fn name(&self) -> &[u8] {
21 &self.name
22 }
23
24 pub fn visibility(&self) -> &SymbolVisibility {
26 &self.visibility
27 }
28}
29
30#[derive(Debug)]
32pub enum SymbolVisibility {
33 Local(SymbolDef),
35 Imported,
37 Exported(SymbolDef),
39}
40impl SymbolVisibility {
41 fn read_from(mut input: impl Read) -> Result<Self, io::Error> {
42 use SymbolVisibility::*;
43
44 match read_u8(&mut input)? {
45 0 => Ok(Local(SymbolDef::read_from(input)?)),
46 1 => Ok(Imported),
47 2 => Ok(Exported(SymbolDef::read_from(input)?)),
48 _ => Err(io::Error::new(
49 io::ErrorKind::InvalidData,
50 "Invalid symbol visibility type",
51 )),
52 }
53 }
54
55 pub fn name(&self) -> &'static str {
57 use SymbolVisibility::*;
58
59 match self {
60 Local(..) => "local",
61 Imported => "import",
62 Exported(..) => "export",
63 }
64 }
65
66 pub fn data(&self) -> Option<&SymbolDef> {
68 use SymbolVisibility::*;
69
70 match self {
71 Local(data) | Exported(data) => Some(data),
72 Imported => None,
73 }
74 }
75}
76impl Display for SymbolVisibility {
77 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
78 write!(fmt, "{}", self.name())
79 }
80}
81
82#[derive(Debug)]
84pub struct SymbolDef {
85 source_file_id: u32,
86 line_no: u32,
87 section_id: Option<u32>,
88 value: u32,
89}
90impl SymbolDef {
91 fn read_from(mut input: impl Read) -> Result<Self, io::Error> {
92 let source_file_id = read_u32le(&mut input)?;
93 let line_no = read_u32le(&mut input)?;
94 let section_id = opt_u32(read_u32le(&mut input)?);
95 let value = read_u32le(input)?;
96
97 Ok(Self {
98 source_file_id,
99 line_no,
100 section_id,
101 value,
102 })
103 }
104
105 pub fn source(&self) -> (u32, u32) {
108 (self.source_file_id, self.line_no)
109 }
110
111 pub fn section(&self) -> Option<u32> {
114 self.section_id
115 }
116
117 pub fn value(&self) -> u32 {
119 self.value
120 }
121}