elf_assembler/assembler/x64/
context.rs

1//! X64 代码生成上下文管理
2//!
3//! 提供 X64 代码生成过程中的状态管理和上下文跟踪
4
5use std::collections::HashMap;
6
7/// X64 寄存器枚举
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum X64Register {
10    // 64位通用寄存器
11    RAX,
12    RBX,
13    RCX,
14    RDX,
15    RSI,
16    RDI,
17    RBP,
18    RSP,
19    R8,
20    R9,
21    R10,
22    R11,
23    R12,
24    R13,
25    R14,
26    R15,
27
28    // 32位寄存器
29    EAX,
30    EBX,
31    ECX,
32    EDX,
33    ESI,
34    EDI,
35    EBP,
36    ESP,
37    /// R8D 32位寄存器
38    R8D,
39    /// R9D 32位寄存器
40    R9D,
41    /// R10D 32位寄存器
42    R10D,
43    /// R11D 32位寄存器
44    R11D,
45    /// R12D 32位寄存器
46    R12D,
47    /// R13D 32位寄存器
48    R13D,
49    /// R14D 32位寄存器
50    R14D,
51    /// R15D 32位寄存器
52    R15D,
53}
54
55/// 标签信息
56#[derive(Debug, Clone)]
57pub struct Label {
58    /// 标签名称
59    pub name: String,
60    /// 标签在代码中的偏移(如果已定义)
61    pub offset: Option<usize>,
62    /// 需要回填的位置列表
63    pub fixup_locations: Vec<usize>,
64}
65
66/// 重定位信息
67#[derive(Debug, Clone)]
68pub struct RelocationInfo {
69    /// 重定位位置
70    pub offset: usize,
71    /// 重定位类型
72    pub reloc_type: RelocationType,
73    /// 目标符号
74    pub symbol: String,
75}
76
77/// 重定位类型
78#[derive(Debug, Clone, Copy)]
79pub enum RelocationType {
80    /// 32位相对地址
81    Rel32,
82    /// 64位绝对地址
83    Abs64,
84    /// RIP相对地址
85    RipRel32,
86}
87
88/// 函数调用信息
89#[derive(Debug, Clone)]
90pub struct FunctionCall {
91    /// 函数名
92    pub name: String,
93    /// 调用位置
94    pub call_offset: usize,
95    /// 是否为导入函数
96    pub is_import: bool,
97}
98
99/// X64 代码生成上下文
100#[derive(Debug)]
101pub struct X64Context {
102    /// 生成的机器码
103    pub code: Vec<u8>,
104
105    /// 当前栈偏移(相对于 RBP)
106    pub stack_offset: i32,
107
108    /// 标签管理
109    pub labels: HashMap<String, Label>,
110
111    /// 重定位信息
112    pub relocations: Vec<RelocationInfo>,
113
114    /// 函数调用信息
115    pub function_calls: Vec<FunctionCall>,
116
117    /// 字符串常量表
118    pub string_constants: HashMap<String, usize>,
119
120    /// 寄存器使用状态
121    pub register_usage: HashMap<X64Register, bool>,
122
123    /// 当前函数的栈空间大小
124    pub stack_size: u32,
125}
126
127impl X64Context {
128    /// 创建新的上下文
129    pub fn new() -> Self {
130        Self {
131            code: Vec::new(),
132            stack_offset: 0,
133            labels: HashMap::new(),
134            relocations: Vec::new(),
135            function_calls: Vec::new(),
136            string_constants: HashMap::new(),
137            register_usage: HashMap::new(),
138            stack_size: 0,
139        }
140    }
141
142    /// 添加机器码字节
143    pub fn emit_bytes(&mut self, bytes: &[u8]) {
144        self.code.extend_from_slice(bytes);
145    }
146
147    /// 获取当前代码位置
148    pub fn current_position(&self) -> usize {
149        self.code.len()
150    }
151
152    /// 定义标签
153    pub fn define_label(&mut self, name: &str) {
154        let offset = self.current_position();
155
156        if let Some(label) = self.labels.get_mut(name) {
157            // 标签已存在,设置偏移并回填
158            label.offset = Some(offset);
159            self.fixup_label(name, offset);
160        }
161        else {
162            // 新标签
163            self.labels
164                .insert(name.to_string(), Label { name: name.to_string(), offset: Some(offset), fixup_locations: Vec::new() });
165        }
166    }
167
168    /// 引用标签(用于跳转指令)
169    pub fn reference_label(&mut self, name: &str) -> usize {
170        let current_pos = self.current_position();
171
172        if let Some(label) = self.labels.get_mut(name) {
173            if let Some(offset) = label.offset {
174                // 标签已定义,计算相对偏移
175                return self.calculate_relative_offset(current_pos, offset);
176            }
177            else {
178                // 标签未定义,记录需要回填的位置
179                label.fixup_locations.push(current_pos);
180            }
181        }
182        else {
183            // 新的未定义标签
184            let label = Label { name: name.to_string(), offset: None, fixup_locations: vec![current_pos] };
185            self.labels.insert(name.to_string(), label);
186        }
187
188        0 // 返回占位符
189    }
190
191    /// 回填标签引用
192    fn fixup_label(&mut self, name: &str, label_offset: usize) {
193        if let Some(label) = self.labels.get_mut(name) {
194            // 先收集需要回填的位置,避免借用冲突
195            let fixup_positions: Vec<usize> = label.fixup_locations.clone();
196
197            for fixup_pos in fixup_positions {
198                let relative_offset = self.calculate_relative_offset(fixup_pos, label_offset);
199                // 回填4字节相对偏移
200                let bytes = (relative_offset as i32).to_le_bytes();
201                for (i, &byte) in bytes.iter().enumerate() {
202                    if fixup_pos + i < self.code.len() {
203                        self.code[fixup_pos + i] = byte;
204                    }
205                }
206            }
207
208            // 清空回填位置列表
209            if let Some(label) = self.labels.get_mut(name) {
210                label.fixup_locations.clear();
211            }
212        }
213    }
214
215    /// 计算相对偏移
216    fn calculate_relative_offset(&self, from: usize, to: usize) -> usize {
217        if to >= from {
218            to - from
219        }
220        else {
221            // 向后跳转,需要处理负偏移
222            0 // 简化处理
223        }
224    }
225
226    /// 分配栈空间
227    pub fn allocate_stack(&mut self, size: u32) -> i32 {
228        self.stack_offset -= size as i32;
229        self.stack_size = self.stack_size.max((-self.stack_offset) as u32);
230        self.stack_offset
231    }
232
233    /// 添加字符串常量
234    pub fn add_string_constant(&mut self, value: &str) -> usize {
235        if let Some(&offset) = self.string_constants.get(value) {
236            offset
237        }
238        else {
239            let offset = self.string_constants.len() * 8; // 简化的偏移计算
240            self.string_constants.insert(value.to_string(), offset);
241            offset
242        }
243    }
244
245    /// 添加函数调用
246    pub fn add_function_call(&mut self, name: &str, is_import: bool) {
247        let call_offset = self.current_position();
248        self.function_calls.push(FunctionCall { name: name.to_string(), call_offset, is_import });
249    }
250
251    /// 添加重定位信息
252    pub fn add_relocation(&mut self, reloc_type: RelocationType, symbol: &str) {
253        let offset = self.current_position();
254        self.relocations.push(RelocationInfo { offset, reloc_type, symbol: symbol.to_string() });
255    }
256}
257
258impl Default for X64Context {
259    fn default() -> Self {
260        Self::new()
261    }
262}