diff --git a/Cargo.lock b/Cargo.lock index 55ea61170f2..8803bc22398 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cranelift-bforest" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "cranelift-entity", ] @@ -52,7 +52,7 @@ dependencies = [ [[package]] name = "cranelift-codegen" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "byteorder", "cranelift-bforest", @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -79,17 +79,17 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" [[package]] name = "cranelift-entity" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" [[package]] name = "cranelift-frontend" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "cranelift-codegen", "log", @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "cranelift-module" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "anyhow", "cranelift-codegen", @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "cranelift-codegen", "raw-cpuid", @@ -122,7 +122,7 @@ dependencies = [ [[package]] name = "cranelift-object" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "anyhow", "cranelift-codegen", @@ -134,7 +134,7 @@ dependencies = [ [[package]] name = "cranelift-simplejit" version = "0.66.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#32db4dcbe98098e5be2e457339d6d1946c73225c" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#1fabb051b0436a38f794ca395601dcdcc31d3c18" dependencies = [ "cranelift-codegen", "cranelift-module", diff --git a/Readme.md b/Readme.md index 24485058250..f5a38f0843b 100644 --- a/Readme.md +++ b/Readme.md @@ -70,6 +70,9 @@ function jit_calc() { object files when their content should have been changed by a change to cg_clif.
CG_CLIF_DISPLAY_CG_TIME
If "1", display the time it took to perform codegen for a crate
+
CG_CLIF_FUNCTION_SECTIONS
+
Use a single section for each function. This will often reduce the executable size at the + cost of making linking significantly slower.
## Not yet supported diff --git a/src/backend.rs b/src/backend.rs index bf4e8d6e02e..072fdc1f246 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -68,8 +68,17 @@ 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.clone(), 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 +104,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, @@ -186,13 +195,17 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object impl cranelift_module::Backend; pub(crate) fn make_module(sess: &Session, name: String) -> Module { + 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 = Module::new( - ObjectBuilder::new( - crate::build_isa(sess, true), - name + ".o", - cranelift_module::default_libcall_names(), - ) - .unwrap(), + builder, ); module } diff --git a/src/constant.rs b/src/constant.rs index d1248110d06..458ace9675d 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -274,7 +274,7 @@ fn data_id_for_alloc_id( ) -> DataId { module .declare_data( - &format!("__alloc_{}", alloc_id.0), + &format!("__alloc_{:x}", alloc_id.0), Linkage::Local, mutability == rustc_hir::Mutability::Mut, false, diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 01cb6d3484d..22e284b9df4 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -46,6 +46,7 @@ pub(crate) struct DebugReloc { pub(crate) size: u8, pub(crate) name: DebugRelocName, pub(crate) addend: i64, + pub(crate) kind: object::RelocationKind, } #[derive(Clone)] @@ -122,14 +123,13 @@ fn write_address(&mut self, address: Address, size: u8) -> Result<()> { size, name: DebugRelocName::Symbol(symbol), addend: addend as i64, + kind: object::RelocationKind::Absolute, }); self.write_udata(0, size) } } } - // TODO: implement write_eh_pointer - fn write_offset(&mut self, val: usize, section: SectionId, size: u8) -> Result<()> { let offset = self.len() as u32; self.relocs.push(DebugReloc { @@ -137,6 +137,7 @@ fn write_offset(&mut self, val: usize, section: SectionId, size: u8) -> Result<( size, name: DebugRelocName::Section(section), addend: val as i64, + kind: object::RelocationKind::Absolute, }); self.write_udata(0, size) } @@ -153,7 +154,55 @@ fn write_offset_at( size, name: DebugRelocName::Section(section), addend: val as i64, + kind: object::RelocationKind::Absolute, }); self.write_udata_at(offset, 0, size) } + + fn write_eh_pointer( + &mut self, + address: Address, + eh_pe: gimli::DwEhPe, + size: u8, + ) -> Result<()> { + match address { + // Address::Constant arm copied from gimli + Address::Constant(val) => { + // Indirect doesn't matter here. + let val = match eh_pe.application() { + gimli::DW_EH_PE_absptr => val, + gimli::DW_EH_PE_pcrel => { + // TODO: better handling of sign + let offset = self.len() as u64; + offset.wrapping_sub(val) + } + _ => { + return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)); + } + }; + self.write_eh_pointer_data(val, eh_pe.format(), size) + } + Address::Symbol { symbol, addend } => { + match eh_pe.application() { + gimli::DW_EH_PE_pcrel => { + let size = match eh_pe.format() { + gimli::DW_EH_PE_sdata4 => 4, + _ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)), + }; + self.relocs.push(DebugReloc { + offset: self.len() as u32, + size, + name: DebugRelocName::Symbol(symbol), + addend, + kind: object::RelocationKind::Relative, + }); + self.write_udata(0, size) + } + _ => { + return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)); + } + } + } + } + } } diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 4c23f75be69..39a951e5eca 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -16,7 +16,10 @@ impl<'tcx> UnwindContext<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, isa: &dyn TargetIsa) -> Self { let mut frame_table = FrameTable::default(); - let cie_id = if let Some(cie) = isa.create_systemv_cie() { + let cie_id = if let Some(mut cie) = isa.create_systemv_cie() { + if isa.flags().is_pic() { + cie.fde_address_encoding = gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0); + } Some(frame_table.add_cie(cie)) } else { None