@@ -2,17 +2,10 @@ use std::{collections::hash_map::Entry, io::Write, iter, path::Path};
22
33use rustc_apfloat:: Float ;
44use 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 ;
137use rustc_middle:: mir;
148use rustc_middle:: ty;
15- use rustc_session:: config:: CrateType ;
169use rustc_span:: Symbol ;
1710use rustc_target:: {
1811 abi:: { Align , Size } ,
@@ -174,74 +167,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
174167 Entry :: Vacant ( e) => {
175168 // Find it if it was not cached.
176169 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+ } ) ;
202193 } 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+ } ) ;
241201 }
242202 }
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) ) ;
243209 }
244- }
210+ Ok ( ( ) )
211+ } ) ?;
245212
246213 e. insert ( instance_and_crate. map ( |ic| ic. 0 ) )
247214 }
0 commit comments