Add ability to relocate constants using RelocSink
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
||||||
use crate::binemit::stackmap::Stackmap;
|
use crate::binemit::stackmap::Stackmap;
|
||||||
use crate::ir::entities::Value;
|
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 crate::isa::TargetIsa;
|
||||||
use core::ptr::write_unaligned;
|
use core::ptr::write_unaligned;
|
||||||
|
|
||||||
@@ -78,6 +78,9 @@ pub trait RelocSink {
|
|||||||
/// Add a relocation referencing an external symbol at the current offset.
|
/// Add a relocation referencing an external symbol at the current offset.
|
||||||
fn reloc_external(&mut self, _: CodeOffset, _: Reloc, _: &ExternalName, _: Addend);
|
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.
|
/// Add a relocation referencing a jump table.
|
||||||
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable);
|
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);
|
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) {
|
fn reloc_jt(&mut self, rel: Reloc, jt: JumpTable) {
|
||||||
let ofs = self.offset();
|
let ofs = self.offset();
|
||||||
self.relocs.reloc_jt(ofs, rel, jt);
|
self.relocs.reloc_jt(ofs, rel, jt);
|
||||||
@@ -169,6 +177,7 @@ pub struct NullRelocSink {}
|
|||||||
impl RelocSink for NullRelocSink {
|
impl RelocSink for NullRelocSink {
|
||||||
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {}
|
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {}
|
||||||
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ExternalName, _: i64) {}
|
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) {}
|
fn reloc_jt(&mut self, _: u32, _: Reloc, _: JumpTable) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub use self::relaxation::relax_branches;
|
|||||||
pub use self::shrink::shrink_instructions;
|
pub use self::shrink::shrink_instructions;
|
||||||
pub use self::stackmap::Stackmap;
|
pub use self::stackmap::Stackmap;
|
||||||
use crate::ir::entities::Value;
|
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;
|
use crate::isa::TargetIsa;
|
||||||
pub use crate::regalloc::RegDiversions;
|
pub use crate::regalloc::RegDiversions;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
@@ -133,6 +133,9 @@ pub trait CodeSink {
|
|||||||
/// Add a relocation referencing an external symbol plus the addend at the current offset.
|
/// Add a relocation referencing an external symbol plus the addend at the current offset.
|
||||||
fn reloc_external(&mut self, _: Reloc, _: &ExternalName, _: Addend);
|
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.
|
/// Add a relocation referencing a jump table.
|
||||||
fn reloc_jt(&mut self, _: Reloc, _: JumpTable);
|
fn reloc_jt(&mut self, _: Reloc, _: JumpTable);
|
||||||
|
|
||||||
@@ -192,7 +195,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
sink.begin_rodata();
|
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();
|
sink.end_codegen();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ use crate::iterators::IteratorExtras;
|
|||||||
use crate::regalloc::RegDiversions;
|
use crate::regalloc::RegDiversions;
|
||||||
use crate::timing;
|
use crate::timing;
|
||||||
use crate::CodegenResult;
|
use crate::CodegenResult;
|
||||||
|
use core::convert::TryFrom;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
#[cfg(feature = "basic-blocks")]
|
#[cfg(feature = "basic-blocks")]
|
||||||
@@ -135,7 +136,11 @@ pub fn relax_branches(
|
|||||||
let jumptables_size = offset - jumptables;
|
let jumptables_size = offset - jumptables;
|
||||||
let rodata = offset;
|
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;
|
let rodata_size = offset - rodata;
|
||||||
|
|
||||||
|
|||||||
@@ -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)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
@@ -90,6 +90,10 @@ impl binemit::CodeSink for TextSink {
|
|||||||
write!(self.text, ") ").unwrap();
|
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) {
|
fn reloc_jt(&mut self, reloc: binemit::Reloc, jt: ir::JumpTable) {
|
||||||
write!(self.text, "{}({}) ", reloc, jt).unwrap();
|
write!(self.text, "{}({}) ", reloc, jt).unwrap();
|
||||||
}
|
}
|
||||||
@@ -313,7 +317,13 @@ impl SubTest for TestBinEmit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sink.begin_rodata();
|
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();
|
sink.end_codegen();
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ impl binemit::CodeSink for SizeSink {
|
|||||||
_addend: binemit::Addend,
|
_addend: binemit::Addend,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
fn reloc_constant(&mut self, _: binemit::Reloc, _: ir::ConstantOffset) {}
|
||||||
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
|
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
|
||||||
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
|
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
|
||||||
fn begin_jumptables(&mut self) {}
|
fn begin_jumptables(&mut self) {}
|
||||||
|
|||||||
@@ -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 {
|
struct SimpleJITStackmapSink {
|
||||||
|
|||||||
@@ -56,6 +56,22 @@ impl binemit::RelocSink for PrintRelocs {
|
|||||||
write!(&mut self.text, "reloc_jt: {} {} at {}\n", r, jt, where_).unwrap();
|
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 {
|
pub struct PrintTraps {
|
||||||
|
|||||||
Reference in New Issue
Block a user