@@ -38,68 +38,74 @@ impl UnwindContext {
38
38
} else {
39
39
gimli:: DW_EH_PE_absptr
40
40
} ;
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
- } ;
62
41
63
42
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
+
103
109
Some ( frame_table. add_cie ( cie) )
104
110
} else {
105
111
None
@@ -135,89 +141,94 @@ impl UnwindContext {
135
141
match unwind_info {
136
142
UnwindInfo :: SystemV ( unwind_info) => {
137
143
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
144
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 ( ) ;
146
149
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
+ } ;
153
155
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 ! ( ) ,
185
196
}
186
- _ => unreachable ! ( ) ,
187
197
}
188
198
}
189
- }
190
199
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
+ }
214
224
}
215
- }
216
- } ;
225
+ } ;
226
+ }
227
+
228
+ module. define_data ( lsda, & data) . unwrap ( ) ;
229
+ fde. lsda = Some ( address_for_data ( lsda) ) ;
217
230
}
218
231
219
- module. define_data ( lsda, & data) . unwrap ( ) ;
220
- fde. lsda = Some ( address_for_data ( lsda) ) ;
221
232
self . frame_table . add_fde ( self . cie_id . unwrap ( ) , fde) ;
222
233
}
223
234
UnwindInfo :: WindowsX64 ( _) | UnwindInfo :: WindowsArm64 ( _) => {
0 commit comments