From 7b2d055f786ba4bd62bcfef1b9eb94b44f722255 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 23 Jul 2019 10:47:03 -0700 Subject: [PATCH] Add ability to relocate constants using RelocSink --- cranelift/codegen/src/binemit/memorysink.rs | 11 ++++++++++- cranelift/codegen/src/binemit/mod.rs | 13 +++++++++++-- cranelift/codegen/src/binemit/relaxation.rs | 7 ++++++- cranelift/faerie/src/backend.rs | 12 ++++++++++++ cranelift/filetests/src/test_binemit.rs | 12 +++++++++++- cranelift/filetests/src/test_compile.rs | 1 + cranelift/simplejit/src/backend.rs | 12 ++++++++++++ cranelift/src/disasm.rs | 16 ++++++++++++++++ 8 files changed, 79 insertions(+), 5 deletions(-) diff --git a/cranelift/codegen/src/binemit/memorysink.rs b/cranelift/codegen/src/binemit/memorysink.rs index 49c519f6b9..ffb8b44b49 100644 --- a/cranelift/codegen/src/binemit/memorysink.rs +++ b/cranelift/codegen/src/binemit/memorysink.rs @@ -16,7 +16,7 @@ use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc}; use crate::binemit::stackmap::Stackmap; use crate::ir::entities::Value; -use crate::ir::{ExternalName, Function, JumpTable, SourceLoc, TrapCode}; +use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, SourceLoc, TrapCode}; use crate::isa::TargetIsa; use core::ptr::write_unaligned; @@ -78,6 +78,9 @@ pub trait RelocSink { /// Add a relocation referencing an external symbol at the current offset. fn reloc_external(&mut self, _: CodeOffset, _: Reloc, _: &ExternalName, _: Addend); + /// Add a relocation referencing a constant. + fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset); + /// Add a relocation referencing a jump table. fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable); } @@ -132,6 +135,11 @@ impl<'a> CodeSink for MemoryCodeSink<'a> { self.relocs.reloc_external(ofs, rel, name, addend); } + fn reloc_constant(&mut self, rel: Reloc, constant_offset: ConstantOffset) { + let ofs = self.offset(); + self.relocs.reloc_constant(ofs, rel, constant_offset); + } + fn reloc_jt(&mut self, rel: Reloc, jt: JumpTable) { let ofs = self.offset(); self.relocs.reloc_jt(ofs, rel, jt); @@ -169,6 +177,7 @@ pub struct NullRelocSink {} impl RelocSink for NullRelocSink { fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {} fn reloc_external(&mut self, _: u32, _: Reloc, _: &ExternalName, _: i64) {} + fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset) {} fn reloc_jt(&mut self, _: u32, _: Reloc, _: JumpTable) {} } diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index ce9321ec19..e5d0cbbec5 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -16,7 +16,7 @@ pub use self::relaxation::relax_branches; pub use self::shrink::shrink_instructions; pub use self::stackmap::Stackmap; use crate::ir::entities::Value; -use crate::ir::{ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode}; +use crate::ir::{ConstantOffset, ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode}; use crate::isa::TargetIsa; pub use crate::regalloc::RegDiversions; use core::fmt; @@ -133,6 +133,9 @@ pub trait CodeSink { /// Add a relocation referencing an external symbol plus the addend at the current offset. fn reloc_external(&mut self, _: Reloc, _: &ExternalName, _: Addend); + /// Add a relocation referencing a jump table. + fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset); + /// Add a relocation referencing a jump table. fn reloc_jt(&mut self, _: Reloc, _: JumpTable); @@ -192,7 +195,13 @@ where } sink.begin_rodata(); - // TODO: No read-only data (constant pools) at this time. + + // output constants + for (_, constant_data) in func.dfg.constants.iter() { + for byte in constant_data.iter() { + sink.put1(*byte) + } + } sink.end_codegen(); } diff --git a/cranelift/codegen/src/binemit/relaxation.rs b/cranelift/codegen/src/binemit/relaxation.rs index 262ef986d0..1fdf51ea0e 100644 --- a/cranelift/codegen/src/binemit/relaxation.rs +++ b/cranelift/codegen/src/binemit/relaxation.rs @@ -37,6 +37,7 @@ use crate::iterators::IteratorExtras; use crate::regalloc::RegDiversions; use crate::timing; use crate::CodegenResult; +use core::convert::TryFrom; use log::debug; #[cfg(feature = "basic-blocks")] @@ -135,7 +136,11 @@ pub fn relax_branches( let jumptables_size = offset - jumptables; let rodata = offset; - // TODO: Once we have constant pools we'll do some processing here to update offset. + for constant in func.dfg.constants.entries_mut() { + constant.set_offset(offset); + offset += + u32::try_from(constant.len()).expect("Constants must have a length that fits in a u32") + } let rodata_size = offset - rodata; diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index a33955a212..d605757c4e 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -430,6 +430,18 @@ impl<'a> RelocSink for FaerieRelocSink<'a> { } } } + + fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::ConstantOffset) { + match reloc { + Reloc::X86PCRelRodata4 => { + // Not necessary to record this unless we are going to split apart code and its + // jumptbl/rodata. + } + _ => { + panic!("Unhandled reloc"); + } + } + } } #[allow(dead_code)] diff --git a/cranelift/filetests/src/test_binemit.rs b/cranelift/filetests/src/test_binemit.rs index f134806663..75bd86008f 100644 --- a/cranelift/filetests/src/test_binemit.rs +++ b/cranelift/filetests/src/test_binemit.rs @@ -90,6 +90,10 @@ impl binemit::CodeSink for TextSink { write!(self.text, ") ").unwrap(); } + fn reloc_constant(&mut self, reloc: binemit::Reloc, constant: ir::ConstantOffset) { + write!(self.text, "{}({}) ", reloc, constant).unwrap(); + } + fn reloc_jt(&mut self, reloc: binemit::Reloc, jt: ir::JumpTable) { write!(self.text, "{}({}) ", reloc, jt).unwrap(); } @@ -313,7 +317,13 @@ impl SubTest for TestBinEmit { } sink.begin_rodata(); - // TODO: Read-only (constant pool) data. + + // output constants + for (_, constant_data) in func.dfg.constants.iter() { + for byte in constant_data.iter() { + sink.put1(*byte) + } + } sink.end_codegen(); diff --git a/cranelift/filetests/src/test_compile.rs b/cranelift/filetests/src/test_compile.rs index 706aa00331..10e07440ed 100644 --- a/cranelift/filetests/src/test_compile.rs +++ b/cranelift/filetests/src/test_compile.rs @@ -106,6 +106,7 @@ impl binemit::CodeSink for SizeSink { _addend: binemit::Addend, ) { } + fn reloc_constant(&mut self, _: binemit::Reloc, _: ir::ConstantOffset) {} fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {} fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {} fn begin_jumptables(&mut self) {} diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index 0a97df8f46..372f112e8d 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -566,6 +566,18 @@ impl RelocSink for SimpleJITRelocSink { } } } + + fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _constant: ir::ConstantOffset) { + match reloc { + Reloc::X86PCRelRodata4 => { + // Not necessary to record this unless we are going to split apart code and its + // jumptbl/rodata. + } + _ => { + panic!("Unhandled reloc"); + } + } + } } struct SimpleJITStackmapSink { diff --git a/cranelift/src/disasm.rs b/cranelift/src/disasm.rs index 5bfa14e313..7a98e02b0b 100644 --- a/cranelift/src/disasm.rs +++ b/cranelift/src/disasm.rs @@ -56,6 +56,22 @@ impl binemit::RelocSink for PrintRelocs { write!(&mut self.text, "reloc_jt: {} {} at {}\n", r, jt, where_).unwrap(); } } + + fn reloc_constant( + &mut self, + code_offset: binemit::CodeOffset, + reloc: binemit::Reloc, + constant: ir::ConstantOffset, + ) { + if self.flag_print { + write!( + &mut self.text, + "reloc_constant: {} {} at {}\n", + reloc, constant, code_offset + ) + .unwrap(); + } + } } pub struct PrintTraps {