userspace/file/format/elf/header/identifier.rs
1pub mod class;
2pub use class::Class;
3
4pub mod index;
5pub use index::Index;
6
7pub mod magic;
8pub use magic::Magic;
9
10pub mod os_abi;
11pub use os_abi::OsABI;
12
13use crate::file::format::elf::dtype;
14
15use dtype::UChar as T;
16
17// /// # Identifier to file as an ELF object file
18// ///
19// /// Provide information about the data representation of the object file structures.
20// /// The bytes of this array that have defined meanings are detailed below.
21// /// The remaining bytes are reserved for future use, and should be set to zero.
22// #[repr(C)]
23
24ample::r#struct!(
25 #[derive(Debug)]
26 pub struct Identifier {
27 /// # Array with “magic numbers” identifying the file as an ELF object file.
28 ///
29 /// They contain the characters ‘\x7f’, ‘E’, ‘L’, and ‘F’, respectively.
30 /// pub magic: [T; 4],
31 pub magic0: T,
32 pub magic1: T,
33 pub magic2: T,
34 pub magic3: T,
35 /// # Identifies the class of the object file, or its capacity.
36 ///
37 /// |Name|Value|Meaning|
38 /// |:-:|:-:|:-:|
39 /// |C32|1|32-bit objects|
40 /// |C64|2|64-bit objects|
41 ///
42 /// The class of the ELF file is independent of the data model assumed by the
43 /// object code. The EI_CLASS field identifies the file format; a processor-
44 /// specific flag in the e_flags field, described below, may be used to identify
45 /// the application’s data model if the processory supports multiple models.
46 pub class: T,
47 /// # Data encoding of the object file data structures
48 ///
49 /// *endianness was originaly identified with "data"*
50 ///
51 /// |Name|Value|Meaning|
52 /// |:-:|:-:|:-:|
53 /// |None|0|Invalid endianness|
54 /// |LSB|1|Little-endian|
55 /// |MSB|2|Big-endian|
56 ///
57 /// For the convenience of code that examines ELF object files at run time
58 /// (e.g., the dynamic loader), it is intended that the data encoding of the
59 /// object file will match that of the running program. For environments that
60 /// support both byte orders, a processor-specific flag in the e_flags field,
61 /// described below, may be used to identify the application’s operating mode.
62 pub endianness: T,
63 /// # Version of the object file format.
64 ///
65 /// Currently, this field has the value
66 /// CURRENT, which is defined with the value 1.
67 pub version: T,
68 /// # Operating system and ABI for which the object is prepared.
69 ///
70 /// Some fields in other ELF structures have flags and values
71 /// that have environment-specific meanings; the interpretation of
72 /// those fields is determined by the value of this field.
73 pub osabi: T,
74 /// # ABI version for which the object is prepared.
75 ///
76 /// Used to distinguish incompatible versions of an ABI.
77 /// Interpretation of this version number is dependent on the ABI identified
78 /// by the EI_OSABI field.
79 /// For applications conforming to the System V ABI, third edition, this field
80 /// should contain 0.
81 pub abiversion: T,
82 /// # Padding bytes
83 pub padding: T,
84 /// # Five unsassigned bytes
85 pub unassigned0: T,
86 pub unassigned1: T,
87 pub unassigned2: T,
88 pub unassigned3: T,
89 pub unassigned4: T,
90 /// # Number of bytes of identifier
91 pub nident: T,
92 }
93);
94
95impl Identifier {
96 /// Loads ELF Identifier from a compliant path
97 ///
98 /// ```rust
99 /// let path : &str = "./data/symver.powerpc64.so";
100 /// let identifier = lib::header::elf::Identifier::from_filepath(&path);
101 /// println!("{}",identifier);
102 /// ```
103 pub fn from_path(filepath: &str) -> crate::Result {
104 let file_descriptor = crate::file::open(filepath);
105 Self::from_file_descriptor(file_descriptor)
106 }
107
108 /// Loads ELF Identifier from a filemap
109 ///
110 /// ```rust
111 /// let path : &str = "./data/symver.powerpc64.so";
112 /// let file = core::fs::File::open(path).unwrap();
113 /// let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
114 /// let identifier = lib::header::elf::Identifier::from_memmap(&map);
115 /// println!("{}",identifier);
116 /// ```
117 pub fn from_file_descriptor(file_descriptor: isize) -> crate::Result {
118 crate::file::seek(file_descriptor, 0);
119
120 core::result::Result::Ok(crate::Ok::File(crate::file::Ok::Format(
121 crate::file::format::Ok::Elf(crate::file::format::elf::Ok::Header(
122 crate::file::format::elf::header::Ok::Identifier(Identifier {
123 magic0: T::read(file_descriptor, true)?,
124 magic1: T::read(file_descriptor, true)?,
125 magic2: T::read(file_descriptor, true)?,
126 magic3: T::read(file_descriptor, true)?,
127 class: T::read(file_descriptor, true)?,
128 endianness: T::read(file_descriptor, true)?,
129 version: T::read(file_descriptor, true)?,
130 osabi: T::read(file_descriptor, true)?,
131 abiversion: T::read(file_descriptor, true)?,
132 padding: T::read(file_descriptor, true)?,
133 unassigned0: T::read(file_descriptor, true)?,
134 unassigned1: T::read(file_descriptor, true)?,
135 unassigned2: T::read(file_descriptor, true)?,
136 unassigned3: T::read(file_descriptor, true)?,
137 unassigned4: T::read(file_descriptor, true)?,
138 nident: T::read(file_descriptor, true)?,
139 }),
140 )),
141 )))
142 }
143
144 /// Each byte of the array is indexed symbolically using the names in the Table
145 /// |Name|Value|Purpose|
146 /// |:-:|:-:|:-:|
147 /// |Mag0|0|File identification|
148 /// |Mag1|1|File identification|
149 /// |Mag2|2|File identification|
150 /// |Mag3|3|File identification|
151 /// |Class|4|File class|
152 /// |Data|5|Data encoding|
153 /// |Version|6|File version|
154 /// |OsABI|7|OS/ABI identification|
155 /// |AbiVersion|8|ABI version|
156 /// |Pad|9|Start of paddingdbytes|
157 /// |Unassigned|10|Meaningless bytes|
158 /// |Unassigned|11|Meaningless bytes|
159 /// |Unassigned|12|Meaningless bytes|
160 /// |Unassigned|13|Meaningless bytes|
161 /// |Unassigned|14|Meaningless bytes|
162 /// |Unassigned|15|Meaningless bytes|
163 /// |NIdent|16|Size of e_ident[]|
164 pub fn as_array(&self) -> [T; 16] {
165 [
166 self.magic0,
167 self.magic1,
168 self.magic2,
169 self.magic3,
170 self.class,
171 self.endianness,
172 self.version,
173 self.osabi,
174 self.abiversion,
175 self.padding,
176 self.unassigned0,
177 self.unassigned1,
178 self.unassigned2,
179 self.unassigned3,
180 self.unassigned4,
181 self.nident,
182 ]
183 }
184}
185
186impl core::fmt::Display for Identifier {
187 fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
188 write!(
189 formatter,
190 "
191 \tELF Identifier {{
192 Magic0 : {:?},
193 Magic1 : {:?},
194 Magic2 : {:?},
195 Magic3 : {:?},
196 Class : {:?},
197 Endianness : {:?},
198 Version : {:?},
199 Osabi : {:?},
200 Abiversion : {:?},
201 Padding : {:?},
202 Unassigned0 : {:?},
203 Unassigned1 : {:?},
204 Unassigned2 : {:?},
205 Unassigned3 : {:?},
206 Unassigned4 : {:?},
207 Nident : {:?},
208 \t}}
209 ",
210 self.magic0,
211 self.magic1,
212 self.magic2,
213 self.magic3,
214 self.class,
215 self.endianness,
216 self.version,
217 self.osabi,
218 self.abiversion,
219 self.padding,
220 self.unassigned0,
221 self.unassigned1,
222 self.unassigned2,
223 self.unassigned3,
224 self.unassigned4,
225 self.nident,
226 )
227 }
228}
229
230// // impl core::fmt::Debug for Identifier {
231// // fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
232// // f.debug_struct("ELF Header Identifier")
233// // .field(
234// // "Class",
235// // &format!("{} ({})", self.class, self.get_class_str()),
236// // )
237// // .field(
238// // "Data",
239// // &format!("{} ({})", self.endianness, self.get_endianness_str()),
240// // )
241// // .field("Version", &self.copy_version())
242// // .field(
243// // "OS ABI",
244// // &format!("{} ({})", self.osabi, self.get_osabi_str()),
245// // )
246// // .field("ABI version", &self.copy_abi_version())
247// // .field("Padding", &self.copy_padding())
248// // .field("Unused", &self.get_unassigned_str())
249// // .field("NIdent", &self.nident)
250// // .finish()
251// // }
252// // }