Record information about sections of emitted code+data.
The result of the emitter is a vector of bytes holding machine code, jump tables, and (in the future) other read-only data. Some clients, notably Firefox's Wasm compiler, needs to separate the machine code from the data in order to insert more code directly after the code generated by Cranelift. To make such separation possible, we record more information about the emitted bytes: the sizes of each of the sections of code, jump tables, and read-only data, as well as the locations within the code that reference (PC-relatively) the jump tables and read-only data.
This commit is contained in:
committed by
Lars T Hansen
parent
70f79d23bf
commit
420850adf0
@@ -33,6 +33,8 @@ pub enum Reloc {
|
||||
Abs8,
|
||||
/// x86 PC-relative 4-byte
|
||||
X86PCRel4,
|
||||
/// x86 PC-relative 4-byte offset to trailing rodata
|
||||
X86PCRelRodata4,
|
||||
/// x86 call to PC-relative 4-byte
|
||||
X86CallPCRel4,
|
||||
/// x86 call to PLT-relative 4-byte
|
||||
@@ -55,6 +57,7 @@ impl fmt::Display for Reloc {
|
||||
Reloc::Abs4 => write!(f, "Abs4"),
|
||||
Reloc::Abs8 => write!(f, "Abs8"),
|
||||
Reloc::X86PCRel4 => write!(f, "PCRel4"),
|
||||
Reloc::X86PCRelRodata4 => write!(f, "PCRelRodata4"),
|
||||
Reloc::X86CallPCRel4 => write!(f, "CallPCRel4"),
|
||||
Reloc::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
|
||||
Reloc::X86GOTPCRel4 => write!(f, "GOTPCRel4"),
|
||||
@@ -63,6 +66,38 @@ impl fmt::Display for Reloc {
|
||||
}
|
||||
}
|
||||
|
||||
/// Container for information about a vector of compiled code and its supporting read-only data.
|
||||
///
|
||||
/// The code starts at offset 0 and is followed optionally by relocatable jump tables and copyable
|
||||
/// (raw binary) read-only data. Any padding between sections is always part of the section that
|
||||
/// precedes the boundary between the sections.
|
||||
#[derive(PartialEq)]
|
||||
pub struct CodeInfo {
|
||||
/// Number of bytes of machine code (the code starts at offset 0).
|
||||
pub code_size: CodeOffset,
|
||||
|
||||
/// Number of bytes of jumptables.
|
||||
pub jumptables_size: CodeOffset,
|
||||
|
||||
/// Number of bytes of rodata.
|
||||
pub rodata_size: CodeOffset,
|
||||
|
||||
/// Number of bytes in total.
|
||||
pub total_size: CodeOffset,
|
||||
}
|
||||
|
||||
impl CodeInfo {
|
||||
/// Offset of any relocatable jump tables, or equal to rodata if there are no jump tables.
|
||||
pub fn jumptables(&self) -> CodeOffset {
|
||||
self.code_size
|
||||
}
|
||||
|
||||
/// Offset of any copyable read-only data, or equal to total_size if there are no rodata.
|
||||
pub fn rodata(&self) -> CodeOffset {
|
||||
self.code_size + self.jumptables_size
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstract interface for adding bytes to the code segment.
|
||||
///
|
||||
/// A `CodeSink` will receive all of the machine code for a function. It also accepts relocations
|
||||
@@ -95,8 +130,14 @@ pub trait CodeSink {
|
||||
/// Add trap information for the current offset.
|
||||
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
||||
|
||||
/// Code output is complete, read-only data may follow.
|
||||
/// Machine code output is complete, jump table data may follow.
|
||||
fn begin_jumptables(&mut self);
|
||||
|
||||
/// Jump table output is complete, raw read-only data may follow.
|
||||
fn begin_rodata(&mut self);
|
||||
|
||||
/// Read-only data output is complete, we're done.
|
||||
fn end_codegen(&mut self);
|
||||
}
|
||||
|
||||
/// Report a bad encoding error.
|
||||
@@ -127,7 +168,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
sink.begin_rodata();
|
||||
sink.begin_jumptables();
|
||||
|
||||
// output jump tables
|
||||
for (jt, jt_data) in func.jump_tables.iter() {
|
||||
@@ -137,4 +178,9 @@ where
|
||||
sink.put4(rel_offset as u32)
|
||||
}
|
||||
}
|
||||
|
||||
sink.begin_rodata();
|
||||
// TODO: No read-only data (constant pools) at this time.
|
||||
|
||||
sink.end_codegen();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user