@@ -37,68 +37,74 @@ impl UnwindContext {
3737 } else {
3838 gimli:: DW_EH_PE_absptr
3939 } ;
40- let code_ptr_encoding = if pic_eh_frame {
41- if module. isa ( ) . triple ( ) . architecture == target_lexicon:: Architecture :: X86_64 {
42- gimli:: DwEhPe (
43- gimli:: DW_EH_PE_indirect . 0
44- | gimli:: DW_EH_PE_pcrel . 0
45- | gimli:: DW_EH_PE_sdata4 . 0 ,
46- )
47- } else if let target_lexicon:: Architecture :: Aarch64 ( _) =
48- module. isa ( ) . triple ( ) . architecture
49- {
50- gimli:: DwEhPe (
51- gimli:: DW_EH_PE_indirect . 0
52- | gimli:: DW_EH_PE_pcrel . 0
53- | gimli:: DW_EH_PE_sdata8 . 0 ,
54- )
55- } else {
56- todo ! ( )
57- }
58- } else {
59- gimli:: DwEhPe ( gimli:: DW_EH_PE_indirect . 0 | gimli:: DW_EH_PE_absptr . 0 )
60- } ;
6140
6241 cie. fde_address_encoding = ptr_encoding;
63- cie. lsda_encoding = Some ( ptr_encoding) ;
64-
65- // FIXME use eh_personality lang item instead
66- let personality = module
67- . declare_function (
68- "rust_eh_personality" ,
69- Linkage :: Import ,
70- & Signature {
71- params : vec ! [
72- AbiParam :: new( types:: I32 ) ,
73- AbiParam :: new( types:: I32 ) ,
74- AbiParam :: new( types:: I64 ) ,
75- AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
76- AbiParam :: new( module. target_config( ) . pointer_type( ) ) ,
77- ] ,
78- returns : vec ! [ AbiParam :: new( types:: I32 ) ] ,
79- call_conv : module. target_config ( ) . default_call_conv ,
80- } ,
81- )
82- . unwrap ( ) ;
83-
84- // Use indirection here to support PIC the case where rust_eh_personality is defined in
85- // another DSO.
86- let personality_ref = module
87- . declare_data ( "DW.ref.rust_eh_personality" , Linkage :: Local , false , false )
88- . unwrap ( ) ;
89-
90- let mut personality_ref_data = DataDescription :: new ( ) ;
91- // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
92- // section.
93- let pointer_bytes = usize:: from ( module. target_config ( ) . pointer_bytes ( ) ) ;
94- personality_ref_data. define ( vec ! [ 0 ; pointer_bytes] . into_boxed_slice ( ) ) ;
95- let personality_func_ref =
96- module. declare_func_in_data ( personality, & mut personality_ref_data) ;
97- personality_ref_data. write_function_addr ( 0 , personality_func_ref) ;
98-
99- module. define_data ( personality_ref, & personality_ref_data) . unwrap ( ) ;
100-
101- cie. personality = Some ( ( code_ptr_encoding, address_for_data ( personality_ref) ) ) ;
42+
43+ // 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
44+ if cfg ! ( feature = "unwinding" ) {
45+ let code_ptr_encoding = if pic_eh_frame {
46+ if module. isa ( ) . triple ( ) . architecture == target_lexicon:: Architecture :: X86_64 {
47+ gimli:: DwEhPe (
48+ gimli:: DW_EH_PE_indirect . 0
49+ | gimli:: DW_EH_PE_pcrel . 0
50+ | gimli:: DW_EH_PE_sdata4 . 0 ,
51+ )
52+ } else if let target_lexicon:: Architecture :: Aarch64 ( _) =
53+ module. isa ( ) . triple ( ) . architecture
54+ {
55+ gimli:: DwEhPe (
56+ gimli:: DW_EH_PE_indirect . 0
57+ | gimli:: DW_EH_PE_pcrel . 0
58+ | gimli:: DW_EH_PE_sdata8 . 0 ,
59+ )
60+ } else {
61+ todo ! ( )
62+ }
63+ } else {
64+ gimli:: DwEhPe ( gimli:: DW_EH_PE_indirect . 0 | gimli:: DW_EH_PE_absptr . 0 )
65+ } ;
66+
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+
102108 Some ( frame_table. add_cie ( cie) )
103109 } else {
104110 None
@@ -134,88 +140,93 @@ impl UnwindContext {
134140 match unwind_info {
135141 UnwindInfo :: SystemV ( unwind_info) => {
136142 let mut fde = unwind_info. to_fde ( address_for_func ( func_id) ) ;
137- // FIXME use unique symbol name derived from function name
138- let lsda = module. declare_anonymous_data ( false , false ) . unwrap ( ) ;
139143
140- let encoding = Encoding {
141- format : Format :: Dwarf32 ,
142- version : 1 ,
143- address_size : module. isa ( ) . frontend_config ( ) . pointer_bytes ( ) ,
144- } ;
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 ( ) ;
145148
146- let mut gcc_except_table_data = GccExceptTable {
147- call_sites : CallSiteTable ( vec ! [ ] ) ,
148- actions : ActionTable :: new ( ) ,
149- type_info : TypeInfoTable :: new ( gimli :: DW_EH_PE_udata4 ) ,
150- } ;
149+ let encoding = Encoding {
150+ format : Format :: Dwarf32 ,
151+ version : 1 ,
152+ address_size : module . isa ( ) . frontend_config ( ) . pointer_bytes ( ) ,
153+ } ;
151154
152- let catch_type = gcc_except_table_data. type_info . add ( Address :: Constant ( 0 ) ) ;
153- let catch_action = gcc_except_table_data
154- . actions
155- . add ( Action { kind : ActionKind :: Catch ( catch_type) , next_action : None } ) ;
156-
157- for call_site in context. compiled_code ( ) . unwrap ( ) . buffer . call_sites ( ) {
158- if call_site. exception_handlers . is_empty ( ) {
159- gcc_except_table_data. call_sites . 0 . push ( CallSite {
160- start : u64:: from ( call_site. ret_addr - 1 ) ,
161- length : 1 ,
162- landing_pad : 0 ,
163- action_entry : None ,
164- } ) ;
165- }
166- for & ( tag, landingpad) in call_site. exception_handlers {
167- match tag. expand ( ) . unwrap ( ) . as_u32 ( ) {
168- EXCEPTION_HANDLER_CLEANUP => {
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 : u64:: from ( landingpad) ,
173- action_entry : None ,
174- } )
175- }
176- EXCEPTION_HANDLER_CATCH => {
177- gcc_except_table_data. call_sites . 0 . push ( CallSite {
178- start : u64:: from ( call_site. ret_addr - 1 ) ,
179- length : 1 ,
180- landing_pad : u64:: from ( landingpad) ,
181- action_entry : Some ( catch_action) ,
182- } )
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+ } ;
160+
161+ let catch_type = gcc_except_table_data. type_info . add ( Address :: Constant ( 0 ) ) ;
162+ let catch_action = gcc_except_table_data
163+ . actions
164+ . add ( Action { kind : ActionKind :: Catch ( catch_type) , next_action : None } ) ;
165+
166+ for call_site in context. compiled_code ( ) . unwrap ( ) . buffer . call_sites ( ) {
167+ if call_site. exception_handlers . is_empty ( ) {
168+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
169+ start : u64:: from ( call_site. ret_addr - 1 ) ,
170+ length : 1 ,
171+ landing_pad : 0 ,
172+ action_entry : None ,
173+ } ) ;
174+ }
175+ for & ( tag, landingpad) in call_site. exception_handlers {
176+ match tag. expand ( ) . unwrap ( ) . as_u32 ( ) {
177+ EXCEPTION_HANDLER_CLEANUP => {
178+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
179+ start : u64:: from ( call_site. ret_addr - 1 ) ,
180+ length : 1 ,
181+ landing_pad : u64:: from ( landingpad) ,
182+ action_entry : None ,
183+ } )
184+ }
185+ EXCEPTION_HANDLER_CATCH => {
186+ gcc_except_table_data. call_sites . 0 . push ( CallSite {
187+ start : u64:: from ( call_site. ret_addr - 1 ) ,
188+ length : 1 ,
189+ landing_pad : u64:: from ( landingpad) ,
190+ action_entry : Some ( catch_action) ,
191+ } )
192+ }
193+ _ => unreachable ! ( ) ,
183194 }
184- _ => unreachable ! ( ) ,
185195 }
186196 }
187- }
188197
189- let mut gcc_except_table = super :: emit:: WriterRelocate :: new ( self . endian ) ;
190-
191- gcc_except_table_data. write ( & mut gcc_except_table, encoding) . unwrap ( ) ;
192-
193- let mut data = DataDescription :: new ( ) ;
194- data. define ( gcc_except_table. writer . into_vec ( ) . into_boxed_slice ( ) ) ;
195- data. set_segment_section ( "" , ".gcc_except_table" ) ;
196-
197- for reloc in & gcc_except_table. relocs {
198- match reloc. name {
199- DebugRelocName :: Section ( _id) => unreachable ! ( ) ,
200- DebugRelocName :: Symbol ( id) => {
201- let id = id. try_into ( ) . unwrap ( ) ;
202- if id & 1 << 31 == 0 {
203- let func_ref =
204- module. declare_func_in_data ( FuncId :: from_u32 ( id) , & mut data) ;
205- data. write_function_addr ( reloc. offset , func_ref) ;
206- } else {
207- let gv = module. declare_data_in_data (
208- DataId :: from_u32 ( id & !( 1 << 31 ) ) ,
209- & mut data,
210- ) ;
211- data. write_data_addr ( reloc. offset , gv, 0 ) ;
198+ let mut gcc_except_table = super :: emit:: WriterRelocate :: new ( self . endian ) ;
199+
200+ gcc_except_table_data. write ( & mut gcc_except_table, encoding) . unwrap ( ) ;
201+
202+ let mut data = DataDescription :: new ( ) ;
203+ data. define ( gcc_except_table. writer . into_vec ( ) . into_boxed_slice ( ) ) ;
204+ data. set_segment_section ( "" , ".gcc_except_table" ) ;
205+
206+ for reloc in & gcc_except_table. relocs {
207+ match reloc. name {
208+ DebugRelocName :: Section ( _id) => unreachable ! ( ) ,
209+ DebugRelocName :: Symbol ( id) => {
210+ let id = id. try_into ( ) . unwrap ( ) ;
211+ if id & 1 << 31 == 0 {
212+ let func_ref = module
213+ . declare_func_in_data ( FuncId :: from_u32 ( id) , & mut data) ;
214+ data. write_function_addr ( reloc. offset , func_ref) ;
215+ } else {
216+ let gv = module. declare_data_in_data (
217+ DataId :: from_u32 ( id & !( 1 << 31 ) ) ,
218+ & mut data,
219+ ) ;
220+ data. write_data_addr ( reloc. offset , gv, 0 ) ;
221+ }
212222 }
213- }
214- } ;
223+ } ;
224+ }
225+
226+ module. define_data ( lsda, & data) . unwrap ( ) ;
227+ fde. lsda = Some ( address_for_data ( lsda) ) ;
215228 }
216229
217- module. define_data ( lsda, & data) . unwrap ( ) ;
218- fde. lsda = Some ( address_for_data ( lsda) ) ;
219230 self . frame_table . add_fde ( self . cie_id . unwrap ( ) , fde) ;
220231 }
221232 UnwindInfo :: WindowsX64 ( _) | UnwindInfo :: WindowsArm64 ( _) => {
0 commit comments