Remove reloc_external from CodeSink
And introduce MachBufferFinalized::relocs() in the place.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -1448,19 +1448,16 @@ 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.
|
||||||
pub fn traps(&self) -> &[MachTrap] {
|
pub fn traps(&self) -> &[MachTrap] {
|
||||||
&self.traps[..]
|
&self.traps[..]
|
||||||
@@ -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)]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user