Ensure functions are aligned properly on AArch64 (#3908)

Previously (as in an hour ago) #3905 landed a new ability for fuzzing to
arbitrarily insert padding between functions. Running some fuzzers
locally though this instantly hit a lot of problems on AArch64 because
the arbitrary padding isn't aligned to 4 bytes like all other functions
are. To fix this issue appending functions now correctly aligns the
output as appropriate for the platform. The alignment argument for
appending was switched to `None` where `None` means "use the platform
default" and otherwise and explicit alignment can be specified for
inserting other data (like arbitrary padding or Windows unwind tables).
This commit is contained in:
Alex Crichton
2022-03-09 15:45:30 -06:00
committed by GitHub
parent 1a54826ca8
commit 4d404c90b4
4 changed files with 11 additions and 9 deletions

View File

@@ -1616,7 +1616,7 @@ impl<I: VCodeInst> MachTextSectionBuilder<I> {
} }
impl<I: VCodeInst> TextSectionBuilder for MachTextSectionBuilder<I> { impl<I: VCodeInst> TextSectionBuilder for MachTextSectionBuilder<I> {
fn append(&mut self, named: bool, func: &[u8], align: u32) -> u64 { fn append(&mut self, named: bool, func: &[u8], align: Option<u32>) -> u64 {
// Conditionally emit an island if it's necessary to resolve jumps // Conditionally emit an island if it's necessary to resolve jumps
// between functions which are too far away. // between functions which are too far away.
let size = func.len() as u32; let size = func.len() as u32;
@@ -1624,7 +1624,7 @@ impl<I: VCodeInst> TextSectionBuilder for MachTextSectionBuilder<I> {
self.buf.emit_island_maybe_forced(self.force_veneers, size); self.buf.emit_island_maybe_forced(self.force_veneers, size);
} }
self.buf.align_to(align); self.buf.align_to(align.unwrap_or(I::LabelUse::ALIGN));
let pos = self.buf.cur_offset(); let pos = self.buf.cur_offset();
if named { if named {
self.buf.bind_label(MachLabel::from_block(self.next_func)); self.buf.bind_label(MachLabel::from_block(self.next_func));

View File

@@ -370,7 +370,7 @@ pub trait TextSectionBuilder {
/// ///
/// This function returns the offset at which the data was placed in the /// This function returns the offset at which the data was placed in the
/// text section. /// text section.
fn append(&mut self, labeled: bool, data: &[u8], align: u32) -> u64; fn append(&mut self, labeled: bool, data: &[u8], align: Option<u32>) -> u64;
/// Attempts to resolve a relocation for this function. /// Attempts to resolve a relocation for this function.
/// ///

View File

@@ -264,9 +264,11 @@ impl wasmtime_environ::Compiler for Compiler {
traps.push(range.clone(), &func.traps); traps.push(range.clone(), &func.traps);
func_starts.push(range.start); func_starts.push(range.start);
if self.linkopts.padding_between_functions > 0 { if self.linkopts.padding_between_functions > 0 {
builder builder.text.append(
.text false,
.append(false, &vec![0; self.linkopts.padding_between_functions], 1); &vec![0; self.linkopts.padding_between_functions],
Some(1),
);
} }
} }

View File

@@ -184,12 +184,12 @@ impl<'a> ObjectBuilder<'a> {
/// that the function resides within the text section. /// that the function resides within the text section.
fn append_func( fn append_func(
&mut self, &mut self,
wat: bool, labeled: bool,
name: Vec<u8>, name: Vec<u8>,
func: &'a CompiledFunction, func: &'a CompiledFunction,
) -> (SymbolId, Range<u64>) { ) -> (SymbolId, Range<u64>) {
let body_len = func.body.len() as u64; let body_len = func.body.len() as u64;
let off = self.text.append(wat, &func.body, 1); let off = self.text.append(labeled, &func.body, None);
let symbol_id = self.obj.add_symbol(Symbol { let symbol_id = self.obj.add_symbol(Symbol {
name, name,
@@ -215,7 +215,7 @@ impl<'a> ObjectBuilder<'a> {
let unwind_size = info.emit_size(); let unwind_size = info.emit_size();
let mut unwind_info = vec![0; unwind_size]; let mut unwind_info = vec![0; unwind_size];
info.emit(&mut unwind_info); info.emit(&mut unwind_info);
let unwind_off = self.text.append(false, &unwind_info, 4); let unwind_off = self.text.append(false, &unwind_info, Some(4));
self.windows_unwind_info.push(RUNTIME_FUNCTION { self.windows_unwind_info.push(RUNTIME_FUNCTION {
begin: u32::try_from(off).unwrap(), begin: u32::try_from(off).unwrap(),
end: u32::try_from(off + body_len).unwrap(), end: u32::try_from(off + body_len).unwrap(),