Align functions according to their ISA's requirements (#4826)
Add a function_alignment function to the TargetIsa trait, and use it to align functions when generating objects. Additionally, collect the maximum alignment required for pc-relative constants in functions and pass that value out. Use the max of these two values when padding functions for alignment. This fixes a bug on x86_64 where rip-relative loads to sse registers could cause a segfault, as functions weren't always guaranteed to be aligned to 16-byte addresses. Fixes #4812
This commit is contained in:
@@ -314,11 +314,13 @@ impl Module for ObjectModule {
|
||||
info!("defining function {}: {}", func_id, ctx.func.display());
|
||||
let mut code: Vec<u8> = Vec::new();
|
||||
|
||||
ctx.compile_and_emit(self.isa(), &mut code)?;
|
||||
let res = ctx.compile_and_emit(self.isa(), &mut code)?;
|
||||
let alignment = res.alignment as u64;
|
||||
|
||||
self.define_function_bytes(
|
||||
func_id,
|
||||
&ctx.func,
|
||||
alignment,
|
||||
&code,
|
||||
ctx.compiled_code().unwrap().buffer.relocs(),
|
||||
)
|
||||
@@ -328,6 +330,7 @@ impl Module for ObjectModule {
|
||||
&mut self,
|
||||
func_id: FuncId,
|
||||
func: &ir::Function,
|
||||
alignment: u64,
|
||||
bytes: &[u8],
|
||||
relocs: &[MachReloc],
|
||||
) -> ModuleResult<ModuleCompiledFunction> {
|
||||
@@ -348,7 +351,10 @@ impl Module for ObjectModule {
|
||||
}
|
||||
*defined = true;
|
||||
|
||||
let align = std::cmp::max(self.function_alignment, self.isa.symbol_alignment());
|
||||
let align = self
|
||||
.function_alignment
|
||||
.max(self.isa.symbol_alignment())
|
||||
.max(alignment);
|
||||
let (section, offset) = if self.per_function_section {
|
||||
let symbol_name = self.object.symbol(symbol).name.clone();
|
||||
let (section, offset) =
|
||||
|
||||
Reference in New Issue
Block a user