diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index f2c227a52a..f10d457778 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -311,7 +311,7 @@ impl Backend for FaerieBackend { // Nothing to do. } - fn finish(self) -> FaerieProduct { + fn finish(self, _namespace: &ModuleNamespace) -> FaerieProduct { FaerieProduct { artifact: self.artifact, trap_manifest: self.trap_manifest, diff --git a/cranelift/module/src/backend.rs b/cranelift/module/src/backend.rs index 27472d042b..9efe17a926 100644 --- a/cranelift/module/src/backend.rs +++ b/cranelift/module/src/backend.rs @@ -146,7 +146,7 @@ where /// Consume this `Backend` and return a result. Some implementations may /// provide additional functionality through this result. - fn finish(self) -> Self::Product; + fn finish(self, namespace: &ModuleNamespace) -> Self::Product; } /// Default names for `ir::LibCall`s. A function by this name is imported into the object as diff --git a/cranelift/module/src/module.rs b/cranelift/module/src/module.rs index 56a94b89db..c6aa533807 100644 --- a/cranelift/module/src/module.rs +++ b/cranelift/module/src/module.rs @@ -714,8 +714,9 @@ where /// Consume the module and return the resulting `Product`. Some `Backend` /// implementations may provide additional functionality available after /// a `Module` is complete. - pub fn finish(mut self) -> B::Product { - self.finalize_definitions(); - self.backend.finish() + pub fn finish(self) -> B::Product { + self.backend.finish(&ModuleNamespace:: { + contents: &self.contents, + }) } } diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index d6a2d98385..0859046685 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -16,6 +16,7 @@ use object::write::{ }; use object::{RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope}; use std::collections::HashMap; +use std::mem; use target_lexicon::PointerWidth; #[derive(Debug)] @@ -79,6 +80,7 @@ pub struct ObjectBackend { functions: SecondaryMap>, data_objects: SecondaryMap>, traps: SecondaryMap>, + relocs: Vec, libcalls: HashMap, libcall_names: Box String>, collect_traps: ObjectTrapCollection, @@ -109,6 +111,7 @@ impl Backend for ObjectBackend { functions: SecondaryMap::new(), data_objects: SecondaryMap::new(), traps: SecondaryMap::new(), + relocs: Vec::new(), libcalls: HashMap::new(), libcall_names: builder.libcall_names, collect_traps: builder.collect_traps, @@ -212,13 +215,15 @@ impl Backend for ObjectBackend { let offset = self .object .add_symbol_data(symbol, section, &code, self.function_alignment); + if !reloc_sink.relocs.is_empty() { + self.relocs.push(SymbolRelocs { + section, + offset, + relocs: reloc_sink.relocs, + }); + } self.traps[func_id] = trap_sink.sites; - Ok(ObjectCompiledFunction { - offset, - size: code_size, - section, - relocs: reloc_sink.relocs, - }) + Ok(ObjectCompiledFunction) } fn define_data( @@ -290,11 +295,14 @@ impl Backend for ObjectBackend { let offset = self.object .add_symbol_data(symbol, section, &data, u64::from(align.unwrap_or(1))); - Ok(ObjectCompiledData { - offset, - section, - relocs, - }) + if !relocs.is_empty() { + self.relocs.push(SymbolRelocs { + section, + offset, + relocs, + }); + } + Ok(ObjectCompiledData) } fn write_data_funcaddr( @@ -319,34 +327,10 @@ impl Backend for ObjectBackend { fn finalize_function( &mut self, _id: FuncId, - func: &ObjectCompiledFunction, - namespace: &ModuleNamespace, + _func: &ObjectCompiledFunction, + _namespace: &ModuleNamespace, ) { - for &RelocRecord { - offset, - ref name, - kind, - encoding, - size, - addend, - } in &func.relocs - { - let offset = func.offset + u64::from(offset); - let symbol = self.get_symbol(namespace, name); - self.object - .add_relocation( - func.section, - Relocation { - offset, - size, - kind, - encoding, - symbol, - addend, - }, - ) - .unwrap(); - } + // Nothing to do. } fn get_finalized_function(&self, _func: &ObjectCompiledFunction) { @@ -356,34 +340,10 @@ impl Backend for ObjectBackend { fn finalize_data( &mut self, _id: DataId, - data: &ObjectCompiledData, - namespace: &ModuleNamespace, + _data: &ObjectCompiledData, + _namespace: &ModuleNamespace, ) { - for &RelocRecord { - offset, - ref name, - kind, - encoding, - size, - addend, - } in &data.relocs - { - let offset = data.offset + u64::from(offset); - let symbol = self.get_symbol(namespace, name); - self.object - .add_relocation( - data.section, - Relocation { - offset, - size, - kind, - encoding, - symbol, - addend, - }, - ) - .unwrap(); - } + // Nothing to do. } fn get_finalized_data(&self, _data: &ObjectCompiledData) { @@ -394,7 +354,36 @@ impl Backend for ObjectBackend { // Nothing to do. } - fn finish(self) -> ObjectProduct { + fn finish(mut self, namespace: &ModuleNamespace) -> ObjectProduct { + let mut symbol_relocs = Vec::new(); + mem::swap(&mut symbol_relocs, &mut self.relocs); + for symbol in symbol_relocs { + for &RelocRecord { + offset, + ref name, + kind, + encoding, + size, + addend, + } in &symbol.relocs + { + let target_symbol = self.get_symbol(namespace, name); + self.object + .add_relocation( + symbol.section, + Relocation { + offset: symbol.offset + u64::from(offset), + size, + kind, + encoding, + symbol: target_symbol, + addend, + }, + ) + .unwrap(); + } + } + ObjectProduct { object: self.object, functions: self.functions, @@ -405,7 +394,7 @@ impl Backend for ObjectBackend { } impl ObjectBackend { - // This should only be called during finalization because it creates + // This should only be called during finish because it creates // symbols for missing libcalls. fn get_symbol( &mut self, @@ -459,20 +448,8 @@ fn translate_linkage(linkage: Linkage) -> (SymbolScope, bool) { (scope, weak) } -#[derive(Clone)] -pub struct ObjectCompiledFunction { - offset: u64, - size: u32, - section: SectionId, - relocs: Vec, -} - -#[derive(Clone)] -pub struct ObjectCompiledData { - offset: u64, - section: SectionId, - relocs: Vec, -} +pub struct ObjectCompiledFunction; +pub struct ObjectCompiledData; /// This is the output of `Module`'s /// [`finish`](../cranelift_module/struct.Module.html#method.finish) function. @@ -509,6 +486,13 @@ impl ObjectProduct { } } +#[derive(Clone)] +struct SymbolRelocs { + section: SectionId, + offset: u64, + relocs: Vec, +} + #[derive(Clone)] struct RelocRecord { offset: CodeOffset, diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index 45c7d3d260..a4b7d1a1da 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -507,7 +507,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { /// /// This method does not need to be called when access to the memory /// handle is not required. - fn finish(self) -> Self::Product { + fn finish(self, _namespace: &ModuleNamespace) -> Self::Product { self.memory } }