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:
Trevor Elliott
2022-08-31 14:41:44 -07:00
committed by GitHub
parent f18a1f1488
commit dde2c5a3b6
13 changed files with 81 additions and 15 deletions

View File

@@ -21,7 +21,6 @@ use std::ptr::NonNull;
use std::sync::atomic::{AtomicPtr, Ordering};
use target_lexicon::PointerWidth;
const EXECUTABLE_DATA_ALIGNMENT: u64 = 0x10;
const WRITABLE_DATA_ALIGNMENT: u64 = 0x8;
const READONLY_DATA_ALIGNMENT: u64 = 0x1;
@@ -234,7 +233,12 @@ impl JITModule {
let plt_entry = self
.memory
.code
.allocate(std::mem::size_of::<[u8; 16]>(), EXECUTABLE_DATA_ALIGNMENT)
.allocate(
std::mem::size_of::<[u8; 16]>(),
self.isa
.symbol_alignment()
.max(self.isa.function_alignment() as u64),
)
.unwrap()
.cast::<[u8; 16]>();
unsafe {
@@ -680,16 +684,20 @@ impl Module for JITModule {
}
// work around borrow-checker to allow reuse of ctx below
let _ = ctx.compile(self.isa())?;
let res = ctx.compile(self.isa())?;
let alignment = res.alignment as u64;
let compiled_code = ctx.compiled_code().unwrap();
let code_size = compiled_code.code_info().total_size;
let size = code_size as usize;
let align = alignment
.max(self.isa.function_alignment() as u64)
.max(self.isa.symbol_alignment());
let ptr = self
.memory
.code
.allocate(size, EXECUTABLE_DATA_ALIGNMENT)
.allocate(size, align)
.expect("TODO: handle OOM etc.");
{
@@ -745,6 +753,7 @@ impl Module for JITModule {
&mut self,
id: FuncId,
func: &ir::Function,
alignment: u64,
bytes: &[u8],
relocs: &[MachReloc],
) -> ModuleResult<ModuleCompiledFunction> {
@@ -764,10 +773,13 @@ impl Module for JITModule {
}
let size = bytes.len();
let align = alignment
.max(self.isa.function_alignment() as u64)
.max(self.isa.symbol_alignment());
let ptr = self
.memory
.code
.allocate(size, EXECUTABLE_DATA_ALIGNMENT)
.allocate(size, align)
.expect("TODO: handle OOM etc.");
unsafe {