authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-08 19:22:46+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:47+02:00
log0cc4938419c52681d7f7d5a48054e3f8aa827840
tree1e4ad2106aa974b73f1097d0d2bc29431ae50435
parent12187586d15b6eae0330a652a6b1532d2b457991

zld: re-enable all of linker after complete rewrite


2 files changed, 144 insertions(+), 125 deletions(-)

src/link/MachO/Symbol.zig+2-2
......@@ -225,7 +225,7 @@ pub fn needsTlvOffset(self: Symbol, zld: *Zld) bool {
225225 return sect_type == macho.S_THREAD_LOCAL_VARIABLES;
226226}
227227
228pub fn asNlist(symbol: *Symbol, strtab: *StringTable) !macho.nlist_64 {
228pub fn asNlist(symbol: *Symbol, zld: *Zld, strtab: *StringTable) !macho.nlist_64 {
229229 const n_strx = try strtab.getOrPut(symbol.name);
230230 const nlist = nlist: {
231231 switch (symbol.payload) {
......@@ -233,7 +233,7 @@ pub fn asNlist(symbol: *Symbol, strtab: *StringTable) !macho.nlist_64 {
233233 var nlist = macho.nlist_64{
234234 .n_strx = n_strx,
235235 .n_type = macho.N_SECT,
236 .n_sect = regular.section,
236 .n_sect = regular.sectionId(zld),
237237 .n_desc = 0,
238238 .n_value = regular.address,
239239 };
src/link/MachO/Zld.zig+142-123
......@@ -337,6 +337,7 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
337337 log.warn(" {}", .{sect});
338338 entry.value_ptr.*.print(self);
339339 }
340
340341 try self.flush();
341342}
342343
......@@ -1109,23 +1110,31 @@ fn writeTextBlocks(self: *Zld) !void {
11091110
11101111 const seg = self.load_commands.items[match.seg].Segment;
11111112 const sect = seg.sections.items[match.sect];
1113 const sect_type = sectionType(sect);
11121114
11131115 log.warn("writing text blocks for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
11141116
11151117 var code = try self.allocator.alloc(u8, sect.size);
11161118 defer self.allocator.free(code);
11171119
1118 var base_off: u64 = sect.size;
1120 if (sect_type == macho.S_ZEROFILL or
1121 sect_type == macho.S_THREAD_LOCAL_ZEROFILL or
1122 sect_type == macho.S_THREAD_LOCAL_VARIABLES)
1123 {
1124 mem.set(u8, code, 0);
1125 } else {
1126 var base_off: u64 = sect.size;
11191127
1120 while (true) {
1121 base_off -= block.size;
1128 while (true) {
1129 base_off -= block.size;
11221130
1123 try block.resolveRelocs(self);
1124 mem.copy(u8, code[base_off..][0..block.size], block.code);
1131 try block.resolveRelocs(self);
1132 mem.copy(u8, code[base_off..][0..block.size], block.code);
11251133
1126 if (block.prev) |prev| {
1127 block = prev;
1128 } else break;
1134 if (block.prev) |prev| {
1135 block = prev;
1136 } else break;
1137 }
11291138 }
11301139
11311140 try self.file.?.pwriteAll(code, sect.offset);
......@@ -2001,104 +2010,100 @@ fn addRpaths(self: *Zld, rpaths: []const []const u8) !void {
20012010
20022011fn flush(self: *Zld) !void {
20032012 try self.writeTextBlocks();
2004 // try self.writeStubHelperCommon();
2005
2006 // if (self.common_section_index) |index| {
2007 // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2008 // const sect = &seg.sections.items[index];
2009 // sect.offset = 0;
2010 // }
2011
2012 // if (self.bss_section_index) |index| {
2013 // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2014 // const sect = &seg.sections.items[index];
2015 // sect.offset = 0;
2016 // }
2017
2018 // if (self.tlv_bss_section_index) |index| {
2019 // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2020 // const sect = &seg.sections.items[index];
2021 // sect.offset = 0;
2022 // }
2023
2024 // if (self.tlv_section_index) |index| {
2025 // const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2026 // const sect = &seg.sections.items[index];
2027
2028 // var buffer = try self.allocator.alloc(u8, @intCast(usize, sect.size));
2029 // defer self.allocator.free(buffer);
2030 // _ = try self.file.?.preadAll(buffer, sect.offset);
2031
2032 // var stream = std.io.fixedBufferStream(buffer);
2033 // var writer = stream.writer();
2034
2035 // std.sort.sort(TlvOffset, self.threadlocal_offsets.items, {}, TlvOffset.cmp);
2036
2037 // const seek_amt = 2 * @sizeOf(u64);
2038 // for (self.threadlocal_offsets.items) |tlv| {
2039 // try writer.context.seekBy(seek_amt);
2040 // try writer.writeIntLittle(u64, tlv.offset);
2041 // }
2042
2043 // try self.file.?.pwriteAll(buffer, sect.offset);
2044 // }
2045
2046 // if (self.mod_init_func_section_index) |index| {
2047 // const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2048 // const sect = &seg.sections.items[index];
2049
2050 // var initializers = std.ArrayList(u64).init(self.allocator);
2051 // defer initializers.deinit();
2052
2053 // for (self.objects.items) |object| {
2054 // for (object.initializers.items) |sym_id| {
2055 // const address = object.symbols.items[sym_id].payload.regular.address;
2056 // try initializers.append(address);
2057 // }
2058 // }
2059
2060 // _ = try self.file.?.pwriteAll(mem.sliceAsBytes(initializers.items), sect.offset);
2061 // sect.size = @intCast(u32, initializers.items.len * @sizeOf(u64));
2062 // }
2063
2064 // try self.writeGotEntries();
2065 // try self.setEntryPoint();
2066 // try self.writeRebaseInfoTable();
2067 // try self.writeBindInfoTable();
2068 // try self.writeLazyBindInfoTable();
2069 // try self.writeExportInfo();
2013 try self.writeStubHelperCommon();
2014
2015 if (self.common_section_index) |index| {
2016 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2017 const sect = &seg.sections.items[index];
2018 sect.offset = 0;
2019 }
2020
2021 if (self.bss_section_index) |index| {
2022 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2023 const sect = &seg.sections.items[index];
2024 sect.offset = 0;
2025 }
2026
2027 if (self.tlv_bss_section_index) |index| {
2028 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2029 const sect = &seg.sections.items[index];
2030 sect.offset = 0;
2031 }
2032
2033 if (self.tlv_section_index) |index| {
2034 // TODO this should be part of relocation resolution routine.
2035 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2036 const sect = &seg.sections.items[index];
2037
2038 const base_addr = if (self.tlv_data_section_index) |i|
2039 seg.sections.items[i].addr
2040 else
2041 seg.sections.items[self.tlv_bss_section_index.?].addr;
2042
2043 var block: *TextBlock = self.blocks.get(.{
2044 .seg = self.data_segment_cmd_index.?,
2045 .sect = index,
2046 }) orelse unreachable;
2047
2048 var buffer = try self.allocator.alloc(u8, @intCast(usize, sect.size));
2049 defer self.allocator.free(buffer);
2050 _ = try self.file.?.preadAll(buffer, sect.offset);
2051
2052 while (true) {
2053 for (block.tlv_offsets.items) |tlv_offset| {
2054 const sym = self.locals.items[tlv_offset.local_sym_index];
2055 assert(sym.payload == .regular);
2056 const offset = sym.payload.regular.address - base_addr;
2057 mem.writeIntLittle(u64, buffer[tlv_offset.offset..][0..@sizeOf(u64)], offset);
2058 }
2059
2060 if (block.prev) |prev| {
2061 block = prev;
2062 } else break;
2063 }
2064
2065 try self.file.?.pwriteAll(buffer, sect.offset);
2066 }
2067
2068 try self.writeGotEntries();
2069 try self.setEntryPoint();
2070 try self.writeRebaseInfoTable();
2071 try self.writeBindInfoTable();
2072 try self.writeLazyBindInfoTable();
2073 try self.writeExportInfo();
2074 // TODO DICE for x86_64
20702075 // try self.writeDataInCode();
20712076
2072 // {
2073 // const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2074 // const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
2075 // symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
2076 // }
2077 {
2078 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2079 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
2080 symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
2081 }
20772082
2078 // try self.writeSymbolTable();
2079 // try self.writeStringTable();
2083 try self.writeSymbolTable();
2084 try self.writeStringTable();
20802085
2081 // {
2082 // // Seal __LINKEDIT size
2083 // const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2084 // seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?);
2085 // }
2086 {
2087 // Seal __LINKEDIT size
2088 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2089 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?);
2090 }
20862091
2087 // if (self.target.?.cpu.arch == .aarch64) {
2088 // try self.writeCodeSignaturePadding();
2089 // }
2092 if (self.target.?.cpu.arch == .aarch64) {
2093 try self.writeCodeSignaturePadding();
2094 }
20902095
2091 // try self.writeLoadCommands();
2092 // try self.writeHeader();
2096 try self.writeLoadCommands();
2097 try self.writeHeader();
20932098
2094 // if (self.target.?.cpu.arch == .aarch64) {
2095 // try self.writeCodeSignature();
2096 // }
2099 if (self.target.?.cpu.arch == .aarch64) {
2100 try self.writeCodeSignature();
2101 }
20972102
2098 // if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) {
2099 // const out_path = self.output.?.path;
2100 // try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{});
2101 // }
2103 if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) {
2104 const out_path = self.output.?.path;
2105 try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{});
2106 }
21022107}
21032108
21042109fn writeGotEntries(self: *Zld) !void {
......@@ -2140,8 +2145,35 @@ fn writeRebaseInfoTable(self: *Zld) !void {
21402145 var pointers = std.ArrayList(Pointer).init(self.allocator);
21412146 defer pointers.deinit();
21422147
2143 try pointers.ensureCapacity(self.local_rebases.items.len);
2144 pointers.appendSliceAssumeCapacity(self.local_rebases.items);
2148 {
2149 var it = self.blocks.iterator();
2150 while (it.next()) |entry| {
2151 const match = entry.key_ptr.*;
2152 var block: *TextBlock = entry.value_ptr.*;
2153
2154 if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
2155
2156 const seg = self.load_commands.items[match.seg].Segment;
2157 const sect = seg.sections.items[match.sect];
2158
2159 while (true) {
2160 const sym = self.locals.items[block.local_sym_index];
2161 assert(sym.payload == .regular);
2162 const base_offset = sym.payload.regular.address - seg.inner.vmaddr;
2163
2164 for (block.rebases.items) |offset| {
2165 try pointers.append(.{
2166 .offset = base_offset + offset,
2167 .segment_id = match.seg,
2168 });
2169 }
2170
2171 if (block.prev) |prev| {
2172 block = prev;
2173 } else break;
2174 }
2175 }
2176 }
21452177
21462178 if (self.got_section_index) |idx| {
21472179 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
......@@ -2159,24 +2191,6 @@ fn writeRebaseInfoTable(self: *Zld) !void {
21592191 }
21602192 }
21612193
2162 if (self.mod_init_func_section_index) |idx| {
2163 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2164 const sect = seg.sections.items[idx];
2165 const base_offset = sect.addr - seg.inner.vmaddr;
2166 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
2167
2168 var index: u64 = 0;
2169 for (self.objects.items) |object| {
2170 for (object.initializers.items) |_| {
2171 try pointers.append(.{
2172 .offset = base_offset + index * @sizeOf(u64),
2173 .segment_id = segment_id,
2174 });
2175 index += 1;
2176 }
2177 }
2178 }
2179
21802194 if (self.la_symbol_ptr_section_index) |idx| {
21812195 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
21822196 const sect = seg.sections.items[idx];
......@@ -2240,10 +2254,15 @@ fn writeBindInfoTable(self: *Zld) !void {
22402254
22412255 const proxy = sym.payload.proxy;
22422256 for (proxy.bind_info.items) |info| {
2243 const seg = self.load_commands.items[info.segment_id].Segment;
2257 const bind_sym = self.locals.items[info.local_sym_index];
2258 assert(bind_sym.payload == .regular);
2259 const reg = bind_sym.payload.regular;
2260 const base_address = self.load_commands.items[reg.segment_id].Segment.inner.vmaddr;
2261 const offset = reg.address + info.offset - base_address;
2262
22442263 try pointers.append(.{
2245 .offset = info.address - seg.inner.vmaddr,
2246 .segment_id = info.segment_id,
2264 .offset = offset,
2265 .segment_id = reg.segment_id,
22472266 .dylib_ordinal = proxy.dylibOrdinal(),
22482267 .name = sym.name,
22492268 });
......@@ -2462,7 +2481,7 @@ fn writeSymbolTable(self: *Zld) !void {
24622481
24632482 for (self.locals.items) |symbol| {
24642483 if (symbol.isTemp()) continue; // TODO when merging codepaths, this should go into freelist
2465 const nlist = try symbol.asNlist(&self.strtab);
2484 const nlist = try symbol.asNlist(self, &self.strtab);
24662485 locals.appendAssumeCapacity(nlist);
24672486 }
24682487
......@@ -2475,7 +2494,7 @@ fn writeSymbolTable(self: *Zld) !void {
24752494 defer undef_dir.deinit();
24762495
24772496 for (self.globals.values()) |sym| {
2478 const nlist = try sym.asNlist(&self.strtab);
2497 const nlist = try sym.asNlist(self, &self.strtab);
24792498 switch (sym.payload) {
24802499 .regular => try exports.append(nlist),
24812500 .proxy => {