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 {...@@ -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);
21672167
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);
23012301
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}
25192519
...@@ -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}
25722572
...@@ -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);
29162916
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);
29762976
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 {
44734473
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 }
44844507
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}
48294852
4830fn addAtomAndBumpSectionSize(self: *MachO, atom: *Atom, match: MatchingSection) !void {4853fn 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.*;