@@ -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 } ,
@@ -158,81 +151,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
158151 Ok ( ( ) )
159152 }
160153
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-
236154 /// Lookup the body of a function that has `link_name` as the symbol name.
237155 fn lookup_exported_symbol (
238156 & mut self ,
@@ -249,74 +167,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
249167 Entry :: Vacant ( e) => {
250168 // Find it if it was not cached.
251169 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+ } ) ;
277193 } 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+ } ) ;
316201 }
317202 }
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) ) ;
318209 }
319- }
210+ Ok ( ( ) )
211+ } ) ?;
320212
321213 e. insert ( instance_and_crate. map ( |ic| ic. 0 ) )
322214 }
0 commit comments