]> git.lizzy.rs Git - rust.git/blobdiff - src/backend.rs
Fold `vtable_trait_upcasting_coercion_new_vptr_slot` logic into obligation processing.
[rust.git] / src / backend.rs
index d9cb1d939f773b127f6cc5aad8666b04ee9194a6..05c06bac27db47d653f3cea67422290b9f7fe517 100644 (file)
@@ -1,28 +1,28 @@
+//! Abstraction around the object writing crate
+
 use std::convert::{TryFrom, TryInto};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_session::Session;
 
-use cranelift_module::{FuncId, Module};
+use cranelift_codegen::isa::TargetIsa;
+use cranelift_module::FuncId;
+use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct};
 
 use object::write::*;
-use object::{RelocationEncoding, RelocationKind, SectionKind, SymbolFlags};
-
-use cranelift_object::{ObjectBackend, ObjectBuilder, ObjectProduct};
+use object::{RelocationEncoding, SectionKind, SymbolFlags};
 
 use gimli::SectionId;
 
 use crate::debuginfo::{DebugReloc, DebugRelocName};
 
 pub(crate) trait WriteMetadata {
-    fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, is_like_osx: bool);
+    fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>);
 }
 
 impl WriteMetadata for object::write::Object {
-    fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, _is_like_osx: bool) {
-        let segment = self
-            .segment_name(object::write::StandardSegment::Data)
-            .to_vec();
+    fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>) {
+        let segment = self.segment_name(object::write::StandardSegment::Data).to_vec();
         let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data);
         let offset = self.append_section_data(section_id, &data, 1);
         // For MachO and probably PE this is necessary to prevent the linker from throwing away the
@@ -68,8 +68,15 @@ fn add_debug_section(
         .into_bytes();
 
         let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
-        let section_id = self.object.add_section(segment, name, SectionKind::Debug);
-        self.object.section_mut(section_id).set_data(data, 1);
+        // FIXME use SHT_X86_64_UNWIND for .eh_frame
+        let section_id = self.object.add_section(
+            segment,
+            name,
+            if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
+        );
+        self.object
+            .section_mut(section_id)
+            .set_data(data, if id == SectionId::EhFrame { 8 } else { 1 });
         let symbol_id = self.object.section_symbol(section_id);
         (section_id, symbol_id)
     }
@@ -95,7 +102,7 @@ fn add_debug_reloc(
                 Relocation {
                     offset: u64::from(reloc.offset),
                     symbol,
-                    kind: RelocationKind::Absolute,
+                    kind: reloc.kind,
                     encoding: RelocationEncoding::Generic,
                     size: reloc.size * 8,
                     addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
@@ -105,55 +112,8 @@ fn add_debug_reloc(
     }
 }
 
-// FIXME remove once atomic instructions are implemented in Cranelift.
-pub(crate) trait AddConstructor {
-    fn add_constructor(&mut self, func_id: FuncId);
-}
-
-impl AddConstructor for ObjectProduct {
-    fn add_constructor(&mut self, func_id: FuncId) {
-        let symbol = self.function_symbol(func_id);
-        let segment = self
-            .object
-            .segment_name(object::write::StandardSegment::Data);
-        let init_array_section =
-            self.object
-                .add_section(segment.to_vec(), b".init_array".to_vec(), SectionKind::Data);
-        self.object.append_section_data(
-            init_array_section,
-            &std::iter::repeat(0)
-                .take(8 /*FIXME pointer size*/)
-                .collect::<Vec<u8>>(),
-            8,
-        );
-        self.object
-            .add_relocation(
-                init_array_section,
-                object::write::Relocation {
-                    offset: 0,
-                    size: 64, // FIXME pointer size
-                    kind: RelocationKind::Absolute,
-                    encoding: RelocationEncoding::Generic,
-                    symbol,
-                    addend: 0,
-                },
-            )
-            .unwrap();
-    }
-}
-
-pub(crate) trait Emit {
-    fn emit(self) -> Vec<u8>;
-}
-
-impl Emit for ObjectProduct {
-    fn emit(self) -> Vec<u8> {
-        self.object.write().unwrap()
-    }
-}
-
 pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec<u8> {
-    let triple = crate::build_isa(sess, true).triple().clone();
+    let triple = crate::target_triple(sess);
 
     let binary_format = match triple.binary_format {
         target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
@@ -166,10 +126,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object
         target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
         target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
         target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
-        architecture => sess.fatal(&format!(
-            "target architecture {:?} is unsupported",
-            architecture,
-        )),
+        architecture => {
+            sess.fatal(&format!("target architecture {:?} is unsupported", architecture,))
+        }
     };
     let endian = match triple.endianness().unwrap() {
         target_lexicon::Endianness::Little => object::Endianness::Little,
@@ -182,21 +141,12 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object
     metadata_object.write().unwrap()
 }
 
-pub(crate) type Backend =
-    impl cranelift_module::Backend<Product: AddConstructor + Emit + WriteDebugInfo>;
-
-pub(crate) fn make_module(sess: &Session, name: String) -> Module<Backend> {
-    let mut builder = ObjectBuilder::new(
-        crate::build_isa(sess, true),
-        name + ".o",
-        cranelift_module::default_libcall_names(),
-    )
-    .unwrap();
-    if std::env::var("CG_CLIF_FUNCTION_SECTIONS").is_ok() {
-        builder.per_function_section(true);
-    }
-    let module: Module<ObjectBackend> = Module::new(
-        builder,
-    );
-    module
+pub(crate) fn make_module(sess: &Session, isa: Box<dyn TargetIsa>, name: String) -> ObjectModule {
+    let mut builder =
+        ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
+    // Unlike cg_llvm, cg_clif defaults to disabling -Zfunction-sections. For cg_llvm binary size
+    // is important, while cg_clif cares more about compilation times. Enabling -Zfunction-sections
+    // can easily double the amount of time necessary to perform linking.
+    builder.per_function_section(sess.opts.debugging_opts.function_sections.unwrap_or(false));
+    ObjectModule::new(builder)
 }