diff --git a/cranelift/codegen/src/binemit/memorysink.rs b/cranelift/codegen/src/binemit/memorysink.rs index d462dd7000..651921609f 100644 --- a/cranelift/codegen/src/binemit/memorysink.rs +++ b/cranelift/codegen/src/binemit/memorysink.rs @@ -29,30 +29,22 @@ use core::ptr::write_unaligned; /// /// Note that `MemoryCodeSink` writes multi-byte values in the native byte order of the host. This /// is not the right thing to do for cross compilation. -pub struct MemoryCodeSink<'a> { +pub struct MemoryCodeSink { /// Pointer to start of sink's preallocated memory. data: *mut u8, /// Offset is isize because its major consumer needs it in that form. offset: isize, - relocs: &'a mut dyn RelocSink, } -impl<'a> MemoryCodeSink<'a> { +impl<'a> MemoryCodeSink { /// Create a new memory code sink that writes a function to the memory pointed to by `data`. /// /// # Safety /// /// This function is unsafe since `MemoryCodeSink` does not perform bounds checking on the /// memory buffer, and it can't guarantee that the `data` pointer is valid. - pub unsafe fn new( - data: *mut u8, - relocs: &'a mut dyn RelocSink, - ) -> Self { - Self { - data, - offset: 0, - relocs, - } + pub unsafe fn new(data: *mut u8) -> Self { + Self { data, offset: 0 } } /// Information about the generated code and read-only data. @@ -85,24 +77,13 @@ pub trait TrapSink { fn trap(&mut self, _: CodeOffset, _: SourceLoc, _: TrapCode); } -impl<'a> CodeSink for MemoryCodeSink<'a> { +impl CodeSink for MemoryCodeSink { fn put1(&mut self, x: u8) { unsafe { write_unaligned(self.data.offset(self.offset), x); self.offset += 1; } } - - fn reloc_external( - &mut self, - srcloc: SourceLoc, - rel: Reloc, - name: &ExternalName, - addend: Addend, - ) { - let ofs = self.offset as CodeOffset; - self.relocs.reloc_external(ofs, srcloc, rel, name, addend); - } } /// A `RelocSink` implementation that does nothing, which is convenient when diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index 8fe228789f..2bb800976f 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -11,7 +11,6 @@ pub use self::memorysink::{ TrapSink, }; pub use self::stack_map::StackMap; -use crate::ir::{ExternalName, SourceLoc}; use core::fmt; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -107,7 +106,4 @@ pub struct CodeInfo { pub trait CodeSink { /// Add 1 byte to the code section. fn put1(&mut self, _: u8); - - /// Add a relocation referencing an external symbol plus the addend at the current offset. - fn reloc_external(&mut self, _: SourceLoc, _: Reloc, _: &ExternalName, _: Addend); } diff --git a/cranelift/codegen/src/context.rs b/cranelift/codegen/src/context.rs index fecf0a852b..c896c8e737 100644 --- a/cranelift/codegen/src/context.rs +++ b/cranelift/codegen/src/context.rs @@ -18,7 +18,7 @@ use crate::isa::TargetIsa; use crate::legalizer::simple_legalize; use crate::licm::do_licm; use crate::loop_analysis::LoopAnalysis; -use crate::machinst::{MachCompileResult, MachStackMap, MachTrap}; +use crate::machinst::{MachCompileResult, MachReloc, MachStackMap, MachTrap}; use crate::nan_canonicalization::do_nan_canonicalization; use crate::remove_constant_phis::do_remove_constant_phis; use crate::result::CodegenResult; @@ -194,13 +194,23 @@ impl Context { stack_maps: &mut dyn StackMapSink, ) -> CodeInfo { let _tt = timing::binemit(); - let mut sink = MemoryCodeSink::new(mem, relocs); + let mut sink = MemoryCodeSink::new(mem); let result = self .mach_compile_result .as_ref() .expect("only using mach backend now"); result.buffer.emit(&mut sink); let info = sink.info(); + for &MachReloc { + offset, + srcloc, + kind, + ref name, + addend, + } in result.buffer.relocs() + { + relocs.reloc_external(offset, srcloc, kind, name, addend); + } for &MachTrap { offset, srcloc, diff --git a/cranelift/codegen/src/lib.rs b/cranelift/codegen/src/lib.rs index 7e14b5380c..e860990372 100644 --- a/cranelift/codegen/src/lib.rs +++ b/cranelift/codegen/src/lib.rs @@ -88,7 +88,7 @@ pub mod verifier; pub mod write; pub use crate::entity::packed_option; -pub use crate::machinst::buffer::{MachCallSite, MachSrcLoc, MachTrap}; +pub use crate::machinst::buffer::{MachCallSite, MachReloc, MachSrcLoc, MachTrap}; pub use crate::machinst::TextSectionBuilder; mod bitset; diff --git a/cranelift/codegen/src/machinst/buffer.rs b/cranelift/codegen/src/machinst/buffer.rs index 6f73649ff4..6c38297a33 100644 --- a/cranelift/codegen/src/machinst/buffer.rs +++ b/cranelift/codegen/src/machinst/buffer.rs @@ -1448,19 +1448,16 @@ impl MachBufferFinalized { // add this designation and segregate the output; take care, however, // to add the appropriate relocations in this case. - let mut next_reloc = 0; - for (idx, byte) in self.data.iter().enumerate() { - while next_reloc < self.relocs.len() - && self.relocs[next_reloc].offset == idx as CodeOffset - { - let reloc = &self.relocs[next_reloc]; - sink.reloc_external(reloc.srcloc, reloc.kind, &reloc.name, reloc.addend); - next_reloc += 1; - } - sink.put1(*byte); + for &byte in self.data.iter() { + sink.put1(byte); } } + /// Get the list of external relocations for this code. + pub fn relocs(&self) -> &[MachReloc] { + &self.relocs[..] + } + /// Get the list of trap records for this code. pub fn traps(&self) -> &[MachTrap] { &self.traps[..] @@ -1504,18 +1501,18 @@ struct MachLabelFixup { } /// A relocation resulting from a compilation. -struct MachReloc { +pub struct MachReloc { /// The offset at which the relocation applies, *relative to the /// containing section*. - offset: CodeOffset, + pub offset: CodeOffset, /// The original source location. - srcloc: SourceLoc, + pub srcloc: SourceLoc, /// The kind of relocation. - kind: Reloc, + pub kind: Reloc, /// The external symbol / name to which this relocation refers. - name: ExternalName, + pub name: ExternalName, /// The addend to add to the symbol value. - addend: i64, + pub addend: i64, } /// A trap record resulting from a compilation. @@ -2072,15 +2069,11 @@ mod test { #[derive(Default)] struct TestCodeSink { offset: CodeOffset, - relocs: Vec<(CodeOffset, Reloc)>, } impl CodeSink for TestCodeSink { fn put1(&mut self, _: u8) { self.offset += 1; } - fn reloc_external(&mut self, _: SourceLoc, r: Reloc, _: &ExternalName, _: Addend) { - self.relocs.push((self.offset, r)); - } } let mut sink = TestCodeSink::default(); @@ -2105,6 +2098,12 @@ mod test { .collect::>(), vec![(2, Opcode::Call)] ); - assert_eq!(sink.relocs, vec![(2, Reloc::Abs4), (3, Reloc::Abs8)]); + assert_eq!( + buf.relocs() + .iter() + .map(|reloc| (reloc.offset, reloc.kind)) + .collect::>(), + vec![(2, Reloc::Abs4), (3, Reloc::Abs8)] + ); } } diff --git a/cranelift/filetests/src/test_compile.rs b/cranelift/filetests/src/test_compile.rs index c059f60d7d..cadc016dc1 100644 --- a/cranelift/filetests/src/test_compile.rs +++ b/cranelift/filetests/src/test_compile.rs @@ -84,15 +84,6 @@ impl binemit::CodeSink for SizeSink { fn put1(&mut self, _: u8) { self.offset += 1; } - - fn reloc_external( - &mut self, - _srcloc: ir::SourceLoc, - _reloc: binemit::Reloc, - _name: &ir::ExternalName, - _addend: binemit::Addend, - ) { - } } fn check_precise_output(text: &str, context: &Context) -> Result<()> {