diff --git a/cranelift/module/src/data_context.rs b/cranelift/module/src/data_context.rs index ca490a09e9..ce9536b1b0 100644 --- a/cranelift/module/src/data_context.rs +++ b/cranelift/module/src/data_context.rs @@ -1,6 +1,6 @@ //! Defines `DataContext`. -use cranelift_codegen::binemit::{Addend, CodeOffset}; +use cranelift_codegen::binemit::{Addend, CodeOffset, Reloc}; use cranelift_codegen::entity::PrimaryMap; use cranelift_codegen::ir; use std::borrow::ToOwned; @@ -8,6 +8,8 @@ use std::boxed::Box; use std::string::String; use std::vec::Vec; +use crate::RelocRecord; + /// This specifies how data is to be initialized. #[derive(PartialEq, Eq, Debug)] pub enum Init { @@ -55,6 +57,34 @@ pub struct DataDescription { pub align: Option, } +impl DataDescription { + /// An iterator over all relocations of the data object. + pub fn all_relocs<'a>( + &'a self, + pointer_reloc: Reloc, + ) -> impl Iterator + 'a { + let func_relocs = self + .function_relocs + .iter() + .map(move |&(offset, id)| RelocRecord { + reloc: pointer_reloc, + offset, + name: self.function_decls[id].clone(), + addend: 0, + }); + let data_relocs = self + .data_relocs + .iter() + .map(move |&(offset, id, addend)| RelocRecord { + reloc: pointer_reloc, + offset, + name: self.data_decls[id].clone(), + addend, + }); + func_relocs.chain(data_relocs) + } +} + /// This is to data objects what cranelift_codegen::Context is to functions. pub struct DataContext { description: DataDescription, diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 853289d3e2..f8bffc8beb 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -305,7 +305,10 @@ impl Module for ObjectModule { }; if !relocs.is_empty() { - let relocs = self.process_relocs(relocs); + let relocs = relocs + .iter() + .map(|record| self.process_reloc(record)) + .collect(); self.relocs.push(SymbolRelocs { section, offset, @@ -330,40 +333,24 @@ impl Module for ObjectModule { let &DataDescription { ref init, - ref function_decls, - ref data_decls, - ref function_relocs, - ref data_relocs, + function_decls: _, + data_decls: _, + function_relocs: _, + data_relocs: _, ref custom_segment_section, align, } = data_ctx.description(); - let reloc_size = match self.isa.triple().pointer_width().unwrap() { - PointerWidth::U16 => 16, - PointerWidth::U32 => 32, - PointerWidth::U64 => 64, + let pointer_reloc = match self.isa.triple().pointer_width().unwrap() { + PointerWidth::U16 => unimplemented!("16bit pointers"), + PointerWidth::U32 => Reloc::Abs4, + PointerWidth::U64 => Reloc::Abs8, }; - let mut relocs = Vec::new(); - for &(offset, id) in function_relocs { - relocs.push(ObjectRelocRecord { - offset, - name: function_decls[id].clone(), - kind: RelocationKind::Absolute, - encoding: RelocationEncoding::Generic, - size: reloc_size, - addend: 0, - }); - } - for &(offset, id, addend) in data_relocs { - relocs.push(ObjectRelocRecord { - offset, - name: data_decls[id].clone(), - kind: RelocationKind::Absolute, - encoding: RelocationEncoding::Generic, - size: reloc_size, - addend, - }); - } + let relocs = data_ctx + .description() + .all_relocs(pointer_reloc) + .map(|record| self.process_reloc(&record)) + .collect::>(); let section = if custom_segment_section.is_none() { let section_kind = if let Init::Zeros { .. } = *init { @@ -510,69 +497,60 @@ impl ObjectModule { } } - fn process_relocs(&self, relocs: &[RelocRecord]) -> Vec { - relocs - .iter() - .map(|record| { - let mut addend = record.addend; - let (kind, encoding, size) = match record.reloc { - Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32), - Reloc::Abs8 => (RelocationKind::Absolute, RelocationEncoding::Generic, 64), - Reloc::X86PCRel4 => (RelocationKind::Relative, RelocationEncoding::Generic, 32), - Reloc::X86CallPCRel4 => { - (RelocationKind::Relative, RelocationEncoding::X86Branch, 32) - } - // TODO: Get Cranelift to tell us when we can use - // R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX. - Reloc::X86CallPLTRel4 => ( - RelocationKind::PltRelative, - RelocationEncoding::X86Branch, - 32, - ), - Reloc::X86GOTPCRel4 => { - (RelocationKind::GotRelative, RelocationEncoding::Generic, 32) - } - Reloc::ElfX86_64TlsGd => { - assert_eq!( - self.object.format(), - object::BinaryFormat::Elf, - "ElfX86_64TlsGd is not supported for this file format" - ); - ( - RelocationKind::Elf(object::elf::R_X86_64_TLSGD), - RelocationEncoding::Generic, - 32, - ) - } - Reloc::MachOX86_64Tlv => { - assert_eq!( - self.object.format(), - object::BinaryFormat::MachO, - "MachOX86_64Tlv is not supported for this file format" - ); - addend += 4; // X86_64_RELOC_TLV has an implicit addend of -4 - ( - RelocationKind::MachO { - value: object::macho::X86_64_RELOC_TLV, - relative: true, - }, - RelocationEncoding::Generic, - 32, - ) - } - // FIXME - _ => unimplemented!(), - }; - ObjectRelocRecord { - offset: record.offset, - name: record.name.clone(), - kind, - encoding, - size, - addend, - } - }) - .collect() + fn process_reloc(&self, record: &RelocRecord) -> ObjectRelocRecord { + let mut addend = record.addend; + let (kind, encoding, size) = match record.reloc { + Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32), + Reloc::Abs8 => (RelocationKind::Absolute, RelocationEncoding::Generic, 64), + Reloc::X86PCRel4 => (RelocationKind::Relative, RelocationEncoding::Generic, 32), + Reloc::X86CallPCRel4 => (RelocationKind::Relative, RelocationEncoding::X86Branch, 32), + // TODO: Get Cranelift to tell us when we can use + // R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX. + Reloc::X86CallPLTRel4 => ( + RelocationKind::PltRelative, + RelocationEncoding::X86Branch, + 32, + ), + Reloc::X86GOTPCRel4 => (RelocationKind::GotRelative, RelocationEncoding::Generic, 32), + Reloc::ElfX86_64TlsGd => { + assert_eq!( + self.object.format(), + object::BinaryFormat::Elf, + "ElfX86_64TlsGd is not supported for this file format" + ); + ( + RelocationKind::Elf(object::elf::R_X86_64_TLSGD), + RelocationEncoding::Generic, + 32, + ) + } + Reloc::MachOX86_64Tlv => { + assert_eq!( + self.object.format(), + object::BinaryFormat::MachO, + "MachOX86_64Tlv is not supported for this file format" + ); + addend += 4; // X86_64_RELOC_TLV has an implicit addend of -4 + ( + RelocationKind::MachO { + value: object::macho::X86_64_RELOC_TLV, + relative: true, + }, + RelocationEncoding::Generic, + 32, + ) + } + // FIXME + _ => unimplemented!(), + }; + ObjectRelocRecord { + offset: record.offset, + name: record.name.clone(), + kind, + encoding, + size, + addend, + } } } diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index febee43b2b..470b504bf0 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -443,10 +443,10 @@ impl<'simple_jit_backend> Module for SimpleJITModule { let &DataDescription { ref init, - ref function_decls, - ref data_decls, - ref function_relocs, - ref data_relocs, + function_decls: _, + data_decls: _, + function_relocs: _, + data_relocs: _, custom_segment_section: _, align, } = data.description(); @@ -477,28 +477,15 @@ impl<'simple_jit_backend> Module for SimpleJITModule { } } - let reloc = match self.isa.triple().pointer_width().unwrap() { + let pointer_reloc = match self.isa.triple().pointer_width().unwrap() { PointerWidth::U16 => panic!(), PointerWidth::U32 => Reloc::Abs4, PointerWidth::U64 => Reloc::Abs8, }; - let mut relocs = Vec::new(); - for &(offset, id) in function_relocs { - relocs.push(RelocRecord { - reloc, - offset, - name: function_decls[id].clone(), - addend: 0, - }); - } - for &(offset, id, addend) in data_relocs { - relocs.push(RelocRecord { - reloc, - offset, - name: data_decls[id].clone(), - addend, - }); - } + let relocs = data + .description() + .all_relocs(pointer_reloc) + .collect::>(); self.compiled_data_objects[id] = Some(CompiledBlob { ptr, size, relocs }); self.data_objects_to_finalize.push(id);