elf_assembler/types/
mod.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// ELF 文件类型枚举
5///
6/// 定义了 ELF 文件的不同类型,决定了文件的用途和加载方式。
7#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
8pub enum ElfType {
9    /// 无类型文件
10    None,
11    /// 可重定位文件(目标文件)
12    Relocatable,
13    /// 可执行文件
14    Executable,
15    /// 共享目标文件(动态库)
16    SharedObject,
17    /// 核心转储文件
18    Core,
19}
20
21impl fmt::Display for ElfType {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        match self {
24            ElfType::None => write!(f, "无类型文件"),
25            ElfType::Relocatable => write!(f, "可重定位文件"),
26            ElfType::Executable => write!(f, "可执行文件"),
27            ElfType::SharedObject => write!(f, "共享目标文件"),
28            ElfType::Core => write!(f, "核心转储文件"),
29        }
30    }
31}
32
33impl From<u16> for ElfType {
34    fn from(value: u16) -> Self {
35        match value {
36            0 => ElfType::None,
37            1 => ElfType::Relocatable,
38            2 => ElfType::Executable,
39            3 => ElfType::SharedObject,
40            4 => ElfType::Core,
41            _ => ElfType::None,
42        }
43    }
44}
45
46/// ELF 机器类型枚举
47///
48/// 定义了 ELF 文件支持的处理器架构类型。
49#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
50pub enum ElfMachine {
51    /// 无机器类型
52    None,
53    /// Intel 80386
54    I386,
55    /// AMD x86-64
56    X86_64,
57    /// ARM
58    Arm,
59    /// AArch64
60    AArch64,
61    /// RISC-V
62    RiscV,
63}
64
65impl From<u16> for ElfMachine {
66    fn from(value: u16) -> Self {
67        match value {
68            0 => ElfMachine::None,
69            3 => ElfMachine::I386,
70            62 => ElfMachine::X86_64,
71            40 => ElfMachine::Arm,
72            183 => ElfMachine::AArch64,
73            243 => ElfMachine::RiscV,
74            _ => ElfMachine::None,
75        }
76    }
77}
78
79/// ELF 头结构(64位)
80///
81/// ELF 文件的主要头部结构,包含文件的基本信息和元数据。
82/// 这是 ELF 文件的第一个结构,用于标识文件格式和基本属性。
83#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
84pub struct ElfHeader64 {
85    /// ELF 魔数和标识信息 (16 字节)
86    pub e_ident: [u8; 16],
87    /// 文件类型
88    pub e_type: u16,
89    /// 机器架构
90    pub e_machine: u16,
91    /// 文件版本
92    pub e_version: u32,
93    /// 程序入口点地址
94    pub e_entry: u64,
95    /// 程序头表偏移
96    pub e_phoff: u64,
97    /// 节头表偏移
98    pub e_shoff: u64,
99    /// 处理器特定标志
100    pub e_flags: u32,
101    /// ELF 头大小
102    pub e_ehsize: u16,
103    /// 程序头表项大小
104    pub e_phentsize: u16,
105    /// 程序头表项数量
106    pub e_phnum: u16,
107    /// 节头表项大小
108    pub e_shentsize: u16,
109    /// 节头表项数量
110    pub e_shnum: u16,
111    /// 字符串表索引
112    pub e_shstrndx: u16,
113}
114
115/// ELF 程序头结构(64位)
116///
117/// 描述程序段的信息,用于程序加载时的内存布局。
118#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
119pub struct ProgramHeader64 {
120    /// 段类型
121    pub p_type: u32,
122    /// 段标志
123    pub p_flags: u32,
124    /// 段在文件中的偏移
125    pub p_offset: u64,
126    /// 段的虚拟地址
127    pub p_vaddr: u64,
128    /// 段的物理地址
129    pub p_paddr: u64,
130    /// 段在文件中的大小
131    pub p_filesz: u64,
132    /// 段在内存中的大小
133    pub p_memsz: u64,
134    /// 段对齐
135    pub p_align: u64,
136}
137
138/// ELF 节头结构(64位)
139///
140/// 描述文件中各个节的信息,用于链接和调试。
141#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
142pub struct SectionHeader64 {
143    /// 节名称(字符串表索引)
144    pub sh_name: u32,
145    /// 节类型
146    pub sh_type: u32,
147    /// 节标志
148    pub sh_flags: u64,
149    /// 节的虚拟地址
150    pub sh_addr: u64,
151    /// 节在文件中的偏移
152    pub sh_offset: u64,
153    /// 节的大小
154    pub sh_size: u64,
155    /// 节头表索引链接
156    pub sh_link: u32,
157    /// 附加信息
158    pub sh_info: u32,
159    /// 节对齐
160    pub sh_addralign: u64,
161    /// 节项大小
162    pub sh_entsize: u64,
163}
164
165/// ELF 程序段类型常量
166pub mod segment_type {
167    /// 空段
168    pub const PT_NULL: u32 = 0;
169    /// 可加载段
170    pub const PT_LOAD: u32 = 1;
171    /// 动态链接信息
172    pub const PT_DYNAMIC: u32 = 2;
173    /// 解释器路径
174    pub const PT_INTERP: u32 = 3;
175    /// 注释信息
176    pub const PT_NOTE: u32 = 4;
177    /// 保留
178    pub const PT_SHLIB: u32 = 5;
179    /// 程序头表
180    pub const PT_PHDR: u32 = 6;
181    /// 线程本地存储
182    pub const PT_TLS: u32 = 7;
183}
184
185/// ELF 节类型常量
186pub mod section_type {
187    /// 空节
188    pub const SHT_NULL: u32 = 0;
189    /// 程序数据
190    pub const SHT_PROGBITS: u32 = 1;
191    /// 符号表
192    pub const SHT_SYMTAB: u32 = 2;
193    /// 字符串表
194    pub const SHT_STRTAB: u32 = 3;
195    /// 重定位表(带加数)
196    pub const SHT_RELA: u32 = 4;
197    /// 哈希表
198    pub const SHT_HASH: u32 = 5;
199    /// 动态链接信息
200    pub const SHT_DYNAMIC: u32 = 6;
201    /// 注释
202    pub const SHT_NOTE: u32 = 7;
203    /// 无数据的程序空间
204    pub const SHT_NOBITS: u32 = 8;
205    /// 重定位表(不带加数)
206    pub const SHT_REL: u32 = 9;
207    /// 保留
208    pub const SHT_SHLIB: u32 = 10;
209    /// 动态符号表
210    pub const SHT_DYNSYM: u32 = 11;
211}
212
213/// ELF 段标志常量
214pub mod segment_flags {
215    /// 可执行
216    pub const PF_X: u32 = 1;
217    /// 可写
218    pub const PF_W: u32 = 2;
219    /// 可读
220    pub const PF_R: u32 = 4;
221}
222
223/// ELF 节标志常量
224pub mod section_flags {
225    /// 可写
226    pub const SHF_WRITE: u64 = 1;
227    /// 占用内存
228    pub const SHF_ALLOC: u64 = 2;
229    /// 可执行
230    pub const SHF_EXECINSTR: u64 = 4;
231}
232
233impl ElfHeader64 {
234    /// 创建一个标准的 ELF64 头
235    pub fn new() -> Self {
236        let mut e_ident = [0u8; 16];
237        // ELF 魔数
238        e_ident[0] = 0x7f;
239        e_ident[1] = b'E';
240        e_ident[2] = b'L';
241        e_ident[3] = b'F';
242        // 64位
243        e_ident[4] = 2;
244        // 小端序
245        e_ident[5] = 1;
246        // 当前版本
247        e_ident[6] = 1;
248        // System V ABI
249        e_ident[7] = 0;
250
251        Self {
252            e_ident,
253            e_type: 2,     // ET_EXEC
254            e_machine: 62, // EM_X86_64
255            e_version: 1,
256            e_entry: 0x401000, // 默认入口点
257            e_phoff: 64,       // 程序头表偏移
258            e_shoff: 0,        // 节头表偏移(暂时为0)
259            e_flags: 0,
260            e_ehsize: 64,    // ELF头大小
261            e_phentsize: 56, // 程序头表项大小
262            e_phnum: 1,      // 程序头表项数量
263            e_shentsize: 64, // 节头表项大小
264            e_shnum: 0,      // 节头表项数量
265            e_shstrndx: 0,   // 字符串表索引
266        }
267    }
268}
269
270impl Default for ElfHeader64 {
271    fn default() -> Self {
272        Self::new()
273    }
274}
275
276impl ProgramHeader64 {
277    /// 创建一个可加载的代码段
278    pub fn new_load_segment(offset: u64, vaddr: u64, size: u64) -> Self {
279        Self {
280            p_type: segment_type::PT_LOAD,
281            p_flags: segment_flags::PF_R | segment_flags::PF_X, // 可读可执行
282            p_offset: offset,
283            p_vaddr: vaddr,
284            p_paddr: vaddr,
285            p_filesz: size,
286            p_memsz: size,
287            p_align: 0x1000, // 4KB 对齐
288        }
289    }
290}
291
292/// ELF 文件构建器
293///
294/// 用于构建完整的 ELF 文件结构
295#[derive(Debug, Clone)]
296pub struct ElfFile {
297    /// ELF 头
298    pub header: ElfHeader64,
299    /// 程序头表
300    pub program_headers: Vec<ProgramHeader64>,
301    /// 节头表
302    pub section_headers: Vec<SectionHeader64>,
303    /// 文件数据
304    pub data: Vec<u8>,
305}
306
307impl ElfFile {
308    /// 创建新的 ELF 文件
309    pub fn new() -> Self {
310        Self { header: ElfHeader64::new(), program_headers: Vec::new(), section_headers: Vec::new(), data: Vec::new() }
311    }
312
313    /// 添加程序头
314    pub fn add_program_header(&mut self, header: ProgramHeader64) {
315        self.program_headers.push(header);
316        self.header.e_phnum = self.program_headers.len() as u16;
317    }
318
319    /// 设置入口点
320    pub fn set_entry_point(&mut self, entry: u64) {
321        self.header.e_entry = entry;
322    }
323
324    /// 生成完整的 ELF 文件字节数组
325    pub fn to_bytes(&self) -> Vec<u8> {
326        let mut bytes = Vec::new();
327
328        // 写入 ELF 头
329        bytes.extend_from_slice(&self.header_to_bytes());
330
331        // 写入程序头表
332        for ph in &self.program_headers {
333            bytes.extend_from_slice(&self.program_header_to_bytes(ph));
334        }
335
336        // 对齐到页边界
337        while bytes.len() % 0x1000 != 0 {
338            bytes.push(0);
339        }
340
341        // 写入数据
342        bytes.extend_from_slice(&self.data);
343
344        bytes
345    }
346
347    /// 将 ELF 头转换为字节数组
348    fn header_to_bytes(&self) -> [u8; 64] {
349        let mut bytes = [0u8; 64];
350        let h = &self.header;
351
352        bytes[0..16].copy_from_slice(&h.e_ident);
353        bytes[16..18].copy_from_slice(&h.e_type.to_le_bytes());
354        bytes[18..20].copy_from_slice(&h.e_machine.to_le_bytes());
355        bytes[20..24].copy_from_slice(&h.e_version.to_le_bytes());
356        bytes[24..32].copy_from_slice(&h.e_entry.to_le_bytes());
357        bytes[32..40].copy_from_slice(&h.e_phoff.to_le_bytes());
358        bytes[40..48].copy_from_slice(&h.e_shoff.to_le_bytes());
359        bytes[48..52].copy_from_slice(&h.e_flags.to_le_bytes());
360        bytes[52..54].copy_from_slice(&h.e_ehsize.to_le_bytes());
361        bytes[54..56].copy_from_slice(&h.e_phentsize.to_le_bytes());
362        bytes[56..58].copy_from_slice(&h.e_phnum.to_le_bytes());
363        bytes[58..60].copy_from_slice(&h.e_shentsize.to_le_bytes());
364        bytes[60..62].copy_from_slice(&h.e_shnum.to_le_bytes());
365        bytes[62..64].copy_from_slice(&h.e_shstrndx.to_le_bytes());
366
367        bytes
368    }
369
370    /// 将程序头转换为字节数组
371    fn program_header_to_bytes(&self, ph: &ProgramHeader64) -> [u8; 56] {
372        let mut bytes = [0u8; 56];
373
374        bytes[0..4].copy_from_slice(&ph.p_type.to_le_bytes());
375        bytes[4..8].copy_from_slice(&ph.p_flags.to_le_bytes());
376        bytes[8..16].copy_from_slice(&ph.p_offset.to_le_bytes());
377        bytes[16..24].copy_from_slice(&ph.p_vaddr.to_le_bytes());
378        bytes[24..32].copy_from_slice(&ph.p_paddr.to_le_bytes());
379        bytes[32..40].copy_from_slice(&ph.p_filesz.to_le_bytes());
380        bytes[40..48].copy_from_slice(&ph.p_memsz.to_le_bytes());
381        bytes[48..56].copy_from_slice(&ph.p_align.to_le_bytes());
382
383        bytes
384    }
385}
386
387impl Default for ElfFile {
388    fn default() -> Self {
389        Self::new()
390    }
391}