@@ -61,45 +61,50 @@ impl UnwindContext {
6161 } ;
6262
6363 cie. fde_address_encoding = ptr_encoding;
64- cie. lsda_encoding = Some ( ptr_encoding) ;
65-
66- // FIXME use eh_personality lang item instead
67- let personality = module
68- . declare_function (
69- "rust_eh_personality" ,
70- Linkage :: Import ,
71- & Signature {
72- params : vec ! [
73- AbiParam :: new( types:: I32 ) ,
74- AbiParam :: new( types:: I32 ) ,
75- AbiParam :: new( types:: I64 ) ,
76- AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
77- AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
78- ] ,
79- returns : vec ! [ AbiParam :: new( types:: I32 ) ] ,
80- call_conv : module. target_config ( ) . default_call_conv ,
81- } ,
82- )
83- . unwrap ( ) ;
84-
85- // Use indirection here to support PIC the case where rust_eh_personality is defined in
86- // another DSO.
87- let personality_ref = module
88- . declare_data ( "DW.ref.rust_eh_personality" , Linkage :: Local , false , false )
89- . unwrap ( ) ;
90-
91- let mut personality_ref_data = DataDescription :: new ( ) ;
92- // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
93- // section.
94- let pointer_bytes = usize:: from ( module. target_config ( ) . pointer_bytes ( ) ) ;
95- personality_ref_data. define ( vec ! [ 0 ; pointer_bytes] . into_boxed_slice ( ) ) ;
96- let personality_func_ref =
97- module. declare_func_in_data ( personality, & mut personality_ref_data) ;
98- personality_ref_data. write_function_addr ( 0 , personality_func_ref) ;
99-
100- module. define_data ( personality_ref, & personality_ref_data) . unwrap ( ) ;
101-
102- cie. personality = Some ( ( code_ptr_encoding, address_for_data ( personality_ref) ) ) ;
64+
65+ // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
66+ if cfg ! ( feature = "unwinding" ) {
67+ cie. lsda_encoding = Some ( ptr_encoding) ;
68+
69+ // FIXME use eh_personality lang item instead
70+ let personality = module
71+ . declare_function (
72+ "rust_eh_personality" ,
73+ Linkage :: Import ,
74+ & Signature {
75+ params : vec ! [
76+ AbiParam :: new( types:: I32 ) ,
77+ AbiParam :: new( types:: I32 ) ,
78+ AbiParam :: new( types:: I64 ) ,
79+ AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
80+ AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
81+ ] ,
82+ returns : vec ! [ AbiParam :: new( types:: I32 ) ] ,
83+ call_conv : module. target_config ( ) . default_call_conv ,
84+ } ,
85+ )
86+ . unwrap ( ) ;
87+
88+ // Use indirection here to support PIC the case where rust_eh_personality is defined in
89+ // another DSO.
90+ let personality_ref = module
91+ . declare_data ( "DW.ref.rust_eh_personality" , Linkage :: Local , false , false )
92+ . unwrap ( ) ;
93+
94+ let mut personality_ref_data = DataDescription :: new ( ) ;
95+ // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
96+ // section.
97+ let pointer_bytes = usize:: from ( module. target_config ( ) . pointer_bytes ( ) ) ;
98+ personality_ref_data. define ( vec ! [ 0 ; pointer_bytes] . into_boxed_slice ( ) ) ;
99+ let personality_func_ref =
100+ module. declare_func_in_data ( personality, & mut personality_ref_data) ;
101+ personality_ref_data. write_function_addr ( 0 , personality_func_ref) ;
102+
103+ module. define_data ( personality_ref, & personality_ref_data) . unwrap ( ) ;
104+
105+ cie. personality = Some ( ( code_ptr_encoding, address_for_data ( personality_ref) ) ) ;
106+ }
107+
103108 Some ( frame_table. add_cie ( cie) )
104109 } else {
105110 None
@@ -135,89 +140,94 @@ impl UnwindContext {
135140 match unwind_info {
136141 UnwindInfo :: SystemV ( unwind_info) => {
137142 let mut fde = unwind_info. to_fde ( address_for_func ( func_id) ) ;
138- // FIXME use unique symbol name derived from function name
139- let lsda = module. declare_anonymous_data ( false , false ) . unwrap ( ) ;
140-
141- let encoding = Encoding {
142- format : Format :: Dwarf32 ,
143- version : 1 ,
144- address_size : module. isa ( ) . frontend_config ( ) . pointer_bytes ( ) ,
145- } ;
146-
147- let mut gcc_except_table_data = GccExceptTable {
148- call_sites : CallSiteTable ( vec ! [ ] ) ,
149- actions : ActionTable :: new ( ) ,
150- type_info : TypeInfoTable :: new ( gimli:: DW_EH_PE_udata4 ) ,
151- exception_specs : ExceptionSpecTable :: new ( ) ,
152- } ;
153-
154- let catch_type = gcc_except_table_data. type_info . add ( Address :: Constant ( 0 ) ) ;
155- let catch_action = gcc_except_table_data
156- . actions
157- . add ( Action { kind : ActionKind :: Catch ( catch_type) , next_action : None } ) ;
158-
159- for call_site in context. compiled_code ( ) . unwrap ( ) . buffer . call_sites ( ) {
160- if call_site. exception_handlers . is_empty ( ) {
161- gcc_except_table_data. call_sites . 0 . push ( CallSite {
162- start : u64:: from ( call_site. ret_addr - 1 ) ,
163- length : 1 ,
164- landing_pad : 0 ,
165- action_entry : None ,
166- } ) ;
167- }
168- for & ( tag, landingpad) in call_site. exception_handlers {
169- match tag. expand ( ) . unwrap ( ) . as_u32 ( ) {
170- EXCEPTION_HANDLER_CLEANUP => {
171- gcc_except_table_data. call_sites . 0 . push ( CallSite {
172- start : u64:: from ( call_site. ret_addr - 1 ) ,
173- length : 1 ,
174- landing_pad : u64:: from ( landingpad) ,
175- action_entry : None ,
176- } )
177- }
178- EXCEPTION_HANDLER_CATCH => {
179- gcc_except_table_data. call_sites . 0 . push ( CallSite {
180- start : u64:: from ( call_site. ret_addr - 1 ) ,
181- length : 1 ,
182- landing_pad : u64:: from ( landingpad) ,
183- action_entry : Some ( catch_action) ,
184- } )
143+
144+ // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
145+ if cfg ! ( feature = "unwinding" ) {
146+ // FIXME use unique symbol name derived from function name
147+ let lsda = module. declare_anonymous_data ( false , false ) . unwrap ( ) ;
148+
149+ let encoding = Encoding {
150+ format : Format :: Dwarf32 ,
151+ version : 1 ,
152+ address_size : module. isa ( ) . frontend_config ( ) . pointer_bytes ( ) ,
153+ } ;
154+
155+ let mut gcc_except_table_data = GccExceptTable {
156+ call_sites : CallSiteTable ( vec ! [ ] ) ,
157+ actions : ActionTable :: new ( ) ,
158+ type_info : TypeInfoTable :: new ( gimli:: DW_EH_PE_udata4 ) ,
159+ exception_specs : ExceptionSpecTable :: new ( ) ,
160+ } ;
161+
162+ let catch_type = gcc_except_table_data. type_info . add ( Address :: Constant ( 0 ) ) ;
163+ let catch_action = gcc_except_table_data
164+ . actions
165+ . add ( Action { kind : ActionKind :: Catch ( catch_type) , next_action : None } ) ;
166+
167+ for call_site in context. compiled_code ( ) . unwrap ( ) . buffer . call_sites ( ) {
168+ if call_site. exception_handlers . is_empty ( ) {
169+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
170+ start : u64:: from ( call_site. ret_addr - 1 ) ,
171+ length : 1 ,
172+ landing_pad : 0 ,
173+ action_entry : None ,
174+ } ) ;
175+ }
176+ for & ( tag, landingpad) in call_site. exception_handlers {
177+ match tag. expand ( ) . unwrap ( ) . as_u32 ( ) {
178+ EXCEPTION_HANDLER_CLEANUP => {
179+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
180+ start : u64:: from ( call_site. ret_addr - 1 ) ,
181+ length : 1 ,
182+ landing_pad : u64:: from ( landingpad) ,
183+ action_entry : None ,
184+ } )
185+ }
186+ EXCEPTION_HANDLER_CATCH => {
187+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
188+ start : u64:: from ( call_site. ret_addr - 1 ) ,
189+ length : 1 ,
190+ landing_pad : u64:: from ( landingpad) ,
191+ action_entry : Some ( catch_action) ,
192+ } )
193+ }
194+ _ => unreachable ! ( ) ,
185195 }
186- _ => unreachable ! ( ) ,
187196 }
188197 }
189- }
190198
191- let mut gcc_except_table = super :: emit:: WriterRelocate :: new ( self . endian ) ;
192-
193- gcc_except_table_data. write ( & mut gcc_except_table, encoding) . unwrap ( ) ;
194-
195- let mut data = DataDescription :: new ( ) ;
196- data. define ( gcc_except_table. writer . into_vec ( ) . into_boxed_slice ( ) ) ;
197- data. set_segment_section ( "" , ".gcc_except_table" ) ;
198-
199- for reloc in & gcc_except_table. relocs {
200- match reloc. name {
201- DebugRelocName :: Section ( _id) => unreachable ! ( ) ,
202- DebugRelocName :: Symbol ( id) => {
203- let id = id. try_into ( ) . unwrap ( ) ;
204- if id & 1 << 31 == 0 {
205- let func_ref =
206- module. declare_func_in_data ( FuncId :: from_u32 ( id) , & mut data) ;
207- data. write_function_addr ( reloc. offset , func_ref) ;
208- } else {
209- let gv = module. declare_data_in_data (
210- DataId :: from_u32 ( id & !( 1 << 31 ) ) ,
211- & mut data,
212- ) ;
213- data. write_data_addr ( reloc. offset , gv, 0 ) ;
199+ let mut gcc_except_table = super :: emit:: WriterRelocate :: new ( self . endian ) ;
200+
201+ gcc_except_table_data. write ( & mut gcc_except_table, encoding) . unwrap ( ) ;
202+
203+ let mut data = DataDescription :: new ( ) ;
204+ data. define ( gcc_except_table. writer . into_vec ( ) . into_boxed_slice ( ) ) ;
205+ data. set_segment_section ( "" , ".gcc_except_table" ) ;
206+
207+ for reloc in & gcc_except_table. relocs {
208+ match reloc. name {
209+ DebugRelocName :: Section ( _id) => unreachable ! ( ) ,
210+ DebugRelocName :: Symbol ( id) => {
211+ let id = id. try_into ( ) . unwrap ( ) ;
212+ if id & 1 << 31 == 0 {
213+ let func_ref = module
214+ . declare_func_in_data ( FuncId :: from_u32 ( id) , & mut data) ;
215+ data. write_function_addr ( reloc. offset , func_ref) ;
216+ } else {
217+ let gv = module. declare_data_in_data (
218+ DataId :: from_u32 ( id & !( 1 << 31 ) ) ,
219+ & mut data,
220+ ) ;
221+ data. write_data_addr ( reloc. offset , gv, 0 ) ;
222+ }
214223 }
215- }
216- } ;
224+ } ;
225+ }
226+
227+ module. define_data ( lsda, & data) . unwrap ( ) ;
228+ fde. lsda = Some ( address_for_data ( lsda) ) ;
217229 }
218230
219- module. define_data ( lsda, & data) . unwrap ( ) ;
220- fde. lsda = Some ( address_for_data ( lsda) ) ;
221231 self . frame_table . add_fde ( self . cie_id . unwrap ( ) , fde) ;
222232 }
223233 UnwindInfo :: WindowsX64 ( _) | UnwindInfo :: WindowsArm64 ( _) => {
0 commit comments