authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-13 15:18:18+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-15 08:59:20+01:00
log2e7a48d6bf6ca3ee4c1fdac04733fd2adb096d06
treed942b1441bc0d0a3e5bc6b5425977cb8515e8e41
parentab328aca3365102cea95ea8c1f5e1e8ca8793dc5

macho: fix section size calculation when no prealloc

Add test for common symbol alignment.

1 files changed, 33 insertions(+), 15 deletions(-)

src/link/MachO.zig+33-15
......@@ -2163,7 +2163,7 @@ fn createDyldPrivateAtom(self: *MachO) !void {
21632163 const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match);
21642164 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
21652165 sym.n_value = vaddr;
2166 } else try self.addAtomAndBumpSectionSize(atom, match);
2166 } else try self.addAtomToSection(atom, match);
21672167
21682168 sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
21692169}
......@@ -2297,7 +2297,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
22972297 const vaddr = try self.allocateAtom(atom, atom.size, alignment_pow_2, match);
22982298 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
22992299 sym.n_value = vaddr;
2300 } else try self.addAtomAndBumpSectionSize(atom, match);
2300 } else try self.addAtomToSection(atom, match);
23012301
23022302 sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
23032303}
......@@ -2513,7 +2513,7 @@ fn createTentativeDefAtoms(self: *MachO) !void {
25132513 const vaddr = try self.allocateAtom(atom, size, alignment_pow_2, match);
25142514 local_sym.n_value = vaddr;
25152515 global_sym.n_value = vaddr;
2516 } else try self.addAtomAndBumpSectionSize(atom, match);
2516 } else try self.addAtomToSection(atom, match);
25172517 }
25182518}
25192519
......@@ -2566,7 +2566,7 @@ fn createDsoHandleAtom(self: *MachO) !void {
25662566 const sym = &self.locals.items[local_sym_index];
25672567 const vaddr = try self.allocateAtom(atom, 0, 1, match);
25682568 sym.n_value = vaddr;
2569 } else try self.addAtomAndBumpSectionSize(atom, match);
2569 } else try self.addAtomToSection(atom, match);
25702570 }
25712571}
25722572
......@@ -2912,7 +2912,7 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {
29122912 const sym = &self.locals.items[local_sym_index];
29132913 const vaddr = try self.allocateAtom(atom, 0, 1, match);
29142914 sym.n_value = vaddr;
2915 } else try self.addAtomAndBumpSectionSize(atom, match);
2915 } else try self.addAtomToSection(atom, match);
29162916
29172917 self.mh_execute_header_index = local_sym_index;
29182918}
......@@ -2972,7 +2972,7 @@ fn resolveDyldStubBinder(self: *MachO) !void {
29722972 const vaddr = try self.allocateAtom(atom, @sizeOf(u64), 8, match);
29732973 log.debug("allocated {s} atom at 0x{x}", .{ self.getString(sym.n_strx), vaddr });
29742974 atom_sym.n_value = vaddr;
2975 } else try self.addAtomAndBumpSectionSize(atom, match);
2975 } else try self.addAtomToSection(atom, match);
29762976
29772977 atom_sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
29782978}
......@@ -4473,13 +4473,36 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
44734473
44744474 // Allocate the sections according to their alignment at the beginning of the segment.
44754475 var start: u64 = offset;
4476 for (seg.sections.items) |*sect| {
4476 for (seg.sections.items) |*sect, sect_id| {
44774477 const alignment = try math.powi(u32, 2, sect.@"align");
44784478 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
4479 const end = start_aligned + sect.size;
44804479 sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned);
44814480 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;
44834506 }
44844507
44854508 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
48274850 return vaddr;
48284851}
48294852
4830fn addAtomAndBumpSectionSize(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
4853fn addAtomToSection(self: *MachO, atom: *Atom, match: MatchingSection) !void {
48364854 if (self.atoms.getPtr(match)) |last| {
48374855 last.*.next = atom;
48384856 atom.prev = last.*;