| ... | ... | @@ -112,7 +112,7 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 112 | 112 | |
| 113 | 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 | 117 | pub const Output = struct { |
| 118 | 118 | tag: enum { exe, dylib }, |
| ... | ... | @@ -225,6 +225,9 @@ pub fn deinit(self: *Zld) void { |
| 225 | 225 | |
| 226 | 226 | self.globals.deinit(self.allocator); |
| 227 | 227 | self.strtab.deinit(); |
| 228 | |
| 229 | // TODO dealloc all blocks |
| 230 | self.blocks.deinit(self.allocator); |
| 228 | 231 | } |
| 229 | 232 | |
| 230 | 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 | 271 | try self.addRpaths(args.rpaths); |
| 269 | 272 | try self.addDataInCodeLC(); |
| 270 | 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 | 283 | return error.TODO; |
| 272 | 284 | // try self.allocateTextSegment(); |
| 273 | 285 | // try self.allocateDataConstSegment(); |
| ... | ... | @@ -835,6 +847,30 @@ fn sortSections(self: *Zld) !void { |
| 835 | 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 | 876 | fn allocateTextSegment(self: *Zld) !void { |
| ... | ... | @@ -1403,13 +1439,19 @@ fn resolveSymbols(self: *Zld) !void { |
| 1403 | 1439 | try self.locals.append(self.allocator, symbol); |
| 1404 | 1440 | }, |
| 1405 | 1441 | .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 | }; |
| 1413 | 1455 | |
| 1414 | 1456 | const size = tent.size; |
| 1415 | 1457 | const code = try self.allocator.alloc(u8, size); |
| ... | ... | @@ -1439,13 +1481,13 @@ fn resolveSymbols(self: *Zld) !void { |
| 1439 | 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 |
| 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); |
| 1447 | 1490 | } |
| 1448 | | self.last_text_block = block; |
| 1449 | 1491 | }, |
| 1450 | 1492 | else => {}, |
| 1451 | 1493 | } |
| ... | ... | @@ -1527,10 +1569,6 @@ fn parseTextBlocks(self: *Zld) !void { |
| 1527 | 1569 | for (self.objects.items) |object| { |
| 1528 | 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 | 1574 | fn populateMetadata(self: *Zld) !void { |