jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
use super::load_cmd::*;
use crate::prelude::*;
const SUPER_BLOB_SIZE: u32 = 0x14;
const IDENT_OFF: u32 = 0x58;
const HASH_OFF: u32 = IDENT_OFF + 2;
#[expect(clippy::arbitrary_source_item_ordering)]
pub(crate) struct LinkEdit {
  pub rebase: Vec<u8>,
  pub bind: Vec<u8>,
  pub lazy: Vec<u8>,
  pub indirect: Vec<u32>,
  pub sym_tab: Vec<u8>,
  pub sym_str: Vec<u8>,
  pub sym_type_idx: [(u32, u32); 3],
}
pub(crate) struct LinkEditOutput {
  pub bytes: Vec<u8>,
  pub code_limit: u32,
  pub lc_code_sign: LoadCmd,
  pub lc_dy_symtab: LoadCmd,
  pub lc_dyld_info_only: LoadCmd,
  pub lc_symtab: LoadCmd,
}
impl LinkEdit {
  pub(crate) fn build(&self, l_e_off: u32, text_file_size: u64) -> ErrOR<LinkEditOutput> {
    fn add_link_edit(vec: &mut Vec<u8>, data: &[u8], align: usize) -> ErrOR<u32> {
      let len = len_u32(vec)?;
      vec.extend_from_slice(data);
      vec.resize(align_up(len as usize + data.len(), align)?, 0);
      Ok(len)
    }
    let mut bytes = vec![];
    let rebase_off = add_link_edit(&mut bytes, &self.rebase, 8)?;
    let bind_off = add_link_edit(&mut bytes, &self.bind, 8)?;
    let lazy_off = add_link_edit(&mut bytes, &self.lazy, 8)?;
    let indirect: Vec<u8> = self.indirect.iter().flat_map(|idx| idx.to_le_bytes()).collect();
    let indirect_off = add_link_edit(&mut bytes, &indirect, 8)?;
    let n_indirect = len_u32(&self.indirect)?;
    let sym_tab_off = add_link_edit(&mut bytes, &self.sym_tab, 8)?;
    let symtab_len = len_u32(&self.sym_tab)?;
    let n_syms = symtab_len / 0x10;
    let str_off = add_link_edit(&mut bytes, &self.sym_str, 16)?;
    let code_sign_off = len_u32(&bytes)?;
    let code_limit = l_e_off + code_sign_off;
    let code_slot = code_limit.div_ceil(A64_PAGE_SIZE);
    let code_sign_size = SUPER_BLOB_SIZE + HASH_OFF + code_slot * 0x20;
    let code_sign = cat_vec!(
      code_sign_size as usize,
      0xFADE0CC0u32.to_be_bytes(),
      code_sign_size.to_be_bytes(),
      1u32.to_be_bytes(),
      [0; 4],
      SUPER_BLOB_SIZE.to_be_bytes(),
      0xFADE0C02u32.to_be_bytes(),
      (code_sign_size - SUPER_BLOB_SIZE).to_be_bytes(),
      0x20400u32.to_be_bytes(),
      2u32.to_be_bytes(),
      HASH_OFF.to_be_bytes(),
      IDENT_OFF.to_be_bytes(),
      [0; 4],
      code_slot.to_be_bytes(),
      code_limit.to_be_bytes(),
      [0x20, 2, 0, A64_PAGE_SHIFT],
      [0; 0x18],
      0u64.to_be_bytes(),
      text_file_size.to_be_bytes(),
      1u64.to_be_bytes(),
      [0x20, 0],
    );
    add_link_edit(&mut bytes, &code_sign, 1)?;
    let dyld_info = [
      Some((l_e_off + rebase_off, len_u32(&self.rebase)?)),
      Some((l_e_off + bind_off, len_u32(&self.bind)?)),
      None,
      Some((l_e_off + lazy_off, len_u32(&self.lazy)?)),
      None,
    ];
    Ok(LinkEditOutput {
      bytes,
      code_limit,
      lc_code_sign: CodeSign(l_e_off + code_sign_off, code_sign_size),
      lc_dyld_info_only: DyldInfoOnly(dyld_info),
      lc_symtab: Symtab(l_e_off + sym_tab_off, n_syms, l_e_off + str_off, len_u32(&self.sym_str)?),
      lc_dy_symtab: DySymtab(self.sym_type_idx, (l_e_off + indirect_off, n_indirect)),
    })
  }
  pub(crate) fn sizeof(&self, l_e_off: u32) -> ErrOR<u32> {
    let mut code_limit = l_e_off;
    code_limit += align_up_u32(len_u32(&self.rebase)?, 8)?;
    code_limit += align_up_u32(len_u32(&self.bind)?, 8)?;
    code_limit += align_up_u32(len_u32(&self.lazy)?, 8)?;
    code_limit += align_up_u32(len_u32(&self.indirect)? * 4, 8)?;
    code_limit += len_u32(&self.sym_tab)?;
    code_limit = align_up_u32(code_limit + len_u32(&self.sym_str)?, 16)?;
    let code_slot = code_limit.div_ceil(A64_PAGE_SIZE);
    let code_sign_size = SUPER_BLOB_SIZE + HASH_OFF + code_slot * 0x20;
    Ok(code_limit + code_sign_size - l_e_off)
  }
}