| ... | @@ -173,6 +173,12 @@ pub const TextBlock = struct { | ... | @@ -173,6 +173,12 @@ pub const TextBlock = struct { |
| 173 | self.tlv_offsets.deinit(); | 173 | self.tlv_offsets.deinit(); |
| 174 | } | 174 | } |
| 175 | | 175 | |
| | 176 | pub fn resolveRelocs(self: *TextBlock, zld: *Zld) !void { |
| | 177 | for (self.relocs.items) |rel| { |
| | 178 | try rel.resolve(zld); |
| | 179 | } |
| | 180 | } |
| | 181 | |
| 176 | pub fn print_this(self: *const TextBlock, zld: *Zld) void { | 182 | pub fn print_this(self: *const TextBlock, zld: *Zld) void { |
| 177 | log.warn("TextBlock", .{}); | 183 | log.warn("TextBlock", .{}); |
| 178 | log.warn(" | {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] }); | 184 | log.warn(" | {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] }); |
| ... | @@ -328,11 +334,10 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg | ... | @@ -328,11 +334,10 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg |
| 328 | const sect = seg.sections.items[entry.key_ptr.sect]; | 334 | const sect = seg.sections.items[entry.key_ptr.sect]; |
| 329 | | 335 | |
| 330 | log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); | 336 | log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) }); |
| 331 | log.warn("{}", .{sect}); | 337 | log.warn(" {}", .{sect}); |
| 332 | entry.value_ptr.*.print(self); | 338 | entry.value_ptr.*.print(self); |
| 333 | } | 339 | } |
| 334 | return error.TODO; | 340 | try self.flush(); |
| 335 | // try self.flush(); | | |
| 336 | } | 341 | } |
| 337 | | 342 | |
| 338 | fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u8) !void { | 343 | fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u8) !void { |
| ... | @@ -1041,6 +1046,8 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { | ... | @@ -1041,6 +1046,8 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { |
| 1041 | } | 1046 | } |
| 1042 | | 1047 | |
| 1043 | fn allocateTextBlocks(self: *Zld) !void { | 1048 | fn allocateTextBlocks(self: *Zld) !void { |
| | 1049 | log.warn("allocating text blocks", .{}); |
| | 1050 | |
| 1044 | var it = self.blocks.iterator(); | 1051 | var it = self.blocks.iterator(); |
| 1045 | while (it.next()) |entry| { | 1052 | while (it.next()) |entry| { |
| 1046 | const match = entry.key_ptr.*; | 1053 | const match = entry.key_ptr.*; |
| ... | @@ -1050,13 +1057,34 @@ fn allocateTextBlocks(self: *Zld) !void { | ... | @@ -1050,13 +1057,34 @@ fn allocateTextBlocks(self: *Zld) !void { |
| 1050 | const sect = seg.sections.items[match.sect]; | 1057 | const sect = seg.sections.items[match.sect]; |
| 1051 | var base_addr: u64 = sect.addr + sect.size; | 1058 | var base_addr: u64 = sect.addr + sect.size; |
| 1052 | | 1059 | |
| | 1060 | log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) }); |
| | 1061 | log.warn(" {}", .{sect}); |
| | 1062 | |
| 1053 | while (true) { | 1063 | while (true) { |
| 1054 | base_addr -= block.size; | 1064 | const block_alignment = try math.powi(u32, 2, block.alignment); |
| | 1065 | base_addr = mem.alignBackwardGeneric(u64, base_addr - block.size, block_alignment); |
| 1055 | | 1066 | |
| 1056 | const sym = self.locals.items[block.local_sym_index]; | 1067 | const sym = self.locals.items[block.local_sym_index]; |
| 1057 | assert(sym.payload == .regular); | 1068 | assert(sym.payload == .regular); |
| 1058 | sym.payload.regular.address = base_addr; | 1069 | sym.payload.regular.address = base_addr; |
| 1059 | | 1070 | |
| | 1071 | log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ |
| | 1072 | sym.name, |
| | 1073 | base_addr, |
| | 1074 | base_addr + block.size, |
| | 1075 | block.size, |
| | 1076 | block.alignment, |
| | 1077 | }); |
| | 1078 | |
| | 1079 | // Update each alias (if any) |
| | 1080 | if (block.aliases) |aliases| { |
| | 1081 | for (aliases) |index| { |
| | 1082 | const alias_sym = self.locals.items[index]; |
| | 1083 | assert(alias_sym.payload == .regular); |
| | 1084 | alias_sym.payload.regular.address = base_addr; |
| | 1085 | } |
| | 1086 | } |
| | 1087 | |
| 1060 | // Update each symbol contained within the TextBlock | 1088 | // Update each symbol contained within the TextBlock |
| 1061 | if (block.contained) |contained| { | 1089 | if (block.contained) |contained| { |
| 1062 | for (contained) |sym_at_off| { | 1090 | for (contained) |sym_at_off| { |
| ... | @@ -1073,6 +1101,37 @@ fn allocateTextBlocks(self: *Zld) !void { | ... | @@ -1073,6 +1101,37 @@ fn allocateTextBlocks(self: *Zld) !void { |
| 1073 | } | 1101 | } |
| 1074 | } | 1102 | } |
| 1075 | | 1103 | |
| | 1104 | fn writeTextBlocks(self: *Zld) !void { |
| | 1105 | var it = self.blocks.iterator(); |
| | 1106 | while (it.next()) |entry| { |
| | 1107 | const match = entry.key_ptr.*; |
| | 1108 | var block: *TextBlock = entry.value_ptr.*; |
| | 1109 | |
| | 1110 | const seg = self.load_commands.items[match.seg].Segment; |
| | 1111 | const sect = seg.sections.items[match.sect]; |
| | 1112 | |
| | 1113 | log.warn("writing text blocks for section {s},{s}", .{ segmentName(sect), sectionName(sect) }); |
| | 1114 | |
| | 1115 | var code = try self.allocator.alloc(u8, sect.size); |
| | 1116 | defer self.allocator.free(code); |
| | 1117 | |
| | 1118 | var base_off: u64 = sect.size; |
| | 1119 | |
| | 1120 | while (true) { |
| | 1121 | base_off -= block.size; |
| | 1122 | |
| | 1123 | try block.resolveRelocs(self); |
| | 1124 | mem.copy(u8, code[base_off..][0..block.size], block.code); |
| | 1125 | |
| | 1126 | if (block.prev) |prev| { |
| | 1127 | block = prev; |
| | 1128 | } else break; |
| | 1129 | } |
| | 1130 | |
| | 1131 | try self.file.?.pwriteAll(code, sect.offset); |
| | 1132 | } |
| | 1133 | } |
| | 1134 | |
| 1076 | fn writeStubHelperCommon(self: *Zld) !void { | 1135 | fn writeStubHelperCommon(self: *Zld) !void { |
| 1077 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 1136 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1078 | const stub_helper = &text_segment.sections.items[self.stub_helper_section_index.?]; | 1137 | const stub_helper = &text_segment.sections.items[self.stub_helper_section_index.?]; |
| ... | @@ -1941,104 +2000,105 @@ fn addRpaths(self: *Zld, rpaths: []const []const u8) !void { | ... | @@ -1941,104 +2000,105 @@ fn addRpaths(self: *Zld, rpaths: []const []const u8) !void { |
| 1941 | } | 2000 | } |
| 1942 | | 2001 | |
| 1943 | fn flush(self: *Zld) !void { | 2002 | fn flush(self: *Zld) !void { |
| 1944 | try self.writeStubHelperCommon(); | 2003 | try self.writeTextBlocks(); |
| 1945 | | 2004 | // try self.writeStubHelperCommon(); |
| 1946 | if (self.common_section_index) |index| { | 2005 | |
| 1947 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2006 | // if (self.common_section_index) |index| { |
| 1948 | const sect = &seg.sections.items[index]; | 2007 | // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1949 | sect.offset = 0; | 2008 | // const sect = &seg.sections.items[index]; |
| 1950 | } | 2009 | // sect.offset = 0; |
| 1951 | | 2010 | // } |
| 1952 | if (self.bss_section_index) |index| { | 2011 | |
| 1953 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2012 | // if (self.bss_section_index) |index| { |
| 1954 | const sect = &seg.sections.items[index]; | 2013 | // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1955 | sect.offset = 0; | 2014 | // const sect = &seg.sections.items[index]; |
| 1956 | } | 2015 | // sect.offset = 0; |
| 1957 | | 2016 | // } |
| 1958 | if (self.tlv_bss_section_index) |index| { | 2017 | |
| 1959 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2018 | // if (self.tlv_bss_section_index) |index| { |
| 1960 | const sect = &seg.sections.items[index]; | 2019 | // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1961 | sect.offset = 0; | 2020 | // const sect = &seg.sections.items[index]; |
| 1962 | } | 2021 | // sect.offset = 0; |
| 1963 | | 2022 | // } |
| 1964 | if (self.tlv_section_index) |index| { | 2023 | |
| 1965 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2024 | // if (self.tlv_section_index) |index| { |
| 1966 | const sect = &seg.sections.items[index]; | 2025 | // const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1967 | | 2026 | // const sect = &seg.sections.items[index]; |
| 1968 | var buffer = try self.allocator.alloc(u8, @intCast(usize, sect.size)); | 2027 | |
| 1969 | defer self.allocator.free(buffer); | 2028 | // var buffer = try self.allocator.alloc(u8, @intCast(usize, sect.size)); |
| 1970 | _ = try self.file.?.preadAll(buffer, sect.offset); | 2029 | // defer self.allocator.free(buffer); |
| 1971 | | 2030 | // _ = try self.file.?.preadAll(buffer, sect.offset); |
| 1972 | var stream = std.io.fixedBufferStream(buffer); | 2031 | |
| 1973 | var writer = stream.writer(); | 2032 | // var stream = std.io.fixedBufferStream(buffer); |
| 1974 | | 2033 | // var writer = stream.writer(); |
| 1975 | std.sort.sort(TlvOffset, self.threadlocal_offsets.items, {}, TlvOffset.cmp); | 2034 | |
| 1976 | | 2035 | // std.sort.sort(TlvOffset, self.threadlocal_offsets.items, {}, TlvOffset.cmp); |
| 1977 | const seek_amt = 2 * @sizeOf(u64); | 2036 | |
| 1978 | for (self.threadlocal_offsets.items) |tlv| { | 2037 | // const seek_amt = 2 * @sizeOf(u64); |
| 1979 | try writer.context.seekBy(seek_amt); | 2038 | // for (self.threadlocal_offsets.items) |tlv| { |
| 1980 | try writer.writeIntLittle(u64, tlv.offset); | 2039 | // try writer.context.seekBy(seek_amt); |
| 1981 | } | 2040 | // try writer.writeIntLittle(u64, tlv.offset); |
| 1982 | | 2041 | // } |
| 1983 | try self.file.?.pwriteAll(buffer, sect.offset); | 2042 | |
| 1984 | } | 2043 | // try self.file.?.pwriteAll(buffer, sect.offset); |
| 1985 | | 2044 | // } |
| 1986 | if (self.mod_init_func_section_index) |index| { | 2045 | |
| 1987 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2046 | // if (self.mod_init_func_section_index) |index| { |
| 1988 | const sect = &seg.sections.items[index]; | 2047 | // const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1989 | | 2048 | // const sect = &seg.sections.items[index]; |
| 1990 | var initializers = std.ArrayList(u64).init(self.allocator); | 2049 | |
| 1991 | defer initializers.deinit(); | 2050 | // var initializers = std.ArrayList(u64).init(self.allocator); |
| 1992 | | 2051 | // defer initializers.deinit(); |
| 1993 | for (self.objects.items) |object| { | 2052 | |
| 1994 | for (object.initializers.items) |sym_id| { | 2053 | // for (self.objects.items) |object| { |
| 1995 | const address = object.symbols.items[sym_id].payload.regular.address; | 2054 | // for (object.initializers.items) |sym_id| { |
| 1996 | try initializers.append(address); | 2055 | // const address = object.symbols.items[sym_id].payload.regular.address; |
| 1997 | } | 2056 | // try initializers.append(address); |
| 1998 | } | 2057 | // } |
| 1999 | | 2058 | // } |
| 2000 | _ = try self.file.?.pwriteAll(mem.sliceAsBytes(initializers.items), sect.offset); | 2059 | |
| 2001 | sect.size = @intCast(u32, initializers.items.len * @sizeOf(u64)); | 2060 | // _ = try self.file.?.pwriteAll(mem.sliceAsBytes(initializers.items), sect.offset); |
| 2002 | } | 2061 | // sect.size = @intCast(u32, initializers.items.len * @sizeOf(u64)); |
| 2003 | | 2062 | // } |
| 2004 | try self.writeGotEntries(); | 2063 | |
| 2005 | try self.setEntryPoint(); | 2064 | // try self.writeGotEntries(); |
| 2006 | try self.writeRebaseInfoTable(); | 2065 | // try self.setEntryPoint(); |
| 2007 | try self.writeBindInfoTable(); | 2066 | // try self.writeRebaseInfoTable(); |
| 2008 | try self.writeLazyBindInfoTable(); | 2067 | // try self.writeBindInfoTable(); |
| 2009 | try self.writeExportInfo(); | 2068 | // try self.writeLazyBindInfoTable(); |
| 2010 | try self.writeDataInCode(); | 2069 | // try self.writeExportInfo(); |
| 2011 | | 2070 | // try self.writeDataInCode(); |
| 2012 | { | 2071 | |
| 2013 | const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | 2072 | // { |
| 2014 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 2073 | // const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2015 | symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); | 2074 | // const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 2016 | } | 2075 | // symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); |
| 2017 | | 2076 | // } |
| 2018 | try self.writeSymbolTable(); | 2077 | |
| 2019 | try self.writeStringTable(); | 2078 | // try self.writeSymbolTable(); |
| 2020 | | 2079 | // try self.writeStringTable(); |
| 2021 | { | 2080 | |
| 2022 | // Seal __LINKEDIT size | 2081 | // { |
| 2023 | const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | 2082 | // // Seal __LINKEDIT size |
| 2024 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); | 2083 | // const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2025 | } | 2084 | // seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2026 | | 2085 | // } |
| 2027 | if (self.target.?.cpu.arch == .aarch64) { | 2086 | |
| 2028 | try self.writeCodeSignaturePadding(); | 2087 | // if (self.target.?.cpu.arch == .aarch64) { |
| 2029 | } | 2088 | // try self.writeCodeSignaturePadding(); |
| 2030 | | 2089 | // } |
| 2031 | try self.writeLoadCommands(); | 2090 | |
| 2032 | try self.writeHeader(); | 2091 | // try self.writeLoadCommands(); |
| 2033 | | 2092 | // try self.writeHeader(); |
| 2034 | if (self.target.?.cpu.arch == .aarch64) { | 2093 | |
| 2035 | try self.writeCodeSignature(); | 2094 | // if (self.target.?.cpu.arch == .aarch64) { |
| 2036 | } | 2095 | // try self.writeCodeSignature(); |
| 2037 | | 2096 | // } |
| 2038 | if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) { | 2097 | |
| 2039 | const out_path = self.output.?.path; | 2098 | // if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) { |
| 2040 | try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{}); | 2099 | // const out_path = self.output.?.path; |
| 2041 | } | 2100 | // try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{}); |
| | 2101 | // } |
| 2042 | } | 2102 | } |
| 2043 | | 2103 | |
| 2044 | fn writeGotEntries(self: *Zld) !void { | 2104 | fn writeGotEntries(self: *Zld) !void { |