diff --git a/macho/chunks/chained_fixups.rs b/macho/chunks/chained_fixups.rs index 30739a31e..588e469bd 100644 --- a/macho/chunks/chained_fixups.rs +++ b/macho/chunks/chained_fixups.rs @@ -12,6 +12,7 @@ use crate::fatal; use crate::input_files::{FileId, data_blob_binds, data_blob_pointers}; use crate::macho::*; use crate::symbol::{Symbol, SymbolId}; +use crate::util::{push16, push32, push64}; #[derive(Debug)] pub struct ChainedFixupsSection { @@ -97,18 +98,6 @@ pub(crate) fn pointer_format(ctx: &Context) -> u16 { } } -fn push16(buf: &mut Vec, val: u16) { - buf.extend_from_slice(&val.to_le_bytes()); -} - -fn push32(buf: &mut Vec, val: u32) { - buf.extend_from_slice(&val.to_le_bytes()); -} - -fn push64(buf: &mut Vec, val: u64) { - buf.extend_from_slice(&val.to_le_bytes()); -} - fn pad(buf: &mut Vec, align: usize) { buf.resize(buf.len().next_multiple_of(align), 0); } diff --git a/macho/chunks/unwind_info.rs b/macho/chunks/unwind_info.rs index 01e660f61..982c79ed0 100644 --- a/macho/chunks/unwind_info.rs +++ b/macho/chunks/unwind_info.rs @@ -9,6 +9,7 @@ use crate::context::Context; use crate::input_sections::{InputSection, UnwindRecord}; use crate::macho::*; use crate::symbol::SymbolId; +use crate::util::{push16, push32}; #[derive(Debug)] pub struct UnwindInfoSection { @@ -266,8 +267,6 @@ fn write_table( let lsda_off = page1_off + (pages.len() + 1) * 12; let page2_off = lsda_off + num_lsda * 8; - let push32 = |buf: &mut Vec, val: u32| buf.extend_from_slice(&val.to_le_bytes()); - let mut buf = Vec::new(); push32(&mut buf, UNWIND_SECTION_VERSION); push32(&mut buf, personality_off as u32); @@ -325,8 +324,6 @@ fn encode_page(ctx: &Context, records: &[UnwindRecord], page: &Pag let base = ctx.mach_header.hdr.addr; let span = &records[page.records.clone()]; let encs = &page.encodings; - let push32 = |buf: &mut Vec, val: u32| buf.extend_from_slice(&val.to_le_bytes()); - let push16 = |buf: &mut Vec, val: u16| buf.extend_from_slice(&val.to_le_bytes()); let mut lsda = Vec::new(); for rec in span { diff --git a/macho/dtrace.rs b/macho/dtrace.rs index a42a4510a..716d28896 100644 --- a/macho/dtrace.rs +++ b/macho/dtrace.rs @@ -34,7 +34,7 @@ use crate::input_files::add_synthetic_section; use crate::input_sections::{InputSection, Reloc, RelocTarget}; use crate::macho::*; use crate::symbol::SymbolId; -use crate::util::split_once; +use crate::util::{push16, push32, push64, split_once}; /// The prefix of the names of the symbols a `dtrace -h` header makes /// code refer to. ld-prime takes every undefined symbol whose name @@ -525,9 +525,9 @@ impl ProbeTables { let offidx = t.sites.len() as u32; put_u32s(&mut t.records, &[func, name, nargv, xargv, argidx, offidx]); t.records.extend_from_slice(&[nargc, nargc]); - t.records.extend_from_slice(&(inst.sites.len() as u16).to_le_bytes()); + push16(&mut t.records, inst.sites.len() as u16); put_u32s(&mut t.records, &[t.tests.len() as u32]); - t.records.extend_from_slice(&(inst.tests.len() as u16).to_le_bytes()); + push16(&mut t.records, inst.tests.len() as u16); t.records.extend_from_slice(&[0; 6]); t.sites.extend(&inst.sites); t.tests.extend(&inst.tests); @@ -599,14 +599,14 @@ fn lay_out_dof( } fn put_u32s(out: &mut Vec, vals: &[u32]) { - for v in vals { - out.extend_from_slice(&v.to_le_bytes()); + for &v in vals { + push32(out, v); } } fn put_u64s(out: &mut Vec, vals: &[u64]) { - for v in vals { - out.extend_from_slice(&v.to_le_bytes()); + for &v in vals { + push64(out, v); } } diff --git a/macho/util/mod.rs b/macho/util/mod.rs index b883e6de6..b0e3b6a90 100644 --- a/macho/util/mod.rs +++ b/macho/util/mod.rs @@ -63,6 +63,21 @@ pub fn write64(loc: &mut [u8], val: u64) { loc[..8].copy_from_slice(&val.to_le_bytes()); } +// Little-endian appends of an integer to a buffer: the fields of the +// tables the linker builds in full before writing them out (the chained +// fixups, the unwind info, a DOF section). +pub fn push16(buf: &mut Vec, val: u16) { + buf.extend_from_slice(&val.to_le_bytes()); +} + +pub fn push32(buf: &mut Vec, val: u32) { + buf.extend_from_slice(&val.to_le_bytes()); +} + +pub fn push64(buf: &mut Vec, val: u64) { + buf.extend_from_slice(&val.to_le_bytes()); +} + /// A sort key that orders byte strings like the strings themselves but /// settles most comparisons on one integer: the first eight bytes, /// big-endian, zero-padded. Symbol names cannot contain NULs, so