1use byteorder::{LittleEndian, ReadBytesExt};
2use gaia_types::{helpers::Architecture, GaiaError};
3use serde::{Deserialize, Serialize};
4use std::io::Read;
5
6#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
11pub struct CoffHeader {
12 pub machine: u16,
14 pub number_of_sections: u16,
16 pub time_date_stamp: u32,
18 pub pointer_to_symbol_table: u32,
20 pub number_of_symbols: u32,
22 pub size_of_optional_header: u16,
24 pub characteristics: u16,
26}
27
28impl CoffHeader {
29 pub fn new(machine: u16, number_of_sections: u16) -> Self {
31 CoffHeader {
32 machine,
33 number_of_sections,
34 time_date_stamp: 0,
35 pointer_to_symbol_table: 0,
36 number_of_symbols: 0,
37 size_of_optional_header: 0,
38 characteristics: 0,
39 }
40 }
41
42 pub fn with_timestamp(mut self, time_date_stamp: u32) -> Self {
44 self.time_date_stamp = time_date_stamp;
45 self
46 }
47
48 pub fn with_symbol_table(mut self, pointer_to_symbol_table: u32, number_of_symbols: u32) -> Self {
50 self.pointer_to_symbol_table = pointer_to_symbol_table;
51 self.number_of_symbols = number_of_symbols;
52 self
53 }
54
55 pub fn with_optional_header_size(mut self, size_of_optional_header: u16) -> Self {
57 self.size_of_optional_header = size_of_optional_header;
58 self
59 }
60
61 pub fn with_characteristics(mut self, characteristics: u16) -> Self {
63 self.characteristics = characteristics;
64 self
65 }
66
67 pub fn read<R: Read>(mut reader: R) -> Result<Self, GaiaError> {
68 Ok(CoffHeader {
69 machine: reader.read_u16::<LittleEndian>()?,
70 number_of_sections: reader.read_u16::<LittleEndian>()?,
71 time_date_stamp: reader.read_u32::<LittleEndian>()?,
72 pointer_to_symbol_table: reader.read_u32::<LittleEndian>()?,
73 number_of_symbols: reader.read_u32::<LittleEndian>()?,
74 size_of_optional_header: reader.read_u16::<LittleEndian>()?,
75 characteristics: reader.read_u16::<LittleEndian>()?,
76 })
77 }
78
79 pub fn get_architecture(&self) -> Architecture {
80 match self.machine {
81 0x014C => Architecture::X86,
82 0x8664 => Architecture::X86_64,
83 0x0200 => Architecture::ARM32,
84 0xAA64 => Architecture::ARM64,
85 _ => Architecture::Unknown,
86 }
87 }
88}
89
90#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
95pub struct SectionHeader {
96 pub name: [u8; 8],
98 pub virtual_size: u32,
100 pub virtual_address: u32,
102 pub size_of_raw_data: u32,
104 pub pointer_to_raw_data: u32,
106 pub pointer_to_relocations: u32,
108 pub pointer_to_line_numbers: u32,
110 pub number_of_relocations: u16,
112 pub number_of_line_numbers: u16,
114 pub characteristics: u32,
116}
117
118#[derive(Clone, Debug, Serialize, Deserialize)]
123pub struct CoffSymbol {
124 pub name: String,
126 pub value: u32,
128 pub section_number: i16,
130 pub symbol_type: u16,
132 pub storage_class: u8,
134 pub number_of_aux_symbols: u8,
136}
137
138#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
143pub struct CoffRelocation {
144 pub virtual_address: u32,
146 pub symbol_table_index: u32,
148 pub relocation_type: u16,
150}
151
152#[derive(Clone, Debug, Serialize, Deserialize)]
157pub struct CoffSection {
158 pub header: SectionHeader,
160 #[serde(skip_serializing_if = "Vec::is_empty")]
162 pub data: Vec<u8>,
163 pub relocations: Vec<CoffRelocation>,
165}
166
167#[derive(Clone, Debug, Serialize, Deserialize)]
172pub struct CoffObject {
173 pub header: CoffHeader,
175 pub sections: Vec<CoffSection>,
177 pub symbols: Vec<CoffSymbol>,
179 pub string_table: Vec<u8>,
181}
182
183#[derive(Clone, Debug, Serialize, Deserialize)]
188pub struct ArchiveMemberHeader {
189 pub name: String,
191 pub timestamp: u32,
193 pub user_id: u16,
195 pub group_id: u16,
197 pub mode: u32,
199 pub size: u32,
201}
202
203#[derive(Clone, Debug, Serialize, Deserialize)]
208pub struct ArchiveMember {
209 pub header: ArchiveMemberHeader,
211 pub data: Vec<u8>,
213 pub coff_object: Option<CoffObject>,
215}
216
217#[derive(Clone, Debug, Serialize, Deserialize)]
222pub struct StaticLibrary {
223 pub signature: String,
225 pub members: Vec<ArchiveMember>,
227 pub symbol_index: Vec<(String, usize)>, }
230
231#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
235pub enum CoffFileType {
236 Object,
238 StaticLibrary,
240 Executable,
242 DynamicLibrary,
244}
245
246#[derive(Clone, Debug, Serialize, Deserialize)]
250pub struct CoffInfo {
251 pub file_type: CoffFileType,
253 pub target_arch: Architecture,
255 pub section_count: u16,
257 pub symbol_count: u32,
259 pub file_size: u64,
261 pub timestamp: u32,
263}