authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-07 14:57:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:47+02:00
log7c662db8d95670f8ac0c88e9a2d6f49ef6782f13
tree69b8e330b43555de544e5c55597b20f7398ddad8
parenta04bc1ed14319bf22769b01709bb7174388734f0

zld: keep text blocks per segment,section pair


2 files changed, 68 insertions(+), 26 deletions(-)

src/link/MachO/Object.zig+12-8
......@@ -543,11 +543,13 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
543543 }
544544 }
545545
546 if (zld.last_text_block) |last| {
547 last.next = block;
548 block.prev = last;
546 if (zld.blocks.getPtr(match)) |last| {
547 last.*.next = block;
548 block.prev = last.*;
549 last.* = block;
550 } else {
551 try zld.blocks.putNoClobber(zld.allocator, match, block);
549552 }
550 zld.last_text_block = block;
551553 }
552554
553555 break :next;
......@@ -607,11 +609,13 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
607609 mem.set(u8, block.code, 0);
608610 }
609611
610 if (zld.last_text_block) |last| {
611 last.next = block;
612 block.prev = last;
612 if (zld.blocks.getPtr(match)) |last| {
613 last.*.next = block;
614 block.prev = last.*;
615 last.* = block;
616 } else {
617 try zld.blocks.putNoClobber(zld.allocator, match, block);
613618 }
614 zld.last_text_block = block;
615619 }
616620 }
617621}
src/link/MachO/Zld.zig+56-18
......@@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{},
112112
113113stub_helper_stubs_start_off: ?u64 = null,
114114
115last_text_block: ?*TextBlock = null,
115blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
116116
117117pub const Output = struct {
118118 tag: enum { exe, dylib },
......@@ -225,6 +225,9 @@ pub fn deinit(self: *Zld) void {
225225
226226 self.globals.deinit(self.allocator);
227227 self.strtab.deinit();
228
229 // TODO dealloc all blocks
230 self.blocks.deinit(self.allocator);
228231}
229232
230233pub fn closeFiles(self: Zld) void {
......@@ -268,6 +271,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
268271 try self.addRpaths(args.rpaths);
269272 try self.addDataInCodeLC();
270273 try self.addCodeSignatureLC();
274
275 var it = self.blocks.iterator();
276 while (it.next()) |entry| {
277 const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
278 const sect = seg.sections.items[entry.key_ptr.sect];
279
280 log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
281 entry.value_ptr.*.print(self);
282 }
271283 return error.TODO;
272284 // try self.allocateTextSegment();
273285 // try self.allocateDataConstSegment();
......@@ -835,6 +847,30 @@ fn sortSections(self: *Zld) !void {
835847 maybe_index.* = new_index;
836848 }
837849 }
850
851 {
852 var transient: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{};
853 try transient.ensureCapacity(self.allocator, self.blocks.count());
854
855 var it = self.blocks.iterator();
856 while (it.next()) |entry| {
857 const old = entry.key_ptr.*;
858 const sect = if (old.seg == self.text_segment_cmd_index.?)
859 text_index_mapping.get(old.sect)
860 else if (old.seg == self.data_const_segment_cmd_index.?)
861 data_const_index_mapping.get(old.sect)
862 else
863 data_index_mapping.get(old.sect);
864 transient.putAssumeCapacityNoClobber(.{
865 .seg = old.seg,
866 .sect = old.sect,
867 }, entry.value_ptr.*);
868 }
869
870 self.blocks.clearAndFree(self.allocator);
871 self.blocks.deinit(self.allocator);
872 self.blocks = transient;
873 }
838874}
839875
840876fn allocateTextSegment(self: *Zld) !void {
......@@ -1403,13 +1439,19 @@ fn resolveSymbols(self: *Zld) !void {
14031439 try self.locals.append(self.allocator, symbol);
14041440 },
14051441 .tentative => |tent| {
1406 if (self.common_section_index == null) {
1407 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1408 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
1409 try data_seg.addSection(self.allocator, "__common", .{
1410 .flags = macho.S_ZEROFILL,
1411 });
1412 }
1442 const match: MatchingSection = blk: {
1443 if (self.common_section_index == null) {
1444 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1445 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
1446 try data_seg.addSection(self.allocator, "__common", .{
1447 .flags = macho.S_ZEROFILL,
1448 });
1449 }
1450 break :blk .{
1451 .seg = self.data_segment_cmd_index.?,
1452 .sect = self.common_section_index.?,
1453 };
1454 };
14131455
14141456 const size = tent.size;
14151457 const code = try self.allocator.alloc(u8, size);
......@@ -1439,13 +1481,13 @@ fn resolveSymbols(self: *Zld) !void {
14391481 .alignment = alignment,
14401482 };
14411483
1442 // TODO I'm not 100% sure about this yet, but I believe we should keep a separate list of
1443 // TextBlocks per segment.
1444 if (self.last_text_block) |last| {
1445 last.next = block;
1446 block.prev = last;
1484 if (self.blocks.getPtr(match)) |last| {
1485 last.*.next = block;
1486 block.prev = last.*;
1487 last.* = block;
1488 } else {
1489 try self.blocks.putNoClobber(self.allocator, match, block);
14471490 }
1448 self.last_text_block = block;
14491491 },
14501492 else => {},
14511493 }
......@@ -1527,10 +1569,6 @@ fn parseTextBlocks(self: *Zld) !void {
15271569 for (self.objects.items) |object| {
15281570 try object.parseTextBlocks(self);
15291571 }
1530
1531 if (self.last_text_block) |block| {
1532 block.print(self);
1533 }
15341572}
15351573
15361574fn populateMetadata(self: *Zld) !void {