Remove reloc_external from CodeSink

And introduce MachBufferFinalized::relocs() in the place.
This commit is contained in:
bjorn3
2022-01-11 16:54:27 +01:00
parent 63e2360346
commit a48a60f958
6 changed files with 38 additions and 61 deletions

View File

@@ -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 /// 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. /// 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. /// Pointer to start of sink's preallocated memory.
data: *mut u8, data: *mut u8,
/// Offset is isize because its major consumer needs it in that form. /// Offset is isize because its major consumer needs it in that form.
offset: isize, 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`. /// Create a new memory code sink that writes a function to the memory pointed to by `data`.
/// ///
/// # Safety /// # Safety
/// ///
/// This function is unsafe since `MemoryCodeSink` does not perform bounds checking on the /// 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. /// memory buffer, and it can't guarantee that the `data` pointer is valid.
pub unsafe fn new( pub unsafe fn new(data: *mut u8) -> Self {
data: *mut u8, Self { data, offset: 0 }
relocs: &'a mut dyn RelocSink,
) -> Self {
Self {
data,
offset: 0,
relocs,
}
} }
/// Information about the generated code and read-only data. /// Information about the generated code and read-only data.
@@ -85,24 +77,13 @@ pub trait TrapSink {
fn trap(&mut self, _: CodeOffset, _: SourceLoc, _: TrapCode); fn trap(&mut self, _: CodeOffset, _: SourceLoc, _: TrapCode);
} }
impl<'a> CodeSink for MemoryCodeSink<'a> { impl CodeSink for MemoryCodeSink {
fn put1(&mut self, x: u8) { fn put1(&mut self, x: u8) {
unsafe { unsafe {
write_unaligned(self.data.offset(self.offset), x); write_unaligned(self.data.offset(self.offset), x);
self.offset += 1; 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 /// A `RelocSink` implementation that does nothing, which is convenient when

View File

@@ -11,7 +11,6 @@ pub use self::memorysink::{
TrapSink, TrapSink,
}; };
pub use self::stack_map::StackMap; pub use self::stack_map::StackMap;
use crate::ir::{ExternalName, SourceLoc};
use core::fmt; use core::fmt;
#[cfg(feature = "enable-serde")] #[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -107,7 +106,4 @@ pub struct CodeInfo {
pub trait CodeSink { pub trait CodeSink {
/// Add 1 byte to the code section. /// Add 1 byte to the code section.
fn put1(&mut self, _: u8); 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);
} }

View File

@@ -18,7 +18,7 @@ use crate::isa::TargetIsa;
use crate::legalizer::simple_legalize; use crate::legalizer::simple_legalize;
use crate::licm::do_licm; use crate::licm::do_licm;
use crate::loop_analysis::LoopAnalysis; 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::nan_canonicalization::do_nan_canonicalization;
use crate::remove_constant_phis::do_remove_constant_phis; use crate::remove_constant_phis::do_remove_constant_phis;
use crate::result::CodegenResult; use crate::result::CodegenResult;
@@ -194,13 +194,23 @@ impl Context {
stack_maps: &mut dyn StackMapSink, stack_maps: &mut dyn StackMapSink,
) -> CodeInfo { ) -> CodeInfo {
let _tt = timing::binemit(); let _tt = timing::binemit();
let mut sink = MemoryCodeSink::new(mem, relocs); let mut sink = MemoryCodeSink::new(mem);
let result = self let result = self
.mach_compile_result .mach_compile_result
.as_ref() .as_ref()
.expect("only using mach backend now"); .expect("only using mach backend now");
result.buffer.emit(&mut sink); result.buffer.emit(&mut sink);
let info = sink.info(); 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 { for &MachTrap {
offset, offset,
srcloc, srcloc,

View File

@@ -88,7 +88,7 @@ pub mod verifier;
pub mod write; pub mod write;
pub use crate::entity::packed_option; 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; pub use crate::machinst::TextSectionBuilder;
mod bitset; mod bitset;

View File

@@ -1448,17 +1448,14 @@ impl MachBufferFinalized {
// add this designation and segregate the output; take care, however, // add this designation and segregate the output; take care, however,
// to add the appropriate relocations in this case. // to add the appropriate relocations in this case.
let mut next_reloc = 0; for &byte in self.data.iter() {
for (idx, byte) in self.data.iter().enumerate() { sink.put1(byte);
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);
} }
/// 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. /// Get the list of trap records for this code.
@@ -1504,18 +1501,18 @@ struct MachLabelFixup<I: VCodeInst> {
} }
/// A relocation resulting from a compilation. /// A relocation resulting from a compilation.
struct MachReloc { pub struct MachReloc {
/// The offset at which the relocation applies, *relative to the /// The offset at which the relocation applies, *relative to the
/// containing section*. /// containing section*.
offset: CodeOffset, pub offset: CodeOffset,
/// The original source location. /// The original source location.
srcloc: SourceLoc, pub srcloc: SourceLoc,
/// The kind of relocation. /// The kind of relocation.
kind: Reloc, pub kind: Reloc,
/// The external symbol / name to which this relocation refers. /// The external symbol / name to which this relocation refers.
name: ExternalName, pub name: ExternalName,
/// The addend to add to the symbol value. /// The addend to add to the symbol value.
addend: i64, pub addend: i64,
} }
/// A trap record resulting from a compilation. /// A trap record resulting from a compilation.
@@ -2072,15 +2069,11 @@ mod test {
#[derive(Default)] #[derive(Default)]
struct TestCodeSink { struct TestCodeSink {
offset: CodeOffset, offset: CodeOffset,
relocs: Vec<(CodeOffset, Reloc)>,
} }
impl CodeSink for TestCodeSink { impl CodeSink for TestCodeSink {
fn put1(&mut self, _: u8) { fn put1(&mut self, _: u8) {
self.offset += 1; self.offset += 1;
} }
fn reloc_external(&mut self, _: SourceLoc, r: Reloc, _: &ExternalName, _: Addend) {
self.relocs.push((self.offset, r));
}
} }
let mut sink = TestCodeSink::default(); let mut sink = TestCodeSink::default();
@@ -2105,6 +2098,12 @@ mod test {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
vec![(2, Opcode::Call)] 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<_>>(),
vec![(2, Reloc::Abs4), (3, Reloc::Abs8)]
);
} }
} }

View File

@@ -84,15 +84,6 @@ impl binemit::CodeSink for SizeSink {
fn put1(&mut self, _: u8) { fn put1(&mut self, _: u8) {
self.offset += 1; 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<()> { fn check_precise_output(text: &str, context: &Context) -> Result<()> {