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 {...@@ -543,11 +543,13 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
543 }543 }
544 }544 }
545545
546 if (zld.last_text_block) |last| {546 if (zld.blocks.getPtr(match)) |last| {
547 last.next = block;547 last.*.next = block;
548 block.prev = last;548 block.prev = last.*;
549 last.* = block;
550 } else {
551 try zld.blocks.putNoClobber(zld.allocator, match, block);
549 }552 }
550 zld.last_text_block = block;
551 }553 }
552554
553 break :next;555 break :next;
...@@ -607,11 +609,13 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {...@@ -607,11 +609,13 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
607 mem.set(u8, block.code, 0);609 mem.set(u8, block.code, 0);
608 }610 }
609611
610 if (zld.last_text_block) |last| {612 if (zld.blocks.getPtr(match)) |last| {
611 last.next = block;613 last.*.next = block;
612 block.prev = last;614 block.prev = last.*;
615 last.* = block;
616 } else {
617 try zld.blocks.putNoClobber(zld.allocator, match, block);
613 }618 }
614 zld.last_text_block = block;
615 }619 }
616 }620 }
617}621}
src/link/MachO/Zld.zig+56-18
...@@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{},...@@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{},
112112
113stub_helper_stubs_start_off: ?u64 = null,113stub_helper_stubs_start_off: ?u64 = null,
114114
115last_text_block: ?*TextBlock = null,115blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
116116
117pub const Output = struct {117pub const Output = struct {
118 tag: enum { exe, dylib },118 tag: enum { exe, dylib },
...@@ -225,6 +225,9 @@ pub fn deinit(self: *Zld) void {...@@ -225,6 +225,9 @@ pub fn deinit(self: *Zld) void {
225225
226 self.globals.deinit(self.allocator);226 self.globals.deinit(self.allocator);
227 self.strtab.deinit();227 self.strtab.deinit();
228
229 // TODO dealloc all blocks
230 self.blocks.deinit(self.allocator);
228}231}
229232
230pub fn closeFiles(self: Zld) void {233pub fn closeFiles(self: Zld) void {
...@@ -268,6 +271,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg...@@ -268,6 +271,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
268 try self.addRpaths(args.rpaths);271 try self.addRpaths(args.rpaths);
269 try self.addDataInCodeLC();272 try self.addDataInCodeLC();
270 try self.addCodeSignatureLC();273 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 }
271 return error.TODO;283 return error.TODO;
272 // try self.allocateTextSegment();284 // try self.allocateTextSegment();
273 // try self.allocateDataConstSegment();285 // try self.allocateDataConstSegment();
...@@ -835,6 +847,30 @@ fn sortSections(self: *Zld) !void {...@@ -835,6 +847,30 @@ fn sortSections(self: *Zld) !void {
835 maybe_index.* = new_index;847 maybe_index.* = new_index;
836 }848 }
837 }849 }
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 }
838}874}
839875
840fn allocateTextSegment(self: *Zld) !void {876fn allocateTextSegment(self: *Zld) !void {
...@@ -1403,13 +1439,19 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1403,13 +1439,19 @@ fn resolveSymbols(self: *Zld) !void {
1403 try self.locals.append(self.allocator, symbol);1439 try self.locals.append(self.allocator, symbol);
1404 },1440 },
1405 .tentative => |tent| {1441 .tentative => |tent| {
1406 if (self.common_section_index == null) {1442 const match: MatchingSection = blk: {
1407 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;1443 if (self.common_section_index == null) {
1408 self.common_section_index = @intCast(u16, data_seg.sections.items.len);1444 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1409 try data_seg.addSection(self.allocator, "__common", .{1445 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
1410 .flags = macho.S_ZEROFILL,1446 try data_seg.addSection(self.allocator, "__common", .{
1411 });1447 .flags = macho.S_ZEROFILL,
1412 }1448 });
1449 }
1450 break :blk .{
1451 .seg = self.data_segment_cmd_index.?,
1452 .sect = self.common_section_index.?,
1453 };
1454 };
14131455
1414 const size = tent.size;1456 const size = tent.size;
1415 const code = try self.allocator.alloc(u8, size);1457 const code = try self.allocator.alloc(u8, size);
...@@ -1439,13 +1481,13 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1439,13 +1481,13 @@ fn resolveSymbols(self: *Zld) !void {
1439 .alignment = alignment,1481 .alignment = alignment,
1440 };1482 };
14411483
1442 // TODO I'm not 100% sure about this yet, but I believe we should keep a separate list of1484 if (self.blocks.getPtr(match)) |last| {
1443 // TextBlocks per segment.1485 last.*.next = block;
1444 if (self.last_text_block) |last| {1486 block.prev = last.*;
1445 last.next = block;1487 last.* = block;
1446 block.prev = last;1488 } else {
1489 try self.blocks.putNoClobber(self.allocator, match, block);
1447 }1490 }
1448 self.last_text_block = block;
1449 },1491 },
1450 else => {},1492 else => {},
1451 }1493 }
...@@ -1527,10 +1569,6 @@ fn parseTextBlocks(self: *Zld) !void {...@@ -1527,10 +1569,6 @@ fn parseTextBlocks(self: *Zld) !void {
1527 for (self.objects.items) |object| {1569 for (self.objects.items) |object| {
1528 try object.parseTextBlocks(self);1570 try object.parseTextBlocks(self);
1529 }1571 }
1530
1531 if (self.last_text_block) |block| {
1532 block.print(self);
1533 }
1534}1572}
15351573
1536fn populateMetadata(self: *Zld) !void {1574fn populateMetadata(self: *Zld) !void {