mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-11 10:55:31 +03:00
Correct use of NativeEndian to LittleEndian
This should specify the endian read from and written to. In our case, we are using elf/macho. So, the endian is always little.
This commit is contained in:
parent
8a76937cff
commit
e88d759331
@ -2,9 +2,9 @@ use iced_x86::{Decoder, DecoderOptions, Instruction, OpCodeOperandKind, OpKind};
|
||||
use memmap2::MmapMut;
|
||||
use object::{elf, endian};
|
||||
use object::{
|
||||
CompressedFileRange, CompressionFormat, LittleEndian as LE, NativeEndian, Object,
|
||||
ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget, Section, SectionIndex,
|
||||
SectionKind, Symbol, SymbolIndex, SymbolSection,
|
||||
CompressedFileRange, CompressionFormat, LittleEndian as LE, Object, ObjectSection,
|
||||
ObjectSymbol, RelocationKind, RelocationTarget, Section, SectionIndex, SectionKind, Symbol,
|
||||
SymbolIndex, SymbolSection,
|
||||
};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_error_macros::{internal_error, user_error};
|
||||
@ -517,12 +517,12 @@ fn gen_elf_le(
|
||||
verbose: bool,
|
||||
) -> MmapMut {
|
||||
let exec_header = load_struct_inplace::<elf::FileHeader64<LE>>(exec_data, 0);
|
||||
let ph_offset = exec_header.e_phoff.get(NativeEndian);
|
||||
let ph_ent_size = exec_header.e_phentsize.get(NativeEndian);
|
||||
let ph_num = exec_header.e_phnum.get(NativeEndian);
|
||||
let sh_offset = exec_header.e_shoff.get(NativeEndian);
|
||||
let sh_ent_size = exec_header.e_shentsize.get(NativeEndian);
|
||||
let sh_num = exec_header.e_shnum.get(NativeEndian);
|
||||
let ph_offset = exec_header.e_phoff.get(LE);
|
||||
let ph_ent_size = exec_header.e_phentsize.get(LE);
|
||||
let ph_num = exec_header.e_phnum.get(LE);
|
||||
let sh_offset = exec_header.e_shoff.get(LE);
|
||||
let sh_ent_size = exec_header.e_shentsize.get(LE);
|
||||
let sh_num = exec_header.e_shnum.get(LE);
|
||||
|
||||
if verbose {
|
||||
println!();
|
||||
@ -555,11 +555,11 @@ fn gen_elf_le(
|
||||
let mut first_load_found = false;
|
||||
let mut virtual_shift_start = 0;
|
||||
for ph in program_headers.iter() {
|
||||
let p_type = ph.p_type.get(NativeEndian);
|
||||
if p_type == elf::PT_LOAD && ph.p_offset.get(NativeEndian) == 0 {
|
||||
let p_type = ph.p_type.get(LE);
|
||||
if p_type == elf::PT_LOAD && ph.p_offset.get(LE) == 0 {
|
||||
first_load_found = true;
|
||||
md.load_align_constraint = ph.p_align.get(NativeEndian);
|
||||
virtual_shift_start = physical_shift_start + ph.p_vaddr.get(NativeEndian);
|
||||
md.load_align_constraint = ph.p_align.get(LE);
|
||||
virtual_shift_start = physical_shift_start + ph.p_vaddr.get(LE);
|
||||
}
|
||||
}
|
||||
if !first_load_found {
|
||||
@ -574,18 +574,18 @@ fn gen_elf_le(
|
||||
|
||||
// Shift all of the program headers.
|
||||
for ph in program_headers.iter_mut() {
|
||||
let p_type = ph.p_type.get(NativeEndian);
|
||||
let p_offset = ph.p_offset.get(NativeEndian);
|
||||
let p_type = ph.p_type.get(LE);
|
||||
let p_offset = ph.p_offset.get(LE);
|
||||
if (p_type == elf::PT_LOAD && p_offset == 0) || p_type == elf::PT_PHDR {
|
||||
// Extend length for the first segment and the program header.
|
||||
ph.p_filesz = endian::U64::new(LE, ph.p_filesz.get(NativeEndian) + md.added_byte_count);
|
||||
ph.p_memsz = endian::U64::new(LE, ph.p_memsz.get(NativeEndian) + md.added_byte_count);
|
||||
ph.p_filesz = endian::U64::new(LE, ph.p_filesz.get(LE) + md.added_byte_count);
|
||||
ph.p_memsz = endian::U64::new(LE, ph.p_memsz.get(LE) + md.added_byte_count);
|
||||
} else {
|
||||
// Shift if needed.
|
||||
if physical_shift_start <= p_offset {
|
||||
ph.p_offset = endian::U64::new(LE, p_offset + md.added_byte_count);
|
||||
}
|
||||
let p_vaddr = ph.p_vaddr.get(NativeEndian);
|
||||
let p_vaddr = ph.p_vaddr.get(LE);
|
||||
if virtual_shift_start <= p_vaddr {
|
||||
ph.p_vaddr = endian::U64::new(LE, p_vaddr + md.added_byte_count);
|
||||
ph.p_paddr = endian::U64::new(LE, p_vaddr + md.added_byte_count);
|
||||
@ -597,8 +597,8 @@ fn gen_elf_le(
|
||||
let last_segment_vaddr = program_headers
|
||||
.iter()
|
||||
.filter_map(|ph| {
|
||||
if ph.p_type.get(NativeEndian) != elf::PT_GNU_STACK {
|
||||
Some(ph.p_vaddr.get(NativeEndian) + ph.p_memsz.get(NativeEndian))
|
||||
if ph.p_type.get(LE) != elf::PT_GNU_STACK {
|
||||
Some(ph.p_vaddr.get(LE) + ph.p_memsz.get(LE))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -620,8 +620,8 @@ fn gen_elf_le(
|
||||
let mut rel_sections: Vec<(u64, u64)> = vec![];
|
||||
let mut rela_sections: Vec<(usize, u64, u64)> = vec![];
|
||||
for (i, sh) in section_headers.iter_mut().enumerate() {
|
||||
let sh_offset = sh.sh_offset.get(NativeEndian);
|
||||
let sh_addr = sh.sh_addr.get(NativeEndian);
|
||||
let sh_offset = sh.sh_offset.get(LE);
|
||||
let sh_addr = sh.sh_addr.get(LE);
|
||||
if physical_shift_start <= sh_offset {
|
||||
sh.sh_offset = endian::U64::new(LE, sh_offset + md.added_byte_count);
|
||||
}
|
||||
@ -630,18 +630,18 @@ fn gen_elf_le(
|
||||
}
|
||||
|
||||
// Record every relocation section.
|
||||
let sh_type = sh.sh_type.get(NativeEndian);
|
||||
let sh_type = sh.sh_type.get(LE);
|
||||
if sh_type == elf::SHT_REL {
|
||||
rel_sections.push((sh_offset, sh.sh_size.get(NativeEndian)));
|
||||
rel_sections.push((sh_offset, sh.sh_size.get(LE)));
|
||||
} else if sh_type == elf::SHT_RELA {
|
||||
rela_sections.push((i, sh_offset, sh.sh_size.get(NativeEndian)));
|
||||
rela_sections.push((i, sh_offset, sh.sh_size.get(LE)));
|
||||
}
|
||||
}
|
||||
|
||||
// Get last section virtual address.
|
||||
let last_section_vaddr = section_headers
|
||||
.iter()
|
||||
.map(|sh| sh.sh_addr.get(NativeEndian) + sh.sh_size.get(NativeEndian))
|
||||
.map(|sh| sh.sh_addr.get(LE) + sh.sh_size.get(LE))
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
@ -658,7 +658,7 @@ fn gen_elf_le(
|
||||
sec_size as usize / mem::size_of::<elf::Rel64<LE>>(),
|
||||
);
|
||||
for rel in relocations.iter_mut() {
|
||||
let r_offset = rel.r_offset.get(NativeEndian);
|
||||
let r_offset = rel.r_offset.get(LE);
|
||||
if virtual_shift_start <= r_offset {
|
||||
rel.r_offset = endian::U64::new(LE, r_offset + md.added_byte_count);
|
||||
}
|
||||
@ -673,7 +673,7 @@ fn gen_elf_le(
|
||||
sec_size as usize / mem::size_of::<elf::Rela64<LE>>(),
|
||||
);
|
||||
for (i, rel) in relocations.iter_mut().enumerate() {
|
||||
let r_offset = rel.r_offset.get(NativeEndian);
|
||||
let r_offset = rel.r_offset.get(LE);
|
||||
if virtual_shift_start <= r_offset {
|
||||
rel.r_offset = endian::U64::new(LE, r_offset + md.added_byte_count);
|
||||
// Deal with potential adjusts to absolute jumps.
|
||||
@ -684,9 +684,9 @@ fn gen_elf_le(
|
||||
}
|
||||
}
|
||||
// If the relocation goes to a roc function, we need to surgically link it and change it to relative.
|
||||
let r_type = rel.r_type(NativeEndian, false);
|
||||
let r_type = rel.r_type(LE, false);
|
||||
if r_type == elf::R_X86_64_GLOB_DAT {
|
||||
let r_sym = rel.r_sym(NativeEndian, false);
|
||||
let r_sym = rel.r_sym(LE, false);
|
||||
for (name, index) in got_app_syms.iter() {
|
||||
if *index as u32 == r_sym {
|
||||
rel.set_r_info(LE, false, 0, elf::R_X86_64_RELATIVE);
|
||||
@ -715,8 +715,8 @@ fn gen_elf_le(
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, rel)| {
|
||||
let r_type = rel.r_type(NativeEndian, false);
|
||||
let r_sym = rel.r_sym(NativeEndian, false);
|
||||
let r_type = rel.r_type(LE, false);
|
||||
let r_sym = rel.r_sym(LE, false);
|
||||
if r_type == elf::R_X86_64_JUMP_SLOT && app_sym_indices.contains(&(r_sym as usize))
|
||||
{
|
||||
Some(i)
|
||||
@ -733,7 +733,7 @@ fn gen_elf_le(
|
||||
let mut j = relocations.len() - 1;
|
||||
for i in to_remove.iter() {
|
||||
relocations.swap(*i, j);
|
||||
let r_sym = relocations[j].r_sym(NativeEndian, false);
|
||||
let r_sym = relocations[j].r_sym(LE, false);
|
||||
relocations[j].set_r_info(LE, false, r_sym, elf::R_X86_64_NONE);
|
||||
j -= 1;
|
||||
}
|
||||
@ -744,12 +744,12 @@ fn gen_elf_le(
|
||||
sh_num as usize,
|
||||
);
|
||||
|
||||
let old_size = section_headers[sec_index].sh_size.get(NativeEndian);
|
||||
let old_size = section_headers[sec_index].sh_size.get(LE);
|
||||
let removed_count = to_remove.len();
|
||||
let removed_size = removed_count * std::mem::size_of::<elf::Rela64<LE>>();
|
||||
section_headers[sec_index]
|
||||
.sh_size
|
||||
.set(NativeEndian, old_size - removed_size as u64);
|
||||
.set(LE, old_size - removed_size as u64);
|
||||
|
||||
let dyns = load_structs_inplace_mut::<elf::Dyn64<LE>>(
|
||||
&mut out_mmap,
|
||||
@ -759,30 +759,30 @@ fn gen_elf_le(
|
||||
let is_rela_dyn = dyns
|
||||
.iter()
|
||||
.filter(|d| {
|
||||
let tag = d.d_tag.get(NativeEndian) as u32;
|
||||
let tag = d.d_tag.get(LE) as u32;
|
||||
tag == elf::DT_RELA
|
||||
})
|
||||
.any(|d| d.d_val.get(NativeEndian) == sec_offset);
|
||||
.any(|d| d.d_val.get(LE) == sec_offset);
|
||||
let is_rela_plt = dyns
|
||||
.iter()
|
||||
.filter(|d| {
|
||||
let tag = d.d_tag.get(NativeEndian) as u32;
|
||||
let tag = d.d_tag.get(LE) as u32;
|
||||
tag == elf::DT_JMPREL
|
||||
})
|
||||
.any(|d| d.d_val.get(NativeEndian) == sec_offset);
|
||||
.any(|d| d.d_val.get(LE) == sec_offset);
|
||||
|
||||
for d in dyns.iter_mut() {
|
||||
match d.d_tag.get(NativeEndian) as u32 {
|
||||
match d.d_tag.get(LE) as u32 {
|
||||
elf::DT_RELACOUNT if is_rela_dyn => {
|
||||
let old_count = d.d_val.get(NativeEndian);
|
||||
let old_count = d.d_val.get(LE);
|
||||
d.d_val.set(LE, old_count - removed_count as u64);
|
||||
}
|
||||
elf::DT_RELASZ if is_rela_dyn => {
|
||||
let old_size = d.d_val.get(NativeEndian);
|
||||
let old_size = d.d_val.get(LE);
|
||||
d.d_val.set(LE, old_size - removed_size as u64);
|
||||
}
|
||||
elf::DT_PLTRELSZ if is_rela_plt => {
|
||||
let old_size = d.d_val.get(NativeEndian);
|
||||
let old_size = d.d_val.get(LE);
|
||||
d.d_val.set(LE, old_size - removed_size as u64);
|
||||
}
|
||||
_ => {}
|
||||
@ -797,7 +797,7 @@ fn gen_elf_le(
|
||||
dynamic_lib_count,
|
||||
);
|
||||
for mut d in dyns {
|
||||
match d.d_tag.get(NativeEndian) as u32 {
|
||||
match d.d_tag.get(LE) as u32 {
|
||||
// I believe this is the list of symbols that need to be update if addresses change.
|
||||
// I am less sure about the symbols from GNU_HASH down.
|
||||
elf::DT_INIT
|
||||
@ -828,7 +828,7 @@ fn gen_elf_le(
|
||||
| elf::DT_VERSYM
|
||||
| elf::DT_VERDEF
|
||||
| elf::DT_VERNEED => {
|
||||
let d_addr = d.d_val.get(NativeEndian);
|
||||
let d_addr = d.d_val.get(LE);
|
||||
if virtual_shift_start <= d_addr {
|
||||
d.d_val = endian::U64::new(LE, d_addr + md.added_byte_count);
|
||||
}
|
||||
@ -848,7 +848,7 @@ fn gen_elf_le(
|
||||
);
|
||||
|
||||
for sym in symbols {
|
||||
let addr = sym.st_value.get(NativeEndian);
|
||||
let addr = sym.st_value.get(LE);
|
||||
if virtual_shift_start <= addr {
|
||||
sym.st_value = endian::U64::new(LE, addr + md.added_byte_count);
|
||||
}
|
||||
@ -862,7 +862,7 @@ fn gen_elf_le(
|
||||
size / mem::size_of::<endian::U64<LE>>(),
|
||||
);
|
||||
for go in global_offsets.iter_mut() {
|
||||
let go_addr = go.get(NativeEndian);
|
||||
let go_addr = go.get(LE);
|
||||
if physical_shift_start <= go_addr {
|
||||
go.set(LE, go_addr + md.added_byte_count);
|
||||
}
|
||||
@ -883,11 +883,8 @@ fn gen_elf_le(
|
||||
|
||||
// Update main elf header for extra data.
|
||||
let mut file_header = load_struct_inplace_mut::<elf::FileHeader64<LE>>(&mut out_mmap, 0);
|
||||
file_header.e_shoff = endian::U64::new(
|
||||
LE,
|
||||
file_header.e_shoff.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
let e_entry = file_header.e_entry.get(NativeEndian);
|
||||
file_header.e_shoff = endian::U64::new(LE, file_header.e_shoff.get(LE) + md.added_byte_count);
|
||||
let e_entry = file_header.e_entry.get(LE);
|
||||
if virtual_shift_start <= e_entry {
|
||||
file_header.e_entry = endian::U64::new(LE, e_entry + md.added_byte_count);
|
||||
}
|
||||
@ -1185,12 +1182,12 @@ fn surgery_elf_help(
|
||||
}
|
||||
let exec_header = load_struct_inplace::<elf::FileHeader64<LE>>(exec_mmap, 0);
|
||||
|
||||
let ph_offset = exec_header.e_phoff.get(NativeEndian);
|
||||
let ph_ent_size = exec_header.e_phentsize.get(NativeEndian);
|
||||
let ph_num = exec_header.e_phnum.get(NativeEndian);
|
||||
let sh_offset = exec_header.e_shoff.get(NativeEndian);
|
||||
let sh_ent_size = exec_header.e_shentsize.get(NativeEndian);
|
||||
let sh_num = exec_header.e_shnum.get(NativeEndian);
|
||||
let ph_offset = exec_header.e_phoff.get(LE);
|
||||
let ph_ent_size = exec_header.e_phentsize.get(LE);
|
||||
let ph_num = exec_header.e_phnum.get(LE);
|
||||
let sh_offset = exec_header.e_shoff.get(LE);
|
||||
let sh_ent_size = exec_header.e_shentsize.get(LE);
|
||||
let sh_num = exec_header.e_shnum.get(LE);
|
||||
|
||||
if verbose {
|
||||
println!();
|
||||
|
@ -3,7 +3,7 @@ use iced_x86::{Decoder, DecoderOptions, Instruction, OpCodeOperandKind, OpKind};
|
||||
use memmap2::MmapMut;
|
||||
use object::macho;
|
||||
use object::{
|
||||
CompressedFileRange, CompressionFormat, LittleEndian, NativeEndian, Object, ObjectSection,
|
||||
CompressedFileRange, CompressionFormat, LittleEndian as LE, Object, ObjectSection,
|
||||
ObjectSymbol, RelocationKind, RelocationTarget, Section, SectionIndex, SectionKind, Symbol,
|
||||
SymbolIndex, SymbolSection,
|
||||
};
|
||||
@ -325,8 +325,8 @@ pub(crate) fn preprocess_macho(
|
||||
{
|
||||
use macho::{DyldInfoCommand, DylibCommand, Section64, SegmentCommand64};
|
||||
|
||||
let exec_header = load_struct_inplace::<macho::MachHeader64<LittleEndian>>(exec_data, 0);
|
||||
let num_load_cmds = exec_header.ncmds.get(NativeEndian);
|
||||
let exec_header = load_struct_inplace::<macho::MachHeader64<LE>>(exec_data, 0);
|
||||
let num_load_cmds = exec_header.ncmds.get(LE);
|
||||
|
||||
let mut offset = mem::size_of_val(exec_header);
|
||||
|
||||
@ -334,17 +334,17 @@ pub(crate) fn preprocess_macho(
|
||||
let mut stubs_symbol_count = None;
|
||||
|
||||
'cmds: for _ in 0..num_load_cmds {
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LittleEndian>>(exec_data, offset);
|
||||
let cmd = info.cmd.get(NativeEndian);
|
||||
let cmdsize = info.cmdsize.get(NativeEndian);
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LE>>(exec_data, offset);
|
||||
let cmd = info.cmd.get(LE);
|
||||
let cmdsize = info.cmdsize.get(LE);
|
||||
|
||||
if cmd == macho::LC_SEGMENT_64 {
|
||||
let info = load_struct_inplace::<SegmentCommand64<LittleEndian>>(exec_data, offset);
|
||||
let info = load_struct_inplace::<SegmentCommand64<LE>>(exec_data, offset);
|
||||
|
||||
if &info.segname[0..6] == b"__TEXT" {
|
||||
let sections = info.nsects.get(NativeEndian);
|
||||
let sections = info.nsects.get(LE);
|
||||
|
||||
let sections_info = load_structs_inplace::<Section64<LittleEndian>>(
|
||||
let sections_info = load_structs_inplace::<Section64<LE>>(
|
||||
exec_data,
|
||||
offset + mem::size_of_val(info),
|
||||
sections as usize,
|
||||
@ -352,9 +352,9 @@ pub(crate) fn preprocess_macho(
|
||||
|
||||
for section_info in sections_info {
|
||||
if §ion_info.sectname[0..7] == b"__stubs" {
|
||||
stubs_symbol_index = Some(section_info.reserved1.get(NativeEndian));
|
||||
stubs_symbol_index = Some(section_info.reserved1.get(LE));
|
||||
stubs_symbol_count =
|
||||
Some(section_info.size.get(NativeEndian) / STUB_ADDRESS_OFFSET);
|
||||
Some(section_info.size.get(LE) / STUB_ADDRESS_OFFSET);
|
||||
|
||||
break 'cmds;
|
||||
}
|
||||
@ -378,14 +378,14 @@ pub(crate) fn preprocess_macho(
|
||||
let shared_lib_filename = shared_lib.file_name();
|
||||
|
||||
for _ in 0..num_load_cmds {
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LittleEndian>>(exec_data, offset);
|
||||
let cmd = info.cmd.get(NativeEndian);
|
||||
let cmdsize = info.cmdsize.get(NativeEndian);
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LE>>(exec_data, offset);
|
||||
let cmd = info.cmd.get(LE);
|
||||
let cmdsize = info.cmdsize.get(LE);
|
||||
|
||||
if cmd == macho::LC_DYLD_INFO_ONLY {
|
||||
let info = load_struct_inplace::<DyldInfoCommand<LittleEndian>>(exec_data, offset);
|
||||
let info = load_struct_inplace::<DyldInfoCommand<LE>>(exec_data, offset);
|
||||
|
||||
let lazy_bind_offset = info.lazy_bind_off.get(NativeEndian) as usize;
|
||||
let lazy_bind_offset = info.lazy_bind_off.get(LE) as usize;
|
||||
|
||||
let lazy_bind_symbols = mach_object::LazyBind::parse(
|
||||
&exec_data[lazy_bind_offset..],
|
||||
@ -412,8 +412,8 @@ pub(crate) fn preprocess_macho(
|
||||
}
|
||||
}
|
||||
} else if cmd == macho::LC_LOAD_DYLIB {
|
||||
let info = load_struct_inplace::<DylibCommand<LittleEndian>>(exec_data, offset);
|
||||
let name_offset = info.dylib.name.offset.get(NativeEndian) as usize;
|
||||
let info = load_struct_inplace::<DylibCommand<LE>>(exec_data, offset);
|
||||
let name_offset = info.dylib.name.offset.get(LE) as usize;
|
||||
let str_start_index = offset + name_offset;
|
||||
let str_end_index = offset + cmdsize as usize;
|
||||
let str_bytes = &exec_data[str_start_index..str_end_index];
|
||||
@ -600,19 +600,18 @@ fn gen_macho_le(
|
||||
|
||||
use macho::{Section64, SegmentCommand64};
|
||||
|
||||
let exec_header = load_struct_inplace::<macho::MachHeader64<LittleEndian>>(exec_data, 0);
|
||||
let num_load_cmds = exec_header.ncmds.get(NativeEndian);
|
||||
let size_of_cmds = exec_header.sizeofcmds.get(NativeEndian) as usize;
|
||||
let exec_header = load_struct_inplace::<macho::MachHeader64<LE>>(exec_data, 0);
|
||||
let num_load_cmds = exec_header.ncmds.get(LE);
|
||||
let size_of_cmds = exec_header.sizeofcmds.get(LE) as usize;
|
||||
|
||||
// Add a new text segment and data segment
|
||||
let segment_cmd_size = mem::size_of::<SegmentCommand64<LittleEndian>>();
|
||||
let section_size = mem::size_of::<Section64<LittleEndian>>();
|
||||
let segment_cmd_size = mem::size_of::<SegmentCommand64<LE>>();
|
||||
let section_size = mem::size_of::<Section64<LE>>();
|
||||
|
||||
// We need the full command size, including the dynamic-length string at the end.
|
||||
// To get that, we need to load the command.
|
||||
let info =
|
||||
load_struct_inplace::<macho::LoadCommand<LittleEndian>>(exec_data, macho_load_so_offset);
|
||||
let total_cmd_size = info.cmdsize.get(NativeEndian) as usize;
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LE>>(exec_data, macho_load_so_offset);
|
||||
let total_cmd_size = info.cmdsize.get(LE) as usize;
|
||||
|
||||
// ======================== Important TODO ==========================
|
||||
// TODO: we accidentally instroduced a big change here.
|
||||
@ -654,16 +653,16 @@ fn gen_macho_le(
|
||||
|
||||
out_mmap[start_index..start_index + rest_of_data.len()].copy_from_slice(rest_of_data);
|
||||
|
||||
let out_header = load_struct_inplace_mut::<macho::MachHeader64<LittleEndian>>(&mut out_mmap, 0);
|
||||
let out_header = load_struct_inplace_mut::<macho::MachHeader64<LE>>(&mut out_mmap, 0);
|
||||
|
||||
// TODO: this needs to change to adding the 2 new commands when we are ready.
|
||||
// -1 because we're deleting 1 load command and then NOT adding 2 new ones.
|
||||
{
|
||||
let added_bytes = -(total_cmd_size as isize); // TODO: Change when add the new sections.
|
||||
out_header.ncmds.set(LittleEndian, num_load_cmds - 1);
|
||||
out_header.ncmds.set(LE, num_load_cmds - 1);
|
||||
out_header
|
||||
.sizeofcmds
|
||||
.set(LittleEndian, (size_of_cmds as isize + added_bytes) as u32);
|
||||
.set(LE, (size_of_cmds as isize + added_bytes) as u32);
|
||||
}
|
||||
|
||||
// Go through every command and shift it by added_bytes if it's absolute, unless it's inside the command header
|
||||
@ -681,50 +680,37 @@ fn gen_macho_le(
|
||||
|
||||
// minus one because we "deleted" a load command
|
||||
for _ in 0..(num_load_cmds - 1) {
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LittleEndian>>(&out_mmap, offset);
|
||||
let cmd_size = info.cmdsize.get(NativeEndian) as usize;
|
||||
let info = load_struct_inplace::<macho::LoadCommand<LE>>(&out_mmap, offset);
|
||||
let cmd_size = info.cmdsize.get(LE) as usize;
|
||||
|
||||
match info.cmd.get(NativeEndian) {
|
||||
match info.cmd.get(LE) {
|
||||
macho::LC_SEGMENT_64 => {
|
||||
let cmd = load_struct_inplace_mut::<macho::SegmentCommand64<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::SegmentCommand64<LE>>(&mut out_mmap, offset);
|
||||
|
||||
// Ignore page zero, it never moves.
|
||||
if cmd.segname == "__PAGEZERO\0\0\0\0\0\0".as_bytes()
|
||||
|| cmd.vmaddr.get(NativeEndian) == 0
|
||||
{
|
||||
if cmd.segname == "__PAGEZERO\0\0\0\0\0\0".as_bytes() || cmd.vmaddr.get(LE) == 0 {
|
||||
offset += cmd_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
let old_file_offest = cmd.fileoff.get(NativeEndian);
|
||||
let old_file_offest = cmd.fileoff.get(LE);
|
||||
// The segment with file offset zero also includes the header.
|
||||
// As such, its file offset does not change.
|
||||
// Instead, its file size should be increased.
|
||||
if old_file_offest > 0 {
|
||||
cmd.fileoff
|
||||
.set(LittleEndian, old_file_offest + md.added_byte_count);
|
||||
cmd.vmaddr.set(
|
||||
LittleEndian,
|
||||
cmd.vmaddr.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
cmd.fileoff.set(LE, old_file_offest + md.added_byte_count);
|
||||
cmd.vmaddr.set(LE, cmd.vmaddr.get(LE) + md.added_byte_count);
|
||||
} else {
|
||||
cmd.filesize.set(
|
||||
LittleEndian,
|
||||
cmd.filesize.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
cmd.vmsize.set(
|
||||
LittleEndian,
|
||||
cmd.vmsize.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
cmd.filesize
|
||||
.set(LE, cmd.filesize.get(LE) + md.added_byte_count);
|
||||
cmd.vmsize.set(LE, cmd.vmsize.get(LE) + md.added_byte_count);
|
||||
}
|
||||
|
||||
// let num_sections = cmd.nsects.get(NativeEndian);
|
||||
// let sections = load_structs_inplace_mut::<macho::Section64<LittleEndian>>(
|
||||
// let num_sections = cmd.nsects.get(LE);
|
||||
// let sections = load_structs_inplace_mut::<macho::Section64<LE >>(
|
||||
// &mut out_mmap,
|
||||
// offset + mem::size_of::<macho::SegmentCommand64<LittleEndian>>(),
|
||||
// offset + mem::size_of::<macho::SegmentCommand64<LE >>(),
|
||||
// num_sections as usize,
|
||||
// );
|
||||
// struct Relocation {
|
||||
@ -736,34 +722,34 @@ fn gen_macho_le(
|
||||
|
||||
// for section in sections {
|
||||
// section.addr.set(
|
||||
// LittleEndian,
|
||||
// section.addr.get(NativeEndian) + md.added_byte_count as u64,
|
||||
// LE ,
|
||||
// section.addr.get(LE) + md.added_byte_count as u64,
|
||||
// );
|
||||
|
||||
// // If offset is zero, don't update it.
|
||||
// // Zero is used for things like BSS that don't exist in the file.
|
||||
// let old_offset = section.offset.get(NativeEndian);
|
||||
// let old_offset = section.offset.get(LE);
|
||||
// if old_offset > 0 {
|
||||
// section
|
||||
// .offset
|
||||
// .set(LittleEndian, old_offset + md.added_byte_count as u32);
|
||||
// .set(LE , old_offset + md.added_byte_count as u32);
|
||||
// }
|
||||
|
||||
// // dbg!(§ion.reloff.get(NativeEndian));
|
||||
// // dbg!(section.reloff.get(NativeEndian) as i32);
|
||||
// // dbg!(§ion.reloff.get(LE));
|
||||
// // dbg!(section.reloff.get(LE) as i32);
|
||||
// // dbg!(§ion);
|
||||
// // dbg!(&md.added_byte_count);
|
||||
// // dbg!(String::from_utf8_lossy(§ion.sectname));
|
||||
// if section.nreloc.get(NativeEndian) > 0 {
|
||||
// if section.nreloc.get(LE) > 0 {
|
||||
// section.reloff.set(
|
||||
// LittleEndian,
|
||||
// section.reloff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
// LE ,
|
||||
// section.reloff.get(LE) + md.added_byte_count as u32,
|
||||
// );
|
||||
// }
|
||||
|
||||
// relocation_offsets.push(Relocation {
|
||||
// offset: section.reloff.get(NativeEndian),
|
||||
// num_relocations: section.nreloc.get(NativeEndian),
|
||||
// offset: section.reloff.get(LE),
|
||||
// num_relocations: section.nreloc.get(LE),
|
||||
// });
|
||||
// }
|
||||
|
||||
@ -773,7 +759,7 @@ fn gen_macho_le(
|
||||
// num_relocations,
|
||||
// } in relocation_offsets
|
||||
// {
|
||||
// let relos = load_structs_inplace_mut::<macho::Relocation<LittleEndian>>(
|
||||
// let relos = load_structs_inplace_mut::<macho::Relocation<LE >>(
|
||||
// &mut out_mmap,
|
||||
// offset as usize,
|
||||
// num_relocations as usize,
|
||||
@ -781,13 +767,13 @@ fn gen_macho_le(
|
||||
|
||||
// // TODO this has never been tested, because scattered relocations only come up on ARM!
|
||||
// for relo in relos.iter_mut() {
|
||||
// if relo.r_scattered(LittleEndian, cpu_type) {
|
||||
// let mut scattered_info = relo.scattered_info(NativeEndian);
|
||||
// if relo.r_scattered(LE , cpu_type) {
|
||||
// let mut scattered_info = relo.scattered_info(LE);
|
||||
|
||||
// if !scattered_info.r_pcrel {
|
||||
// scattered_info.r_value += md.added_byte_count as u32;
|
||||
|
||||
// let new_info = scattered_info.relocation(LittleEndian);
|
||||
// let new_info = scattered_info.relocation(LE );
|
||||
|
||||
// relo.r_word0 = new_info.r_word0;
|
||||
// relo.r_word1 = new_info.r_word1;
|
||||
@ -797,30 +783,25 @@ fn gen_macho_le(
|
||||
// }
|
||||
|
||||
// TODO this seems to be wrong and unnecessary, and should probably be deleted.
|
||||
// offset += num_sections as usize * mem::size_of::<macho::Section64<LittleEndian>>();
|
||||
// offset += num_sections as usize * mem::size_of::<macho::Section64<LE >>();
|
||||
}
|
||||
macho::LC_SYMTAB => {
|
||||
let cmd = load_struct_inplace_mut::<macho::SymtabCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::SymtabCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
let sym_offset = cmd.symoff.get(NativeEndian);
|
||||
let num_syms = cmd.nsyms.get(NativeEndian);
|
||||
let sym_offset = cmd.symoff.get(LE);
|
||||
let num_syms = cmd.nsyms.get(LE);
|
||||
|
||||
if num_syms > 0 {
|
||||
cmd.symoff
|
||||
.set(LittleEndian, sym_offset + md.added_byte_count as u32);
|
||||
cmd.symoff.set(LE, sym_offset + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.strsize.get(NativeEndian) > 0 {
|
||||
cmd.stroff.set(
|
||||
LittleEndian,
|
||||
cmd.stroff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.strsize.get(LE) > 0 {
|
||||
cmd.stroff
|
||||
.set(LE, cmd.stroff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
let table = load_structs_inplace_mut::<macho::Nlist64<LittleEndian>>(
|
||||
let table = load_structs_inplace_mut::<macho::Nlist64<LE>>(
|
||||
&mut out_mmap,
|
||||
sym_offset as usize + md.added_byte_count as usize,
|
||||
num_syms as usize,
|
||||
@ -829,59 +810,44 @@ fn gen_macho_le(
|
||||
for entry in table {
|
||||
let entry_type = entry.n_type & macho::N_TYPE;
|
||||
if entry_type == macho::N_ABS || entry_type == macho::N_SECT {
|
||||
entry.n_value.set(
|
||||
LittleEndian,
|
||||
entry.n_value.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
entry
|
||||
.n_value
|
||||
.set(LE, entry.n_value.get(LE) + md.added_byte_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
macho::LC_DYSYMTAB => {
|
||||
let cmd = load_struct_inplace_mut::<macho::DysymtabCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::DysymtabCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
if cmd.ntoc.get(NativeEndian) > 0 {
|
||||
cmd.tocoff.set(
|
||||
LittleEndian,
|
||||
cmd.tocoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.ntoc.get(LE) > 0 {
|
||||
cmd.tocoff
|
||||
.set(LE, cmd.tocoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.nmodtab.get(NativeEndian) > 0 {
|
||||
cmd.modtaboff.set(
|
||||
LittleEndian,
|
||||
cmd.modtaboff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nmodtab.get(LE) > 0 {
|
||||
cmd.modtaboff
|
||||
.set(LE, cmd.modtaboff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.nextrefsyms.get(NativeEndian) > 0 {
|
||||
cmd.extrefsymoff.set(
|
||||
LittleEndian,
|
||||
cmd.extrefsymoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nextrefsyms.get(LE) > 0 {
|
||||
cmd.extrefsymoff
|
||||
.set(LE, cmd.extrefsymoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.nindirectsyms.get(NativeEndian) > 0 {
|
||||
cmd.indirectsymoff.set(
|
||||
LittleEndian,
|
||||
cmd.indirectsymoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nindirectsyms.get(LE) > 0 {
|
||||
cmd.indirectsymoff
|
||||
.set(LE, cmd.indirectsymoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.nextrel.get(NativeEndian) > 0 {
|
||||
cmd.extreloff.set(
|
||||
LittleEndian,
|
||||
cmd.extreloff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nextrel.get(LE) > 0 {
|
||||
cmd.extreloff
|
||||
.set(LE, cmd.extreloff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.nlocrel.get(NativeEndian) > 0 {
|
||||
cmd.locreloff.set(
|
||||
LittleEndian,
|
||||
cmd.locreloff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nlocrel.get(LE) > 0 {
|
||||
cmd.locreloff
|
||||
.set(LE, cmd.locreloff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
// TODO maybe we need to update something else too - relocations maybe?
|
||||
@ -889,29 +855,25 @@ fn gen_macho_le(
|
||||
// Look at otool -I at least for the indirect symbols.
|
||||
}
|
||||
macho::LC_TWOLEVEL_HINTS => {
|
||||
let cmd = load_struct_inplace_mut::<macho::TwolevelHintsCommand<LittleEndian>>(
|
||||
let cmd = load_struct_inplace_mut::<macho::TwolevelHintsCommand<LE>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
|
||||
if cmd.nhints.get(NativeEndian) > 0 {
|
||||
cmd.offset.set(
|
||||
LittleEndian,
|
||||
cmd.offset.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.nhints.get(LE) > 0 {
|
||||
cmd.offset
|
||||
.set(LE, cmd.offset.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
}
|
||||
macho::LC_FUNCTION_STARTS => {
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LittleEndian>>(
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LE>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
|
||||
if cmd.datasize.get(NativeEndian) > 0 {
|
||||
cmd.dataoff.set(
|
||||
LittleEndian,
|
||||
cmd.dataoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.datasize.get(LE) > 0 {
|
||||
cmd.dataoff
|
||||
.set(LE, cmd.dataoff.get(LE) + md.added_byte_count as u32);
|
||||
// TODO: This lists the start of every function. Which, of course, have moved.
|
||||
// That being said, to my understanding this section is optional and may just be debug information.
|
||||
// As such, updating it should not be required.
|
||||
@ -920,36 +882,30 @@ fn gen_macho_le(
|
||||
}
|
||||
macho::LC_DATA_IN_CODE => {
|
||||
let (offset, size) = {
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LittleEndian>>(
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LE>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
|
||||
if cmd.datasize.get(NativeEndian) > 0 {
|
||||
cmd.dataoff.set(
|
||||
LittleEndian,
|
||||
cmd.dataoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.datasize.get(LE) > 0 {
|
||||
cmd.dataoff
|
||||
.set(LE, cmd.dataoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
(
|
||||
cmd.dataoff.get(NativeEndian),
|
||||
cmd.datasize.get(NativeEndian),
|
||||
)
|
||||
(cmd.dataoff.get(LE), cmd.datasize.get(LE))
|
||||
};
|
||||
|
||||
// Update every data in code entry.
|
||||
if size > 0 {
|
||||
let entry_size = mem::size_of::<macho::DataInCodeEntry<LittleEndian>>();
|
||||
let entries = load_structs_inplace_mut::<macho::DataInCodeEntry<LittleEndian>>(
|
||||
let entry_size = mem::size_of::<macho::DataInCodeEntry<LE>>();
|
||||
let entries = load_structs_inplace_mut::<macho::DataInCodeEntry<LE>>(
|
||||
&mut out_mmap,
|
||||
offset as usize,
|
||||
size as usize / entry_size,
|
||||
);
|
||||
for entry in entries.iter_mut() {
|
||||
entry.offset.set(
|
||||
LittleEndian,
|
||||
entry.offset.get(NativeEndian) + md.added_byte_count as u32,
|
||||
)
|
||||
entry
|
||||
.offset
|
||||
.set(LE, entry.offset.get(LE) + md.added_byte_count as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -959,63 +915,49 @@ fn gen_macho_le(
|
||||
| macho::LC_LINKER_OPTIMIZATION_HINT
|
||||
| macho::LC_DYLD_EXPORTS_TRIE
|
||||
| macho::LC_DYLD_CHAINED_FIXUPS => {
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LittleEndian>>(
|
||||
let cmd = load_struct_inplace_mut::<macho::LinkeditDataCommand<LE>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
|
||||
if cmd.datasize.get(NativeEndian) > 0 {
|
||||
cmd.dataoff.set(
|
||||
LittleEndian,
|
||||
cmd.dataoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.datasize.get(LE) > 0 {
|
||||
cmd.dataoff
|
||||
.set(LE, cmd.dataoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
}
|
||||
macho::LC_ENCRYPTION_INFO_64 => {
|
||||
let cmd = load_struct_inplace_mut::<macho::EncryptionInfoCommand64<LittleEndian>>(
|
||||
let cmd = load_struct_inplace_mut::<macho::EncryptionInfoCommand64<LE>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
|
||||
if cmd.cryptsize.get(NativeEndian) > 0 {
|
||||
cmd.cryptoff.set(
|
||||
LittleEndian,
|
||||
cmd.cryptoff.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.cryptsize.get(LE) > 0 {
|
||||
cmd.cryptoff
|
||||
.set(LE, cmd.cryptoff.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
}
|
||||
macho::LC_DYLD_INFO | macho::LC_DYLD_INFO_ONLY => {
|
||||
let cmd = load_struct_inplace_mut::<macho::DyldInfoCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::DyldInfoCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
if cmd.rebase_size.get(NativeEndian) > 0 {
|
||||
cmd.rebase_off.set(
|
||||
LittleEndian,
|
||||
cmd.rebase_off.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.rebase_size.get(LE) > 0 {
|
||||
cmd.rebase_off
|
||||
.set(LE, cmd.rebase_off.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.bind_size.get(NativeEndian) > 0 {
|
||||
cmd.bind_off.set(
|
||||
LittleEndian,
|
||||
cmd.bind_off.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.bind_size.get(LE) > 0 {
|
||||
cmd.bind_off
|
||||
.set(LE, cmd.bind_off.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.weak_bind_size.get(NativeEndian) > 0 {
|
||||
cmd.weak_bind_off.set(
|
||||
LittleEndian,
|
||||
cmd.weak_bind_off.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.weak_bind_size.get(LE) > 0 {
|
||||
cmd.weak_bind_off
|
||||
.set(LE, cmd.weak_bind_off.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
if cmd.lazy_bind_size.get(NativeEndian) > 0 {
|
||||
cmd.lazy_bind_off.set(
|
||||
LittleEndian,
|
||||
cmd.lazy_bind_off.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.lazy_bind_size.get(LE) > 0 {
|
||||
cmd.lazy_bind_off
|
||||
.set(LE, cmd.lazy_bind_off.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
|
||||
// TODO: Parse and update the related tables here.
|
||||
@ -1026,40 +968,26 @@ fn gen_macho_le(
|
||||
// Also `xcrun dyldinfo` is useful for debugging this.
|
||||
}
|
||||
macho::LC_SYMSEG => {
|
||||
let cmd = load_struct_inplace_mut::<macho::SymsegCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::SymsegCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
if cmd.size.get(NativeEndian) > 0 {
|
||||
cmd.offset.set(
|
||||
LittleEndian,
|
||||
cmd.offset.get(NativeEndian) + md.added_byte_count as u32,
|
||||
);
|
||||
if cmd.size.get(LE) > 0 {
|
||||
cmd.offset
|
||||
.set(LE, cmd.offset.get(LE) + md.added_byte_count as u32);
|
||||
}
|
||||
}
|
||||
macho::LC_MAIN => {
|
||||
let cmd = load_struct_inplace_mut::<macho::EntryPointCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd =
|
||||
load_struct_inplace_mut::<macho::EntryPointCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
cmd.entryoff.set(
|
||||
LittleEndian,
|
||||
cmd.entryoff.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
cmd.entryoff
|
||||
.set(LE, cmd.entryoff.get(LE) + md.added_byte_count);
|
||||
}
|
||||
macho::LC_NOTE => {
|
||||
let cmd = load_struct_inplace_mut::<macho::NoteCommand<LittleEndian>>(
|
||||
&mut out_mmap,
|
||||
offset,
|
||||
);
|
||||
let cmd = load_struct_inplace_mut::<macho::NoteCommand<LE>>(&mut out_mmap, offset);
|
||||
|
||||
if cmd.size.get(NativeEndian) > 0 {
|
||||
cmd.offset.set(
|
||||
LittleEndian,
|
||||
cmd.offset.get(NativeEndian) + md.added_byte_count,
|
||||
);
|
||||
if cmd.size.get(LE) > 0 {
|
||||
cmd.offset.set(LE, cmd.offset.get(LE) + md.added_byte_count);
|
||||
}
|
||||
}
|
||||
macho::LC_ID_DYLIB
|
||||
@ -1459,89 +1387,89 @@ fn surgery_macho_help(
|
||||
// // Load this section (we made room for it earlier) and then mutate all its data to make it the desired command
|
||||
// {
|
||||
// let cmd =
|
||||
// load_struct_inplace_mut::<macho::SegmentCommand64<LittleEndian>>(exec_mmap, cmd_offset);
|
||||
// let size_of_section = mem::size_of::<macho::Section64<LittleEndian>>() as u32;
|
||||
// load_struct_inplace_mut::<macho::SegmentCommand64<LE >>(exec_mmap, cmd_offset);
|
||||
// let size_of_section = mem::size_of::<macho::Section64<LE >>() as u32;
|
||||
// let size_of_cmd = mem::size_of_val(cmd);
|
||||
|
||||
// cmd_offset += size_of_cmd;
|
||||
|
||||
// cmd.cmd.set(LittleEndian, macho::LC_SEGMENT_64);
|
||||
// cmd.cmd.set(LE , macho::LC_SEGMENT_64);
|
||||
// cmd.cmdsize
|
||||
// .set(LittleEndian, size_of_section + size_of_cmd as u32);
|
||||
// .set(LE , size_of_section + size_of_cmd as u32);
|
||||
// cmd.segname = *b"__DATA_CONST\0\0\0\0";
|
||||
// cmd.vmaddr
|
||||
// .set(LittleEndian, new_rodata_section_vaddr as u64);
|
||||
// .set(LE , new_rodata_section_vaddr as u64);
|
||||
// cmd.vmsize.set(
|
||||
// LittleEndian,
|
||||
// LE ,
|
||||
// (new_text_section_vaddr - new_rodata_section_vaddr) as u64,
|
||||
// );
|
||||
// cmd.fileoff
|
||||
// .set(LittleEndian, new_rodata_section_offset as u64);
|
||||
// .set(LE , new_rodata_section_offset as u64);
|
||||
// cmd.filesize.set(
|
||||
// LittleEndian,
|
||||
// LE ,
|
||||
// (new_text_section_offset - new_rodata_section_offset) as u64,
|
||||
// );
|
||||
// cmd.nsects.set(LittleEndian, 1);
|
||||
// cmd.maxprot.set(LittleEndian, 0x00000003);
|
||||
// cmd.initprot.set(LittleEndian, 0x00000003);
|
||||
// cmd.nsects.set(LE , 1);
|
||||
// cmd.maxprot.set(LE , 0x00000003);
|
||||
// cmd.initprot.set(LE , 0x00000003);
|
||||
|
||||
// // TODO set protection
|
||||
// }
|
||||
|
||||
// {
|
||||
// let cmd = load_struct_inplace_mut::<macho::Section64<LittleEndian>>(exec_mmap, cmd_offset);
|
||||
// let cmd = load_struct_inplace_mut::<macho::Section64<LE >>(exec_mmap, cmd_offset);
|
||||
// let size_of_cmd = mem::size_of_val(cmd);
|
||||
|
||||
// cmd_offset += size_of_cmd;
|
||||
|
||||
// cmd.sectname = *b"__const\0\0\0\0\0\0\0\0\0";
|
||||
// cmd.segname = *b"__DATA_CONST\0\0\0\0";
|
||||
// cmd.addr.set(LittleEndian, new_rodata_section_vaddr as u64);
|
||||
// cmd.addr.set(LE , new_rodata_section_vaddr as u64);
|
||||
// cmd.size.set(
|
||||
// LittleEndian,
|
||||
// LE ,
|
||||
// (new_text_section_offset - new_rodata_section_offset) as u64,
|
||||
// );
|
||||
// cmd.offset.set(LittleEndian, 0); // TODO is this offset since the start of the file, or segment offset?
|
||||
// cmd.align.set(LittleEndian, 12); // TODO should this be 4096?
|
||||
// cmd.reloff.set(LittleEndian, 264); // TODO this should NOT be hardcoded! Should get it from somewhere.
|
||||
// cmd.offset.set(LE , 0); // TODO is this offset since the start of the file, or segment offset?
|
||||
// cmd.align.set(LE , 12); // TODO should this be 4096?
|
||||
// cmd.reloff.set(LE , 264); // TODO this should NOT be hardcoded! Should get it from somewhere.
|
||||
// }
|
||||
|
||||
// {
|
||||
// let cmd =
|
||||
// load_struct_inplace_mut::<macho::SegmentCommand64<LittleEndian>>(exec_mmap, cmd_offset);
|
||||
// let size_of_section = mem::size_of::<macho::Section64<LittleEndian>>() as u32;
|
||||
// load_struct_inplace_mut::<macho::SegmentCommand64<LE >>(exec_mmap, cmd_offset);
|
||||
// let size_of_section = mem::size_of::<macho::Section64<LE >>() as u32;
|
||||
// let size_of_cmd = mem::size_of_val(cmd);
|
||||
|
||||
// cmd_offset += size_of_cmd;
|
||||
|
||||
// cmd.cmd.set(LittleEndian, macho::LC_SEGMENT_64);
|
||||
// cmd.cmd.set(LE , macho::LC_SEGMENT_64);
|
||||
// cmd.cmdsize
|
||||
// .set(LittleEndian, size_of_section + size_of_cmd as u32);
|
||||
// .set(LE , size_of_section + size_of_cmd as u32);
|
||||
// cmd.segname = *b"__TEXT\0\0\0\0\0\0\0\0\0\0";
|
||||
// cmd.vmaddr.set(LittleEndian, new_text_section_vaddr as u64);
|
||||
// cmd.vmaddr.set(LE , new_text_section_vaddr as u64);
|
||||
// cmd.vmsize
|
||||
// .set(LittleEndian, (offset - new_text_section_offset) as u64);
|
||||
// .set(LE , (offset - new_text_section_offset) as u64);
|
||||
// cmd.fileoff
|
||||
// .set(LittleEndian, new_text_section_offset as u64);
|
||||
// .set(LE , new_text_section_offset as u64);
|
||||
// cmd.filesize
|
||||
// .set(LittleEndian, (offset - new_text_section_offset) as u64);
|
||||
// cmd.nsects.set(LittleEndian, 1);
|
||||
// cmd.maxprot.set(LittleEndian, 0x00000005); // this is what a zig-generated host had
|
||||
// cmd.initprot.set(LittleEndian, 0x00000005); // this is what a zig-generated host had
|
||||
// .set(LE , (offset - new_text_section_offset) as u64);
|
||||
// cmd.nsects.set(LE , 1);
|
||||
// cmd.maxprot.set(LE , 0x00000005); // this is what a zig-generated host had
|
||||
// cmd.initprot.set(LE , 0x00000005); // this is what a zig-generated host had
|
||||
// }
|
||||
|
||||
// {
|
||||
// let cmd = load_struct_inplace_mut::<macho::Section64<LittleEndian>>(exec_mmap, cmd_offset);
|
||||
// let cmd = load_struct_inplace_mut::<macho::Section64<LE >>(exec_mmap, cmd_offset);
|
||||
|
||||
// cmd.segname = *b"__TEXT\0\0\0\0\0\0\0\0\0\0";
|
||||
// cmd.sectname = *b"__text\0\0\0\0\0\0\0\0\0\0";
|
||||
// cmd.addr.set(LittleEndian, new_text_section_vaddr as u64);
|
||||
// cmd.addr.set(LE , new_text_section_vaddr as u64);
|
||||
// cmd.size
|
||||
// .set(LittleEndian, (offset - new_text_section_offset) as u64);
|
||||
// cmd.offset.set(LittleEndian, 0); // TODO is this offset since the start of the file, or segment offset?
|
||||
// cmd.align.set(LittleEndian, 12); // TODO this is 4096 (2^12) - which load_align_constraint does, above - but should it?
|
||||
// cmd.flags.set(LittleEndian, 0x80000400); // TODO this is what a zig-generated host had
|
||||
// cmd.reloff.set(LittleEndian, 264); // TODO this should NOT be hardcoded! Should get it from somewhere.
|
||||
// .set(LE , (offset - new_text_section_offset) as u64);
|
||||
// cmd.offset.set(LE , 0); // TODO is this offset since the start of the file, or segment offset?
|
||||
// cmd.align.set(LE , 12); // TODO this is 4096 (2^12) - which load_align_constraint does, above - but should it?
|
||||
// cmd.flags.set(LE , 0x80000400); // TODO this is what a zig-generated host had
|
||||
// cmd.reloff.set(LE , 264); // TODO this should NOT be hardcoded! Should get it from somewhere.
|
||||
// }
|
||||
|
||||
// Update calls from platform and dynamic symbols.
|
||||
@ -1618,13 +1546,13 @@ fn surgery_macho_help(
|
||||
|
||||
// Commented out because it doesn't apply to mach-o
|
||||
// if let Some(i) = md.dynamic_symbol_indices.get(func_name) {
|
||||
// let sym = load_struct_inplace_mut::<elf::Sym64<LittleEndian>>(
|
||||
// let sym = load_struct_inplace_mut::<elf::Sym64<LE >>(
|
||||
// exec_mmap,
|
||||
// dynsym_offset as usize + *i as usize * mem::size_of::<elf::Sym64<LittleEndian>>(),
|
||||
// dynsym_offset as usize + *i as usize * mem::size_of::<elf::Sym64<LE >>(),
|
||||
// );
|
||||
// sym.st_value = endian::U64::new(LittleEndian, func_virt_offset as u64);
|
||||
// sym.st_value = endian::U64::new(LE , func_virt_offset as u64);
|
||||
// sym.st_size = endian::U64::new(
|
||||
// LittleEndian,
|
||||
// LE ,
|
||||
// match app_func_size_map.get(func_name) {
|
||||
// Some(size) => *size,
|
||||
// None => {
|
||||
|
Loading…
Reference in New Issue
Block a user