@@ -2,17 +2,10 @@ use std::{collections::hash_map::Entry, io::Write, iter, path::Path};
2
2
3
3
use rustc_apfloat:: Float ;
4
4
use rustc_ast:: expand:: allocator:: AllocatorKind ;
5
- use rustc_hir:: {
6
- def:: DefKind ,
7
- def_id:: { CrateNum , LOCAL_CRATE } ,
8
- } ;
9
- use rustc_middle:: middle:: {
10
- codegen_fn_attrs:: CodegenFnAttrFlags , dependency_format:: Linkage ,
11
- exported_symbols:: ExportedSymbol ,
12
- } ;
5
+ use rustc_hir:: { def:: DefKind , def_id:: CrateNum } ;
6
+ use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
13
7
use rustc_middle:: mir;
14
8
use rustc_middle:: ty;
15
- use rustc_session:: config:: CrateType ;
16
9
use rustc_span:: Symbol ;
17
10
use rustc_target:: {
18
11
abi:: { Align , Size } ,
@@ -158,81 +151,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
158
151
Ok ( ( ) )
159
152
}
160
153
161
- fn lookup_init_array ( & mut self ) -> InterpResult < ' tcx , Vec < ty:: Instance < ' tcx > > > {
162
- let this = self . eval_context_mut ( ) ;
163
- let tcx = this. tcx . tcx ;
164
-
165
- let mut init_arrays = vec ! [ ] ;
166
-
167
- let dependency_formats = tcx. dependency_formats ( ( ) ) ;
168
- let dependency_format = dependency_formats
169
- . iter ( )
170
- . find ( |( crate_type, _) | * crate_type == CrateType :: Executable )
171
- . expect ( "interpreting a non-executable crate" ) ;
172
- for cnum in iter:: once ( LOCAL_CRATE ) . chain (
173
- dependency_format. 1 . iter ( ) . enumerate ( ) . filter_map ( |( num, & linkage) | {
174
- // We add 1 to the number because that's what rustc also does everywhere it
175
- // calls `CrateNum::new`...
176
- #[ allow( clippy:: arithmetic_side_effects) ]
177
- ( linkage != Linkage :: NotLinked ) . then_some ( CrateNum :: new ( num + 1 ) )
178
- } ) ,
179
- ) {
180
- for & ( symbol, _export_info) in tcx. exported_symbols ( cnum) {
181
- if let ExportedSymbol :: NonGeneric ( def_id) = symbol {
182
- let attrs = tcx. codegen_fn_attrs ( def_id) ;
183
- let link_section = if let Some ( link_section) = attrs. link_section {
184
- if !link_section. as_str ( ) . starts_with ( ".init_array" ) {
185
- continue ;
186
- }
187
- link_section
188
- } else {
189
- continue ;
190
- } ;
191
-
192
- init_arrays. push ( ( link_section, def_id) ) ;
193
- }
194
- }
195
- }
196
-
197
- init_arrays. sort_by ( |( a, _) , ( b, _) | a. as_str ( ) . cmp ( b. as_str ( ) ) ) ;
198
-
199
- let endianness = tcx. data_layout . endian ;
200
- let ptr_size = tcx. data_layout . pointer_size ;
201
-
202
- let mut init_array = vec ! [ ] ;
203
-
204
- for ( _, def_id) in init_arrays {
205
- let alloc = tcx. eval_static_initializer ( def_id) ?. inner ( ) ;
206
- let mut expected_offset = Size :: ZERO ;
207
- for & ( offset, prov) in alloc. provenance ( ) . ptrs ( ) . iter ( ) {
208
- if offset != expected_offset {
209
- throw_ub_format ! ( ".init_array.* may not contain any non-function pointer data" ) ;
210
- }
211
- expected_offset += ptr_size;
212
-
213
- let alloc_id = prov. alloc_id ( ) ;
214
-
215
- let reloc_target_alloc = tcx. global_alloc ( alloc_id) ;
216
- match reloc_target_alloc {
217
- GlobalAlloc :: Function ( instance) => {
218
- let addend = {
219
- let offset = offset. bytes ( ) as usize ;
220
- let bytes = & alloc. inspect_with_uninit_and_ptr_outside_interpreter (
221
- offset..offset + ptr_size. bytes ( ) as usize ,
222
- ) ;
223
- read_target_uint ( endianness, bytes) . unwrap ( )
224
- } ;
225
- assert_eq ! ( addend, 0 ) ;
226
- init_array. push ( instance) ;
227
- }
228
- _ => throw_ub_format ! ( ".init_array.* member is not a function pointer" ) ,
229
- }
230
- }
231
- }
232
-
233
- Ok ( init_array)
234
- }
235
-
236
154
/// Lookup the body of a function that has `link_name` as the symbol name.
237
155
fn lookup_exported_symbol (
238
156
& mut self ,
@@ -249,74 +167,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
249
167
Entry :: Vacant ( e) => {
250
168
// Find it if it was not cached.
251
169
let mut instance_and_crate: Option < ( ty:: Instance < ' _ > , CrateNum ) > = None ;
252
- // `dependency_formats` includes all the transitive informations needed to link a crate,
253
- // which is what we need here since we need to dig out `exported_symbols` from all transitive
254
- // dependencies.
255
- let dependency_formats = tcx. dependency_formats ( ( ) ) ;
256
- let dependency_format = dependency_formats
257
- . iter ( )
258
- . find ( |( crate_type, _) | * crate_type == CrateType :: Executable )
259
- . expect ( "interpreting a non-executable crate" ) ;
260
- for cnum in iter:: once ( LOCAL_CRATE ) . chain (
261
- dependency_format. 1 . iter ( ) . enumerate ( ) . filter_map ( |( num, & linkage) | {
262
- // We add 1 to the number because that's what rustc also does everywhere it
263
- // calls `CrateNum::new`...
264
- #[ allow( clippy:: arithmetic_side_effects) ]
265
- ( linkage != Linkage :: NotLinked ) . then_some ( CrateNum :: new ( num + 1 ) )
266
- } ) ,
267
- ) {
268
- // We can ignore `_export_info` here: we are a Rust crate, and everything is exported
269
- // from a Rust crate.
270
- for & ( symbol, _export_info) in tcx. exported_symbols ( cnum) {
271
- if let ExportedSymbol :: NonGeneric ( def_id) = symbol {
272
- let attrs = tcx. codegen_fn_attrs ( def_id) ;
273
- let symbol_name = if let Some ( export_name) = attrs. export_name {
274
- export_name
275
- } else if attrs. flags . contains ( CodegenFnAttrFlags :: NO_MANGLE ) {
276
- tcx. item_name ( def_id)
170
+ helpers:: iter_exported_symbols ( tcx, |cnum, def_id| {
171
+ let attrs = tcx. codegen_fn_attrs ( def_id) ;
172
+ let symbol_name = if let Some ( export_name) = attrs. export_name {
173
+ export_name
174
+ } else if attrs. flags . contains ( CodegenFnAttrFlags :: NO_MANGLE ) {
175
+ tcx. item_name ( def_id)
176
+ } else {
177
+ // Skip over items without an explicitly defined symbol name.
178
+ return Ok ( ( ) ) ;
179
+ } ;
180
+ if symbol_name == link_name {
181
+ if let Some ( ( original_instance, original_cnum) ) = instance_and_crate {
182
+ // Make sure we are consistent wrt what is 'first' and 'second'.
183
+ let original_span = tcx. def_span ( original_instance. def_id ( ) ) . data ( ) ;
184
+ let span = tcx. def_span ( def_id) . data ( ) ;
185
+ if original_span < span {
186
+ throw_machine_stop ! ( TerminationInfo :: MultipleSymbolDefinitions {
187
+ link_name,
188
+ first: original_span,
189
+ first_crate: tcx. crate_name( original_cnum) ,
190
+ second: span,
191
+ second_crate: tcx. crate_name( cnum) ,
192
+ } ) ;
277
193
} else {
278
- // Skip over items without an explicitly defined symbol name.
279
- continue ;
280
- } ;
281
- if symbol_name == link_name {
282
- if let Some ( ( original_instance, original_cnum) ) = instance_and_crate
283
- {
284
- // Make sure we are consistent wrt what is 'first' and 'second'.
285
- let original_span =
286
- tcx. def_span ( original_instance. def_id ( ) ) . data ( ) ;
287
- let span = tcx. def_span ( def_id) . data ( ) ;
288
- if original_span < span {
289
- throw_machine_stop ! (
290
- TerminationInfo :: MultipleSymbolDefinitions {
291
- link_name,
292
- first: original_span,
293
- first_crate: tcx. crate_name( original_cnum) ,
294
- second: span,
295
- second_crate: tcx. crate_name( cnum) ,
296
- }
297
- ) ;
298
- } else {
299
- throw_machine_stop ! (
300
- TerminationInfo :: MultipleSymbolDefinitions {
301
- link_name,
302
- first: span,
303
- first_crate: tcx. crate_name( cnum) ,
304
- second: original_span,
305
- second_crate: tcx. crate_name( original_cnum) ,
306
- }
307
- ) ;
308
- }
309
- }
310
- if !matches ! ( tcx. def_kind( def_id) , DefKind :: Fn | DefKind :: AssocFn ) {
311
- throw_ub_format ! (
312
- "attempt to call an exported symbol that is not defined as a function"
313
- ) ;
314
- }
315
- instance_and_crate = Some ( ( ty:: Instance :: mono ( tcx, def_id) , cnum) ) ;
194
+ throw_machine_stop ! ( TerminationInfo :: MultipleSymbolDefinitions {
195
+ link_name,
196
+ first: span,
197
+ first_crate: tcx. crate_name( cnum) ,
198
+ second: original_span,
199
+ second_crate: tcx. crate_name( original_cnum) ,
200
+ } ) ;
316
201
}
317
202
}
203
+ if !matches ! ( tcx. def_kind( def_id) , DefKind :: Fn | DefKind :: AssocFn ) {
204
+ throw_ub_format ! (
205
+ "attempt to call an exported symbol that is not defined as a function"
206
+ ) ;
207
+ }
208
+ instance_and_crate = Some ( ( ty:: Instance :: mono ( tcx, def_id) , cnum) ) ;
318
209
}
319
- }
210
+ Ok ( ( ) )
211
+ } ) ?;
320
212
321
213
e. insert ( instance_and_crate. map ( |ic| ic. 0 ) )
322
214
}
0 commit comments