authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-09 00:25:55+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-09 00:25:55+02:00
log9fb44e8e1fa4f07e44e2d354e09db9d953861e71
treeff2e06aee633e5f81a2306c1cb9701f4598f6b58
parente00b9d6192a09305c4160ccbeeb761a1f1af855a

macho: precompute total required size when parsing objects

This way, we can preallocate the necessary sizes for segments and sections upfront rather than doing it per parsed atom.

1 files changed, 41 insertions(+), 0 deletions(-)

src/link/MachO.zig+41
......@@ -2589,6 +2589,47 @@ fn resolveDyldStubBinder(self: *MachO) !void {
25892589}
25902590
25912591fn parseTextBlocks(self: *MachO) !void {
2592 var section_metadata = std.AutoHashMap(MatchingSection, struct {
2593 size: u64,
2594 alignment: u32,
2595 }).init(self.base.allocator);
2596 defer section_metadata.deinit();
2597
2598 for (self.objects.items) |object| {
2599 const seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
2600 for (seg.sections.items) |sect| {
2601 const match = (try self.getMatchingSection(sect)) orelse {
2602 log.debug("unhandled section", .{});
2603 continue;
2604 };
2605 const res = try section_metadata.getOrPut(match);
2606 if (!res.found_existing) {
2607 res.value_ptr.* = .{
2608 .size = 0,
2609 .alignment = 0,
2610 };
2611 }
2612 const alignment = try math.powi(u32, 2, sect.@"align");
2613 res.value_ptr.size += mem.alignForwardGeneric(u64, sect.size, alignment);
2614 res.value_ptr.alignment = math.max(res.value_ptr.alignment, sect.@"align");
2615 }
2616 }
2617
2618 var it = section_metadata.iterator();
2619 while (it.next()) |entry| {
2620 const match = entry.key_ptr.*;
2621 const metadata = entry.value_ptr.*;
2622 const seg = self.load_commands.items[match.seg].Segment;
2623 const sect = seg.sections.items[match.sect];
2624 log.debug("{s},{s} => size: 0x{x}, alignment: 0x{x}", .{
2625 commands.segmentName(sect),
2626 commands.sectionName(sect),
2627 metadata.size,
2628 metadata.alignment,
2629 });
2630 try self.growSection(match, @intCast(u32, metadata.size));
2631 }
2632
25922633 for (self.objects.items) |*object, object_id| {
25932634 try object.parseTextBlocks(self.base.allocator, @intCast(u16, object_id), self);
25942635 }