| ... | @@ -129,10 +129,15 @@ pub const TextBlock = struct { | ... | @@ -129,10 +129,15 @@ pub const TextBlock = struct { |
| 129 | size: u64, | 129 | size: u64, |
| 130 | alignment: u32, | 130 | alignment: u32, |
| 131 | rebases: std.ArrayList(u64), | 131 | rebases: std.ArrayList(u64), |
| 132 | tlv_offsets: std.ArrayList(u64), | 132 | tlv_offsets: std.ArrayList(TlvOffset), |
| 133 | next: ?*TextBlock = null, | 133 | next: ?*TextBlock = null, |
| 134 | prev: ?*TextBlock = null, | 134 | prev: ?*TextBlock = null, |
| 135 | | 135 | |
| | 136 | pub const TlvOffset = struct { |
| | 137 | local_sym_index: u32, |
| | 138 | offset: u64, |
| | 139 | }; |
| | 140 | |
| 136 | pub fn deinit(block: *TextBlock, allocator: *Allocator) void { | 141 | pub fn deinit(block: *TextBlock, allocator: *Allocator) void { |
| 137 | if (block.aliases) |aliases| { | 142 | if (block.aliases) |aliases| { |
| 138 | allocator.free(aliases); | 143 | allocator.free(aliases); |
| ... | @@ -281,10 +286,11 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg | ... | @@ -281,10 +286,11 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg |
| 281 | try self.addRpaths(args.rpaths); | 286 | try self.addRpaths(args.rpaths); |
| 282 | try self.addDataInCodeLC(); | 287 | try self.addDataInCodeLC(); |
| 283 | try self.addCodeSignatureLC(); | 288 | try self.addCodeSignatureLC(); |
| 284 | // try self.allocateTextSegment(); | 289 | try self.allocateTextSegment(); |
| 285 | // try self.allocateDataConstSegment(); | 290 | try self.allocateDataConstSegment(); |
| 286 | // try self.allocateDataSegment(); | 291 | try self.allocateDataSegment(); |
| 287 | // self.allocateLinkeditSegment(); | 292 | self.allocateLinkeditSegment(); |
| | 293 | try self.allocateTextBlocks(); |
| 288 | | 294 | |
| 289 | var it = self.blocks.iterator(); | 295 | var it = self.blocks.iterator(); |
| 290 | while (it.next()) |entry| { | 296 | while (it.next()) |entry| { |
| ... | @@ -292,6 +298,7 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg | ... | @@ -292,6 +298,7 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg |
| 292 | const sect = seg.sections.items[entry.key_ptr.sect]; | 298 | const sect = seg.sections.items[entry.key_ptr.sect]; |
| 293 | | 299 | |
| 294 | log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); | 300 | log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); |
| | 301 | log.warn("{}", .{sect}); |
| 295 | entry.value_ptr.*.print(self); | 302 | entry.value_ptr.*.print(self); |
| 296 | } | 303 | } |
| 297 | return error.TODO; | 304 | return error.TODO; |
| ... | @@ -865,14 +872,14 @@ fn sortSections(self: *Zld) !void { | ... | @@ -865,14 +872,14 @@ fn sortSections(self: *Zld) !void { |
| 865 | while (it.next()) |entry| { | 872 | while (it.next()) |entry| { |
| 866 | const old = entry.key_ptr.*; | 873 | const old = entry.key_ptr.*; |
| 867 | const sect = if (old.seg == self.text_segment_cmd_index.?) | 874 | const sect = if (old.seg == self.text_segment_cmd_index.?) |
| 868 | text_index_mapping.get(old.sect) | 875 | text_index_mapping.get(old.sect).? |
| 869 | else if (old.seg == self.data_const_segment_cmd_index.?) | 876 | else if (old.seg == self.data_const_segment_cmd_index.?) |
| 870 | data_const_index_mapping.get(old.sect) | 877 | data_const_index_mapping.get(old.sect).? |
| 871 | else | 878 | else |
| 872 | data_index_mapping.get(old.sect); | 879 | data_index_mapping.get(old.sect).?; |
| 873 | transient.putAssumeCapacityNoClobber(.{ | 880 | transient.putAssumeCapacityNoClobber(.{ |
| 874 | .seg = old.seg, | 881 | .seg = old.seg, |
| 875 | .sect = old.sect, | 882 | .sect = sect, |
| 876 | }, entry.value_ptr.*); | 883 | }, entry.value_ptr.*); |
| 877 | } | 884 | } |
| 878 | | 885 | |
| ... | @@ -880,6 +887,18 @@ fn sortSections(self: *Zld) !void { | ... | @@ -880,6 +887,18 @@ fn sortSections(self: *Zld) !void { |
| 880 | self.blocks.deinit(self.allocator); | 887 | self.blocks.deinit(self.allocator); |
| 881 | self.blocks = transient; | 888 | self.blocks = transient; |
| 882 | } | 889 | } |
| | 890 | |
| | 891 | for (self.locals.items) |sym, i| { |
| | 892 | if (i == 0) continue; // skip the null symbol |
| | 893 | assert(sym.payload == .regular); |
| | 894 | const reg = &sym.payload.regular; |
| | 895 | reg.section_id = if (reg.segment_id == self.text_segment_cmd_index.?) |
| | 896 | text_index_mapping.get(reg.section_id).? |
| | 897 | else if (reg.segment_id == self.data_const_segment_cmd_index.?) |
| | 898 | data_const_index_mapping.get(reg.section_id).? |
| | 899 | else |
| | 900 | data_index_mapping.get(reg.section_id).?; |
| | 901 | } |
| 883 | } | 902 | } |
| 884 | | 903 | |
| 885 | fn allocateTextSegment(self: *Zld) !void { | 904 | fn allocateTextSegment(self: *Zld) !void { |
| ... | @@ -991,50 +1010,26 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { | ... | @@ -991,50 +1010,26 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { |
| 991 | seg.inner.vmsize = seg_size_aligned; | 1010 | seg.inner.vmsize = seg_size_aligned; |
| 992 | } | 1011 | } |
| 993 | | 1012 | |
| 994 | fn allocateSymbol(self: *Zld, symbol: *Symbol) !void { | 1013 | fn allocateTextBlocks(self: *Zld) !void { |
| 995 | const reg = &symbol.payload.regular; | 1014 | var it = self.blocks.iterator(); |
| 996 | const object = reg.file orelse return; | 1015 | while (it.next()) |entry| { |
| 997 | const source_sect = &object.sections.items[reg.section]; | 1016 | const match = entry.key_ptr.*; |
| 998 | const target_map = source_sect.target_map orelse { | 1017 | var block: *TextBlock = entry.value_ptr.*; |
| 999 | log.debug("section '{s},{s}' not mapped for symbol '{s}'", .{ | 1018 | |
| 1000 | segmentName(source_sect.inner), | 1019 | const seg = self.load_commands.items[match.seg].Segment; |
| 1001 | sectionName(source_sect.inner), | 1020 | const sect = seg.sections.items[match.sect]; |
| 1002 | symbol.name, | 1021 | var base_addr: u64 = sect.addr + sect.size; |
| 1003 | }); | 1022 | |
| 1004 | return; | 1023 | while (true) { |
| 1005 | }; | 1024 | const sym = self.locals.items[block.local_sym_index]; |
| 1006 | | 1025 | assert(sym.payload == .regular); |
| 1007 | const target_seg = self.load_commands.items[target_map.segment_id].Segment; | 1026 | sym.payload.regular.address = base_addr - block.size; |
| 1008 | const target_sect = target_seg.sections.items[target_map.section_id]; | 1027 | base_addr -= block.size; |
| 1009 | const target_addr = target_sect.addr + target_map.offset; | 1028 | |
| 1010 | const address = reg.address - source_sect.inner.addr + target_addr; | 1029 | if (block.prev) |prev| { |
| 1011 | | 1030 | block = prev; |
| 1012 | log.debug("resolving symbol '{s}' at 0x{x}", .{ symbol.name, address }); | 1031 | } else break; |
| 1013 | | | |
| 1014 | // TODO there might be a more generic way of doing this. | | |
| 1015 | var section: u8 = 0; | | |
| 1016 | for (self.load_commands.items) |cmd, cmd_id| { | | |
| 1017 | if (cmd != .Segment) break; | | |
| 1018 | if (cmd_id == target_map.segment_id) { | | |
| 1019 | section += @intCast(u8, target_map.section_id) + 1; | | |
| 1020 | break; | | |
| 1021 | } | 1032 | } |
| 1022 | section += @intCast(u8, cmd.Segment.sections.items.len); | | |
| 1023 | } | | |
| 1024 | | | |
| 1025 | reg.address = address; | | |
| 1026 | reg.section = section; | | |
| 1027 | } | | |
| 1028 | | | |
| 1029 | fn allocateSymbols(self: *Zld) !void { | | |
| 1030 | for (self.locals.items) |symbol| { | | |
| 1031 | if (symbol.payload != .regular) continue; | | |
| 1032 | try self.allocateSymbol(symbol); | | |
| 1033 | } | | |
| 1034 | | | |
| 1035 | for (self.globals.values()) |symbol| { | | |
| 1036 | if (symbol.payload != .regular) continue; | | |
| 1037 | try self.allocateSymbol(symbol); | | |
| 1038 | } | 1033 | } |
| 1039 | } | 1034 | } |
| 1040 | | 1035 | |
| ... | @@ -1487,7 +1482,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1487,7 +1482,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 1487 | .code = code, | 1482 | .code = code, |
| 1488 | .relocs = std.ArrayList(Relocation).init(self.allocator), | 1483 | .relocs = std.ArrayList(Relocation).init(self.allocator), |
| 1489 | .rebases = std.ArrayList(u64).init(self.allocator), | 1484 | .rebases = std.ArrayList(u64).init(self.allocator), |
| 1490 | .tlv_offsets = std.ArrayList(u64).init(self.allocator), | 1485 | .tlv_offsets = std.ArrayList(TextBlock.TlvOffset).init(self.allocator), |
| 1491 | .size = size, | 1486 | .size = size, |
| 1492 | .alignment = alignment, | 1487 | .alignment = alignment, |
| 1493 | }; | 1488 | }; |