+//! 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_module::FuncId;
use object::write::*;
use object::{RelocationEncoding, RelocationKind, SectionKind, SymbolFlags};
-use cranelift_object::{ObjectBackend, ObjectBuilder, ObjectProduct};
+use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct};
use gimli::SectionId;
.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)
}
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,
let init_array_section =
self.object
.add_section(segment.to_vec(), b".init_array".to_vec(), SectionKind::Data);
+ let address_size = self
+ .object
+ .architecture()
+ .address_size()
+ .expect("address_size must be known")
+ .bytes();
self.object.append_section_data(
init_array_section,
&std::iter::repeat(0)
- .take(8 /*FIXME pointer size*/)
+ .take(address_size.into())
.collect::<Vec<u8>>(),
8,
);
init_array_section,
object::write::Relocation {
offset: 0,
- size: 64, // FIXME pointer size
+ size: address_size * 8,
kind: RelocationKind::Absolute,
encoding: RelocationEncoding::Generic,
symbol,
}
}
-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::build_isa(sess).triple().clone();
let binary_format = match triple.binary_format {
target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
target_lexicon::BinaryFormat::Coff => object::BinaryFormat::Coff,
target_lexicon::BinaryFormat::Macho => object::BinaryFormat::MachO,
- target_lexicon::BinaryFormat::Wasm => sess.fatal("binary format wasm is unsupported"),
- target_lexicon::BinaryFormat::Unknown => sess.fatal("binary format is unknown"),
+ binary_format => sess.fatal(&format!("binary format {} is unsupported", binary_format)),
};
let architecture = match triple.architecture {
- target_lexicon::Architecture::I386
- | target_lexicon::Architecture::I586
- | target_lexicon::Architecture::I686 => object::Architecture::I386,
+ target_lexicon::Architecture::X86_32(_) => object::Architecture::I386,
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
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 module: Module<ObjectBackend> = Module::new(
- ObjectBuilder::new(
- crate::build_isa(sess, true),
- name + ".o",
- cranelift_module::default_libcall_names(),
- )
- .unwrap(),
- );
- module
+pub(crate) fn make_module(sess: &Session, name: String) -> ObjectModule {
+ let mut builder = ObjectBuilder::new(
+ crate::build_isa(sess),
+ 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)
}