@@ -35,11 +35,121 @@ impl UnwindModule<ObjectModule> {
3535impl UnwindModule < cranelift_jit:: JITModule > {
3636 pub ( crate ) fn finalize_definitions ( mut self ) -> cranelift_jit:: JITModule {
3737 self . module . finalize_definitions ( ) . unwrap ( ) ;
38- unsafe { self . unwind_context . register_jit ( & self . module ) } ;
38+ let eh_frame = unsafe { self . unwind_context . register_jit ( & self . module ) } ;
39+
40+ let mut symbol_obj = object:: write:: Object :: new (
41+ object:: BinaryFormat :: Elf ,
42+ object:: Architecture :: Aarch64 ,
43+ object:: Endianness :: Little ,
44+ ) ;
45+ let eh_frame_section = symbol_obj. add_section (
46+ vec ! [ ] ,
47+ b".eh_frame" . to_vec ( ) ,
48+ object:: SectionKind :: ReadOnlyData ,
49+ ) ;
50+ symbol_obj. append_section_data ( eh_frame_section, & eh_frame, 1 ) ;
51+
52+ let mut lowest_symbol = u64:: MAX ;
53+ let mut highest_symbol = u64:: MIN ;
54+ for ( func_id, func_decl) in self . module . declarations ( ) . get_functions ( ) {
55+ if !func_decl. linkage . is_final ( ) {
56+ continue ;
57+ }
58+ let name = func_decl. linkage_name ( func_id) . into_owned ( ) . into_bytes ( ) ;
59+ let addr = self . module . get_finalized_function ( func_id) . addr ( ) as u64 ;
60+ if addr < lowest_symbol {
61+ lowest_symbol = addr;
62+ }
63+ if addr + 1 > highest_symbol {
64+ highest_symbol = addr + 1 ;
65+ }
66+ symbol_obj. add_symbol ( object:: write:: Symbol {
67+ name,
68+ value : addr,
69+ size : 1 ,
70+ kind : object:: write:: SymbolKind :: Text ,
71+ scope : object:: write:: SymbolScope :: Dynamic ,
72+ weak : false ,
73+ section : object:: write:: SymbolSection :: Absolute ,
74+ flags : object:: write:: SymbolFlags :: None ,
75+ } ) ;
76+ }
77+
78+ let mut symbol_obj = symbol_obj. write ( ) . unwrap ( ) ;
79+
80+ convert_object_elf_to_loadable_file :: < object:: LittleEndian > (
81+ & mut symbol_obj,
82+ ( lowest_symbol as * const u8 , ( highest_symbol - lowest_symbol) as usize ) ,
83+ ) ;
84+
85+ std:: fs:: write ( "symbols.elf" , symbol_obj) . unwrap ( ) ;
86+
87+ /*#[unsafe(no_mangle)]
88+ static mut SYMBOL_OBJECT: *mut u8 = std::ptr::null_mut();
89+ unsafe {
90+ SYMBOL_OBJECT = Vec::leak(symbol_obj).as_mut_ptr();
91+ }*/
92+
3993 self . module
4094 }
4195}
4296
97+ #[ cfg( feature = "jit" ) ]
98+ fn convert_object_elf_to_loadable_file < E : object:: Endian > (
99+ bytes : & mut Vec < u8 > ,
100+ code_region : ( * const u8 , usize ) ,
101+ ) {
102+ use object:: elf:: { ET_DYN , ET_EXEC , FileHeader64 , ProgramHeader64 , SectionHeader64 } ;
103+ use object:: read:: elf:: { FileHeader , SectionHeader } ;
104+
105+ let e = E :: default ( ) ;
106+
107+ let header = FileHeader64 :: < E > :: parse ( & bytes[ ..] ) . unwrap ( ) ;
108+ let sections = header. sections ( e, & bytes[ ..] ) . unwrap ( ) ;
109+ let text_range = match sections. section_by_name ( e, b".text" ) {
110+ Some ( ( i, text) ) => {
111+ let range = text. file_range ( e) ;
112+ let e_shoff = usize:: try_from ( header. e_shoff . get ( e) ) . unwrap ( ) ;
113+ let off = e_shoff + i. 0 * header. e_shentsize . get ( e) as usize ;
114+
115+ let section: & mut SectionHeader64 < E > =
116+ object:: from_bytes_mut ( & mut bytes[ off..] ) . unwrap ( ) . 0 ;
117+ // Patch vaddr, and save file location and its size.
118+ section. sh_addr . set ( e, code_region. 0 as u64 ) ;
119+ range
120+ }
121+ None => None ,
122+ } ;
123+
124+ // LLDB wants segment with virtual address set, placing them at the end of ELF.
125+ let ph_off = bytes. len ( ) ;
126+ let e_phentsize = size_of :: < ProgramHeader64 < E > > ( ) ;
127+ let mut e_phnum = 1 ;
128+ bytes. resize ( ph_off + e_phentsize * e_phnum, 0 ) ;
129+ //if let Some((sh_offset, sh_size)) = text_range {
130+ use object:: elf:: PT_LOAD ;
131+
132+ let ( v_offset, size) = code_region;
133+ let program: & mut ProgramHeader64 < E > = object:: from_bytes_mut ( & mut bytes[ ph_off..] ) . unwrap ( ) . 0 ;
134+ program. p_type . set ( e, PT_LOAD ) ;
135+ program. p_offset . set ( e, /*sh_offset*/ 0 ) ;
136+ program. p_vaddr . set ( e, v_offset as u64 ) ;
137+ program. p_paddr . set ( e, v_offset as u64 ) ;
138+ program. p_filesz . set ( e, /*sh_size*/ 0 ) ;
139+ program. p_memsz . set ( e, size as u64 ) ;
140+ /*} else {
141+ //unreachable!();
142+ e_phnum = 0;
143+ }*/
144+
145+ // It is somewhat loadable ELF file at this moment.
146+ let header: & mut FileHeader64 < E > = object:: from_bytes_mut ( bytes) . unwrap ( ) . 0 ;
147+ header. e_type . set ( e, ET_EXEC ) ;
148+ header. e_phoff . set ( e, ph_off as u64 ) ;
149+ header. e_phentsize . set ( e, u16:: try_from ( e_phentsize) . unwrap ( ) ) ;
150+ header. e_phnum . set ( e, u16:: try_from ( e_phnum) . unwrap ( ) ) ;
151+ }
152+
43153impl < T : Module > Module for UnwindModule < T > {
44154 fn isa ( & self ) -> & dyn TargetIsa {
45155 self . module . isa ( )
0 commit comments