Skip to content

Commit

Permalink
Introduce DataDescription::all_relocs to dedup some code
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Nov 11, 2020
1 parent a5501e1 commit 1dc27c9
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 116 deletions.
32 changes: 31 additions & 1 deletion cranelift/module/src/data_context.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! 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;
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 {
Expand Down Expand Up @@ -55,6 +57,34 @@ pub struct DataDescription {
pub align: Option<u64>,
}

impl DataDescription {
/// An iterator over all relocations of the data object.
pub fn all_relocs<'a>(
&'a self,
pointer_reloc: Reloc,
) -> impl Iterator<Item = RelocRecord> + '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,
Expand Down
164 changes: 71 additions & 93 deletions cranelift/object/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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::<Vec<_>>();

let section = if custom_segment_section.is_none() {
let section_kind = if let Init::Zeros { .. } = *init {
Expand Down Expand Up @@ -510,69 +497,60 @@ impl ObjectModule {
}
}

fn process_relocs(&self, relocs: &[RelocRecord]) -> Vec<ObjectRelocRecord> {
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,
}
}
}

Expand Down
31 changes: 9 additions & 22 deletions cranelift/simplejit/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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::<Vec<_>>();

self.compiled_data_objects[id] = Some(CompiledBlob { ptr, size, relocs });
self.data_objects_to_finalize.push(id);
Expand Down

0 comments on commit 1dc27c9

Please sign in to comment.