| ... | @@ -2163,7 +2163,7 @@ fn createDyldPrivateAtom(self: *MachO) !void { | ... | @@ -2163,7 +2163,7 @@ fn createDyldPrivateAtom(self: *MachO) !void { |
| 2163 | const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match); | 2163 | const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match); |
| 2164 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); | 2164 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 2165 | sym.n_value = vaddr; | 2165 | sym.n_value = vaddr; |
| 2166 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2166 | } else try self.addAtomToSection(atom, match); |
| 2167 | | 2167 | |
| 2168 | sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); | 2168 | sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 2169 | } | 2169 | } |
| ... | @@ -2297,7 +2297,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -2297,7 +2297,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 2297 | const vaddr = try self.allocateAtom(atom, atom.size, alignment_pow_2, match); | 2297 | const vaddr = try self.allocateAtom(atom, atom.size, alignment_pow_2, match); |
| 2298 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); | 2298 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 2299 | sym.n_value = vaddr; | 2299 | sym.n_value = vaddr; |
| 2300 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2300 | } else try self.addAtomToSection(atom, match); |
| 2301 | | 2301 | |
| 2302 | sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); | 2302 | sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 2303 | } | 2303 | } |
| ... | @@ -2513,7 +2513,7 @@ fn createTentativeDefAtoms(self: *MachO) !void { | ... | @@ -2513,7 +2513,7 @@ fn createTentativeDefAtoms(self: *MachO) !void { |
| 2513 | const vaddr = try self.allocateAtom(atom, size, alignment_pow_2, match); | 2513 | const vaddr = try self.allocateAtom(atom, size, alignment_pow_2, match); |
| 2514 | local_sym.n_value = vaddr; | 2514 | local_sym.n_value = vaddr; |
| 2515 | global_sym.n_value = vaddr; | 2515 | global_sym.n_value = vaddr; |
| 2516 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2516 | } else try self.addAtomToSection(atom, match); |
| 2517 | } | 2517 | } |
| 2518 | } | 2518 | } |
| 2519 | | 2519 | |
| ... | @@ -2566,7 +2566,7 @@ fn createDsoHandleAtom(self: *MachO) !void { | ... | @@ -2566,7 +2566,7 @@ fn createDsoHandleAtom(self: *MachO) !void { |
| 2566 | const sym = &self.locals.items[local_sym_index]; | 2566 | const sym = &self.locals.items[local_sym_index]; |
| 2567 | const vaddr = try self.allocateAtom(atom, 0, 1, match); | 2567 | const vaddr = try self.allocateAtom(atom, 0, 1, match); |
| 2568 | sym.n_value = vaddr; | 2568 | sym.n_value = vaddr; |
| 2569 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2569 | } else try self.addAtomToSection(atom, match); |
| 2570 | } | 2570 | } |
| 2571 | } | 2571 | } |
| 2572 | | 2572 | |
| ... | @@ -2912,7 +2912,7 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { | ... | @@ -2912,7 +2912,7 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { |
| 2912 | const sym = &self.locals.items[local_sym_index]; | 2912 | const sym = &self.locals.items[local_sym_index]; |
| 2913 | const vaddr = try self.allocateAtom(atom, 0, 1, match); | 2913 | const vaddr = try self.allocateAtom(atom, 0, 1, match); |
| 2914 | sym.n_value = vaddr; | 2914 | sym.n_value = vaddr; |
| 2915 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2915 | } else try self.addAtomToSection(atom, match); |
| 2916 | | 2916 | |
| 2917 | self.mh_execute_header_index = local_sym_index; | 2917 | self.mh_execute_header_index = local_sym_index; |
| 2918 | } | 2918 | } |
| ... | @@ -2972,7 +2972,7 @@ fn resolveDyldStubBinder(self: *MachO) !void { | ... | @@ -2972,7 +2972,7 @@ fn resolveDyldStubBinder(self: *MachO) !void { |
| 2972 | const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match); | 2972 | const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match); |
| 2973 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); | 2973 | log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 2974 | atom_sym.n_value = vaddr; | 2974 | atom_sym.n_value = vaddr; |
| 2975 | } else try self.addAtomAndBumpSectionSize(atom, match); | 2975 | } else try self.addAtomToSection(atom, match); |
| 2976 | | 2976 | |
| 2977 | atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); | 2977 | atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 2978 | } | 2978 | } |
| ... | @@ -4473,13 +4473,36 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { | ... | @@ -4473,13 +4473,36 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { |
| 4473 | | 4473 | |
| 4474 | // Allocate the sections according to their alignment at the beginning of the segment. | 4474 | // Allocate the sections according to their alignment at the beginning of the segment. |
| 4475 | var start: u64 = offset; | 4475 | var start: u64 = offset; |
| 4476 | for (seg.sections.items) |*sect| { | 4476 | for (seg.sections.items) |*sect, sect_id| { |
| 4477 | const alignment = try math.powi(u32, 2, sect.@"align"); | 4477 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| 4478 | const start_aligned = mem.alignForwardGeneric(u64, start, alignment); | 4478 | const start_aligned = mem.alignForwardGeneric(u64, start, alignment); |
| 4479 | const end = start_aligned + sect.size; | | |
| 4480 | sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned); | 4479 | sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned); |
| 4481 | sect.addr = seg.inner.vmaddr + start_aligned; | 4480 | sect.addr = seg.inner.vmaddr + start_aligned; |
| 4482 | start = end; | 4481 | |
| | 4482 | // Recalculate section size given the allocated start address |
| | 4483 | sect.size = if (self.atoms.get(.{ |
| | 4484 | .seg = index, |
| | 4485 | .sect = @intCast(u16, sect_id), |
| | 4486 | })) |last_atom| blk: { |
| | 4487 | var atom = last_atom; |
| | 4488 | while (atom.prev) |prev| { |
| | 4489 | atom = prev; |
| | 4490 | } |
| | 4491 | |
| | 4492 | var base_addr = sect.addr; |
| | 4493 | |
| | 4494 | while (true) { |
| | 4495 | const atom_alignment = try math.powi(u32, 2, atom.alignment); |
| | 4496 | base_addr = mem.alignForwardGeneric(u64, base_addr, atom_alignment) + atom.size; |
| | 4497 | if (atom.next) |next| { |
| | 4498 | atom = next; |
| | 4499 | } else break; |
| | 4500 | } |
| | 4501 | |
| | 4502 | break :blk base_addr - sect.addr; |
| | 4503 | } else 0; |
| | 4504 | |
| | 4505 | start = start_aligned + sect.size; |
| 4483 | } | 4506 | } |
| 4484 | | 4507 | |
| 4485 | const seg_size_aligned = mem.alignForwardGeneric(u64, start, self.page_size); | 4508 | const seg_size_aligned = mem.alignForwardGeneric(u64, start, self.page_size); |
| ... | @@ -4827,12 +4850,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m | ... | @@ -4827,12 +4850,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m |
| 4827 | return vaddr; | 4850 | return vaddr; |
| 4828 | } | 4851 | } |
| 4829 | | 4852 | |
| 4830 | fn addAtomAndBumpSectionSize(self: *MachO, atom: *Atom, match: MatchingSection) !void { | 4853 | fn addAtomToSection(self: *MachO, atom: *Atom, match: MatchingSection) !void { |
| 4831 | const seg = &self.load_commands.items[match.seg].segment; | | |
| 4832 | const sect = &seg.sections.items[match.sect]; | | |
| 4833 | const alignment = try math.powi(u32, 2, atom.alignment); | | |
| 4834 | sect.size = mem.alignForwardGeneric(u64, sect.size, alignment) + atom.size; | | |
| 4835 | | | |
| 4836 | if (self.atoms.getPtr(match)) |last| { | 4854 | if (self.atoms.getPtr(match)) |last| { |
| 4837 | last.*.next = atom; | 4855 | last.*.next = atom; |
| 4838 | atom.prev = last.*; | 4856 | atom.prev = last.*; |