| ... | @@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, | ... | @@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 112 | | 112 | |
| 113 | stub_helper_stubs_start_off: ?u64 = null, | 113 | stub_helper_stubs_start_off: ?u64 = null, |
| 114 | | 114 | |
| 115 | last_text_block: ?*TextBlock = null, | 115 | blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{}, |
| 116 | | 116 | |
| 117 | pub const Output = struct { | 117 | pub 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 { |
| 225 | | 225 | |
| 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 | } |
| 229 | | 232 | |
| 230 | pub fn closeFiles(self: Zld) void { | 233 | pub 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 | } |
| 839 | | 875 | |
| 840 | fn allocateTextSegment(self: *Zld) !void { | 876 | fn 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 | }; |
| 1413 | | 1455 | |
| 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 | }; |
| 1441 | | 1483 | |
| 1442 | // TODO I'm not 100% sure about this yet, but I believe we should keep a separate list of | 1484 | 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 | } |
| 1535 | | 1573 | |
| 1536 | fn populateMetadata(self: *Zld) !void { | 1574 | fn populateMetadata(self: *Zld) !void { |