Skip to main content

luaur_code_gen/methods/
unwind_builder_dwarf_2_finalize.rs

1use crate::functions::writeu_64::writeu_64;
2use crate::records::unwind_builder_dwarf_2::UnwindBuilderDwarf2;
3use crate::records::unwind_function_dwarf_2::UnwindFunctionDwarf2;
4use core::ffi::c_char;
5
6impl UnwindBuilderDwarf2 {
7    pub fn finalize(
8        &self,
9        target: *mut c_char,
10        offset: usize,
11        func_address: *mut core::ffi::c_void,
12        block_size: usize,
13    ) -> usize {
14        unsafe {
15            core::ptr::copy_nonoverlapping(
16                self.raw_data.as_ptr(),
17                target as *mut u8,
18                self.get_unwind_info_size(block_size),
19            );
20        }
21
22        let k_full_block_function: u32 = u32::MAX;
23        let target_u8 = target as *mut u8;
24
25        // Constants for DWARF FDE offsets
26        const K_FDE_INITIAL_LOCATION_OFFSET: usize = 8;
27        const K_FDE_ADDRESS_RANGE_OFFSET: usize = 16;
28
29        for func in &self.unwind_functions {
30            unsafe {
31                let fde_entry = target_u8.add(func.fde_entry_start_pos as usize);
32
33                writeu_64(
34                    fde_entry.add(K_FDE_INITIAL_LOCATION_OFFSET),
35                    (func_address as usize as u64) + (offset as u64) + (func.begin_offset as u64),
36                );
37
38                let address_range = if func.end_offset == k_full_block_function {
39                    (block_size as u64) - (offset as u64)
40                } else {
41                    (func.end_offset as u64) - (func.begin_offset as u64)
42                };
43
44                write_u_64(fde_entry.add(K_FDE_ADDRESS_RANGE_OFFSET), address_range);
45            }
46        }
47
48        self.unwind_functions.len()
49    }
50}
51
52#[inline(always)]
53unsafe fn write_u_64(target: *mut u8, value: u64) -> *mut u8 {
54    writeu_64(target, value)
55}