@@ -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 } ,
@@ -174,74 +167,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
174
167
Entry :: Vacant ( e) => {
175
168
// Find it if it was not cached.
176
169
let mut instance_and_crate: Option < ( ty:: Instance < ' _ > , CrateNum ) > = None ;
177
- // `dependency_formats` includes all the transitive informations needed to link a crate,
178
- // which is what we need here since we need to dig out `exported_symbols` from all transitive
179
- // dependencies.
180
- let dependency_formats = tcx. dependency_formats ( ( ) ) ;
181
- let dependency_format = dependency_formats
182
- . iter ( )
183
- . find ( |( crate_type, _) | * crate_type == CrateType :: Executable )
184
- . expect ( "interpreting a non-executable crate" ) ;
185
- for cnum in iter:: once ( LOCAL_CRATE ) . chain (
186
- dependency_format. 1 . iter ( ) . enumerate ( ) . filter_map ( |( num, & linkage) | {
187
- // We add 1 to the number because that's what rustc also does everywhere it
188
- // calls `CrateNum::new`...
189
- #[ allow( clippy:: arithmetic_side_effects) ]
190
- ( linkage != Linkage :: NotLinked ) . then_some ( CrateNum :: new ( num + 1 ) )
191
- } ) ,
192
- ) {
193
- // We can ignore `_export_info` here: we are a Rust crate, and everything is exported
194
- // from a Rust crate.
195
- for & ( symbol, _export_info) in tcx. exported_symbols ( cnum) {
196
- if let ExportedSymbol :: NonGeneric ( def_id) = symbol {
197
- let attrs = tcx. codegen_fn_attrs ( def_id) ;
198
- let symbol_name = if let Some ( export_name) = attrs. export_name {
199
- export_name
200
- } else if attrs. flags . contains ( CodegenFnAttrFlags :: NO_MANGLE ) {
201
- 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
+ } ) ;
202
193
} else {
203
- // Skip over items without an explicitly defined symbol name.
204
- continue ;
205
- } ;
206
- if symbol_name == link_name {
207
- if let Some ( ( original_instance, original_cnum) ) = instance_and_crate
208
- {
209
- // Make sure we are consistent wrt what is 'first' and 'second'.
210
- let original_span =
211
- tcx. def_span ( original_instance. def_id ( ) ) . data ( ) ;
212
- let span = tcx. def_span ( def_id) . data ( ) ;
213
- if original_span < span {
214
- throw_machine_stop ! (
215
- TerminationInfo :: MultipleSymbolDefinitions {
216
- link_name,
217
- first: original_span,
218
- first_crate: tcx. crate_name( original_cnum) ,
219
- second: span,
220
- second_crate: tcx. crate_name( cnum) ,
221
- }
222
- ) ;
223
- } else {
224
- throw_machine_stop ! (
225
- TerminationInfo :: MultipleSymbolDefinitions {
226
- link_name,
227
- first: span,
228
- first_crate: tcx. crate_name( cnum) ,
229
- second: original_span,
230
- second_crate: tcx. crate_name( original_cnum) ,
231
- }
232
- ) ;
233
- }
234
- }
235
- if !matches ! ( tcx. def_kind( def_id) , DefKind :: Fn | DefKind :: AssocFn ) {
236
- throw_ub_format ! (
237
- "attempt to call an exported symbol that is not defined as a function"
238
- ) ;
239
- }
240
- 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
+ } ) ;
241
201
}
242
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) ) ;
243
209
}
244
- }
210
+ Ok ( ( ) )
211
+ } ) ?;
245
212
246
213
e. insert ( instance_and_crate. map ( |ic| ic. 0 ) )
247
214
}
0 commit comments