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
118impl SectionHeader {
119 pub fn get_name(&self) -> &str {
120 unsafe {
121 let name = str::from_utf8_unchecked(&self.name);
122 name.trim_end_matches('\0')
123 }
124 }
125}
126
127#[derive(Clone, Debug, Serialize, Deserialize)]
132pub struct CoffSymbol {
133 pub name: String,
135 pub value: u32,
137 pub section_number: i16,
139 pub symbol_type: u16,
141 pub storage_class: u8,
143 pub number_of_aux_symbols: u8,
145}
146
147#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
152pub struct CoffRelocation {
153 pub virtual_address: u32,
155 pub symbol_table_index: u32,
157 pub relocation_type: u16,
159}
160
161#[derive(Clone, Debug, Serialize, Deserialize)]
166pub struct CoffSection {
167 pub header: SectionHeader,
169 #[serde(skip_serializing_if = "Vec::is_empty")]
171 pub data: Vec<u8>,
172 pub relocations: Vec<CoffRelocation>,
174}
175
176#[derive(Clone, Debug, Serialize, Deserialize)]
181pub struct CoffObject {
182 pub header: CoffHeader,
184 pub sections: Vec<CoffSection>,
186 pub symbols: Vec<CoffSymbol>,
188 pub string_table: Vec<u8>,
190}
191
192#[derive(Clone, Debug, Serialize, Deserialize)]
197pub struct ArchiveMemberHeader {
198 pub name: String,
200 pub timestamp: u32,
202 pub user_id: u16,
204 pub group_id: u16,
206 pub mode: u32,
208 pub size: u32,
210}
211
212#[derive(Clone, Debug, Serialize, Deserialize)]
217pub struct ArchiveMember {
218 pub header: ArchiveMemberHeader,
220 pub data: Vec<u8>,
222 pub coff_object: Option<CoffObject>,
224}
225
226#[derive(Clone, Debug, Serialize, Deserialize)]
231pub struct StaticLibrary {
232 pub signature: String,
234 pub members: Vec<ArchiveMember>,
236 pub symbol_index: Vec<(String, usize)>, }
239
240#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
244pub enum CoffFileType {
245 Object,
247 StaticLibrary,
249 Executable,
251 DynamicLibrary,
253}
254
255#[derive(Clone, Debug, Serialize, Deserialize)]
259pub struct CoffInfo {
260 pub file_type: CoffFileType,
262 pub target_arch: Architecture,
264 pub section_count: u16,
266 pub symbol_count: u32,
268 pub file_size: u64,
270 pub timestamp: u32,
272}