ghostscope_compiler/ebpf/codegen/
expr_error.rs1use super::*;
2
3impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
4 pub fn generate_expr_error(
6 &mut self,
7 expr_string_index: u16,
8 error_code_iv: inkwell::values::IntValue<'ctx>,
9 flags_iv: inkwell::values::IntValue<'ctx>,
10 failing_addr_iv: inkwell::values::IntValue<'ctx>,
11 ) -> Result<()> {
12 let inst_buffer = self
14 .reserve_instruction_region_or_return_zero(
15 (INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_SIZE) as u64,
16 )?
17 .into_value_after_runtime_returns();
18
19 let inst_type_val = self
21 .context
22 .i8_type()
23 .const_int(InstructionType::ExprError as u64, false);
24 self.builder
25 .build_store(inst_buffer, inst_type_val)
26 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store inst_type: {e}")))?;
27
28 let data_length_ptr = unsafe {
32 self.builder
33 .build_gep(
34 self.context.i8_type(),
35 inst_buffer,
36 &[self
37 .context
38 .i32_type()
39 .const_int(INSTRUCTION_HEADER_DATA_LENGTH_OFFSET as u64, false)],
40 "exprerr_data_length_ptr",
41 )
42 .map_err(|e| {
43 CodeGenError::LLVMError(format!("Failed to get data_length GEP: {e}"))
44 })?
45 };
46 let data_length_i16_ptr = self
47 .builder
48 .build_pointer_cast(
49 data_length_ptr,
50 self.context.ptr_type(AddressSpace::default()),
51 "exprerr_data_length_i16_ptr",
52 )
53 .map_err(|e| CodeGenError::LLVMError(format!("Failed to cast data_length ptr: {e}")))?;
54 let data_length_val = self
55 .context
56 .i16_type()
57 .const_int(EXPR_ERROR_DATA_SIZE as u64, false);
58 self.builder
59 .build_store(data_length_i16_ptr, data_length_val)
60 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store data_length: {e}")))?;
61
62 let si_ptr = unsafe {
66 self.builder
67 .build_gep(
68 self.context.i8_type(),
69 inst_buffer,
70 &[self.context.i32_type().const_int(
71 (INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_STRING_INDEX_OFFSET) as u64,
72 false,
73 )],
74 "exprerr_si_ptr",
75 )
76 .map_err(|e| {
77 CodeGenError::LLVMError(format!("Failed to get string_index GEP: {e}"))
78 })?
79 };
80 let si_i16_ptr = self
81 .builder
82 .build_pointer_cast(
83 si_ptr,
84 self.context.ptr_type(AddressSpace::default()),
85 "exprerr_si_i16_ptr",
86 )
87 .map_err(|e| {
88 CodeGenError::LLVMError(format!("Failed to cast string_index ptr: {e}"))
89 })?;
90 let si_val = self
91 .context
92 .i16_type()
93 .const_int(expr_string_index as u64, false);
94 self.builder
95 .build_store(si_i16_ptr, si_val)
96 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store string_index: {e}")))?;
97
98 let ec_ptr = unsafe {
100 self.builder
101 .build_gep(
102 self.context.i8_type(),
103 inst_buffer,
104 &[self.context.i32_type().const_int(
105 (INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_ERROR_CODE_OFFSET) as u64,
106 false,
107 )],
108 "exprerr_ec_ptr",
109 )
110 .map_err(|e| {
111 CodeGenError::LLVMError(format!("Failed to get error_code GEP: {e}"))
112 })?
113 };
114 let ec_i8 = if error_code_iv.get_type().get_bit_width() == 8 {
116 error_code_iv
117 } else if error_code_iv.get_type().get_bit_width() > 8 {
118 self.builder
119 .build_int_truncate(error_code_iv, self.context.i8_type(), "ec_trunc")
120 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
121 } else {
122 self.builder
123 .build_int_z_extend(error_code_iv, self.context.i8_type(), "ec_zext")
124 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
125 };
126 self.builder
127 .build_store(ec_ptr, ec_i8)
128 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store error_code: {e}")))?;
129 let fl_ptr = unsafe {
131 self.builder
132 .build_gep(
133 self.context.i8_type(),
134 inst_buffer,
135 &[self.context.i32_type().const_int(
136 (INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_FLAGS_OFFSET) as u64,
137 false,
138 )],
139 "exprerr_flags_ptr",
140 )
141 .map_err(|e| CodeGenError::LLVMError(format!("Failed to get flags GEP: {e}")))?
142 };
143 let fl_i8 = if flags_iv.get_type().get_bit_width() == 8 {
145 flags_iv
146 } else if flags_iv.get_type().get_bit_width() > 8 {
147 self.builder
148 .build_int_truncate(flags_iv, self.context.i8_type(), "fl_trunc")
149 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
150 } else {
151 self.builder
152 .build_int_z_extend(flags_iv, self.context.i8_type(), "fl_zext")
153 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
154 };
155 self.builder
156 .build_store(fl_ptr, fl_i8)
157 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store flags: {e}")))?;
158
159 let addr_ptr = unsafe {
161 self.builder
162 .build_gep(
163 self.context.i8_type(),
164 inst_buffer,
165 &[self.context.i32_type().const_int(
166 (INSTRUCTION_HEADER_SIZE + EXPR_ERROR_DATA_FAILING_ADDR_OFFSET) as u64,
167 false,
168 )],
169 "exprerr_addr_ptr",
170 )
171 .map_err(|e| CodeGenError::LLVMError(format!("Failed to get addr GEP: {e}")))?
172 };
173 let addr_i64 = if failing_addr_iv.get_type().get_bit_width() == 64 {
174 failing_addr_iv
175 } else if failing_addr_iv.get_type().get_bit_width() > 64 {
176 self.builder
177 .build_int_truncate(failing_addr_iv, self.context.i64_type(), "addr_trunc")
178 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
179 } else {
180 self.builder
181 .build_int_z_extend(failing_addr_iv, self.context.i64_type(), "addr_zext")
182 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?
183 };
184 let addr_ptr_cast = self
185 .builder
186 .build_pointer_cast(
187 addr_ptr,
188 self.context.ptr_type(AddressSpace::default()),
189 "exprerr_addr_i64_ptr",
190 )
191 .map_err(|e| CodeGenError::LLVMError(e.to_string()))?;
192 self.builder
193 .build_store(addr_ptr_cast, addr_i64)
194 .map_err(|e| CodeGenError::LLVMError(format!("Failed to store failing_addr: {e}")))?;
195
196 Ok(())
198 }
199}