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