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// // }