authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-08 08:17:38+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-13 10:56:03+02:00
log23bb6fa9f45d99f97e64bea7011702db19718914
tree67e3f6a0a34461cbcd0646429c350f330e10ad88
parentdb44a7803fac38096526e9b8baba60d966d77ab6

zld: flush MachO


3 files changed, 161 insertions(+), 156 deletions(-)

src/link/MachO/Object.zig+1-1
...@@ -183,7 +183,7 @@ pub fn readLoadCommands(self: *Object, reader: anytype) !void {...@@ -183,7 +183,7 @@ pub fn readLoadCommands(self: *Object, reader: anytype) !void {
183 cmd.LinkeditData.dataoff += offset;183 cmd.LinkeditData.dataoff += offset;
184 },184 },
185 else => {185 else => {
186 log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()});186 log.warn("Unknown load command detected: 0x{x}.", .{cmd.cmd()});
187 },187 },
188 }188 }
189 self.load_commands.appendAssumeCapacity(cmd);189 self.load_commands.appendAssumeCapacity(cmd);
src/link/MachO/Zld.zig+144-140
...@@ -283,7 +283,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {...@@ -283,7 +283,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {
283 try self.allocateStubsAndGotEntries();283 try self.allocateStubsAndGotEntries();
284 try self.writeStubHelperCommon();284 try self.writeStubHelperCommon();
285 try self.resolveRelocsAndWriteSections();285 try self.resolveRelocsAndWriteSections();
286 // try self.flush();286 try self.flush();
287}287}
288288
289fn parseInputFiles(self: *Zld, files: []const []const u8) !void {289fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
...@@ -386,7 +386,7 @@ fn mapAndUpdateSections(...@@ -386,7 +386,7 @@ fn mapAndUpdateSections(
386 .target_sect_id = target_sect_id,386 .target_sect_id = target_sect_id,
387 .offset = @intCast(u32, offset),387 .offset = @intCast(u32, offset),
388 });388 });
389 log.debug("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{389 log.warn("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{
390 object.name,390 object.name,
391 parseName(&source_sect.segname),391 parseName(&source_sect.segname),
392 parseName(&source_sect.sectname),392 parseName(&source_sect.sectname),
...@@ -596,7 +596,7 @@ fn updateMetadata(self: *Zld) !void {...@@ -596,7 +596,7 @@ fn updateMetadata(self: *Zld) !void {
596 });596 });
597 },597 },
598 else => {598 else => {
599 log.debug("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname });599 log.warn("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname });
600 },600 },
601 }601 }
602 }602 }
...@@ -620,7 +620,7 @@ fn updateMetadata(self: *Zld) !void {...@@ -620,7 +620,7 @@ fn updateMetadata(self: *Zld) !void {
620620
621 const segname = parseName(&source_sect.segname);621 const segname = parseName(&source_sect.segname);
622 const sectname = parseName(&source_sect.sectname);622 const sectname = parseName(&source_sect.sectname);
623 log.debug("section '{s}/{s}' will be unmapped", .{ segname, sectname });623 log.warn("section '{s}/{s}' will be unmapped", .{ segname, sectname });
624 try self.unhandled_sections.putNoClobber(self.allocator, .{624 try self.unhandled_sections.putNoClobber(self.allocator, .{
625 .object_id = object_id,625 .object_id = object_id,
626 .source_sect_id = source_sect_id,626 .source_sect_id = source_sect_id,
...@@ -964,7 +964,7 @@ fn allocateSymbols(self: *Zld) !void {...@@ -964,7 +964,7 @@ fn allocateSymbols(self: *Zld) !void {
964 const target_addr = target_sect.addr + target_mapping.offset;964 const target_addr = target_sect.addr + target_mapping.offset;
965 const n_value = source_sym.inner.n_value - source_sect.addr + target_addr;965 const n_value = source_sym.inner.n_value - source_sect.addr + target_addr;
966966
967 log.debug("resolving '{s}' symbol at 0x{x}", .{ entry.key, n_value });967 log.warn("resolving '{s}' symbol at 0x{x}", .{ entry.key, n_value });
968968
969 // TODO there might be a more generic way of doing this.969 // TODO there might be a more generic way of doing this.
970 var n_sect: u8 = 0;970 var n_sect: u8 = 0;
...@@ -1172,7 +1172,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void {...@@ -1172,7 +1172,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void {
1172 var buf: [@sizeOf(u64)]u8 = undefined;1172 var buf: [@sizeOf(u64)]u8 = undefined;
1173 mem.writeIntLittle(u64, &buf, end);1173 mem.writeIntLittle(u64, &buf, end);
1174 const off = la_symbol_ptr.offset + index * @sizeOf(u64);1174 const off = la_symbol_ptr.offset + index * @sizeOf(u64);
1175 log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off });1175 log.warn("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off });
1176 try self.file.?.pwriteAll(&buf, off);1176 try self.file.?.pwriteAll(&buf, off);
1177}1177}
11781178
...@@ -1185,7 +1185,7 @@ fn writeStub(self: *Zld, index: u32) !void {...@@ -1185,7 +1185,7 @@ fn writeStub(self: *Zld, index: u32) !void {
1185 const stub_off = stubs.offset + index * stubs.reserved2;1185 const stub_off = stubs.offset + index * stubs.reserved2;
1186 const stub_addr = stubs.addr + index * stubs.reserved2;1186 const stub_addr = stubs.addr + index * stubs.reserved2;
1187 const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64);1187 const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64);
1188 log.debug("writing stub at 0x{x}", .{stub_off});1188 log.warn("writing stub at 0x{x}", .{stub_off});
1189 var code = try self.allocator.alloc(u8, stubs.reserved2);1189 var code = try self.allocator.alloc(u8, stubs.reserved2);
1190 defer self.allocator.free(code);1190 defer self.allocator.free(code);
1191 switch (self.arch.?) {1191 switch (self.arch.?) {
...@@ -1444,7 +1444,7 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1444,7 +1444,7 @@ fn resolveSymbols(self: *Zld) !void {
14441444
1445fn resolveStubsAndGotEntries(self: *Zld) !void {1445fn resolveStubsAndGotEntries(self: *Zld) !void {
1446 for (self.objects.items) |object, object_id| {1446 for (self.objects.items) |object, object_id| {
1447 log.debug("\nresolving stubs and got entries from {s}", .{object.name});1447 log.warn("\nresolving stubs and got entries from {s}", .{object.name});
14481448
1449 for (object.sections.items) |sect| {1449 for (object.sections.items) |sect| {
1450 const relocs = sect.relocs orelse continue;1450 const relocs = sect.relocs orelse continue;
...@@ -1469,7 +1469,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {...@@ -1469,7 +1469,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
1469 .local_index = if (is_import) 0 else reloc.target.symbol,1469 .local_index = if (is_import) 0 else reloc.target.symbol,
1470 });1470 });
14711471
1472 log.debug(" | found GOT entry {s}: {}", .{ sym_name, self.got_entries.get(sym_name) });1472 log.warn(" | found GOT entry {s}: {}", .{ sym_name, self.got_entries.get(sym_name) });
1473 },1473 },
1474 else => {1474 else => {
1475 const sym = object.symtab.items[reloc.target.symbol];1475 const sym = object.symtab.items[reloc.target.symbol];
...@@ -1486,7 +1486,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {...@@ -1486,7 +1486,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
1486 const index = @intCast(u32, self.stubs.items().len);1486 const index = @intCast(u32, self.stubs.items().len);
1487 try self.stubs.putNoClobber(self.allocator, name, index);1487 try self.stubs.putNoClobber(self.allocator, name, index);
14881488
1489 log.debug(" | found stub {s}: {}", .{ sym_name, self.stubs.get(sym_name) });1489 log.warn(" | found stub {s}: {}", .{ sym_name, self.stubs.get(sym_name) });
1490 },1490 },
1491 }1491 }
1492 }1492 }
...@@ -1504,7 +1504,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {...@@ -1504,7 +1504,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
1504 .local_index = 0,1504 .local_index = 0,
1505 });1505 });
15061506
1507 log.debug(" | found GOT entry dyld_stub_binder: {}", .{self.got_entries.get("dyld_stub_binder")});1507 log.warn(" | found GOT entry dyld_stub_binder: {}", .{self.got_entries.get("dyld_stub_binder")});
1508}1508}
15091509
1510fn resolveRelocsAndWriteSections(self: *Zld) !void {1510fn resolveRelocsAndWriteSections(self: *Zld) !void {
...@@ -1520,7 +1520,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1520,7 +1520,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1520 .object_id = @intCast(u16, object_id),1520 .object_id = @intCast(u16, object_id),
1521 .source_sect_id = @intCast(u16, source_sect_id),1521 .source_sect_id = @intCast(u16, source_sect_id),
1522 }) orelse {1522 }) orelse {
1523 log.debug("no mapping for {s},{s}; skipping", .{ segname, sectname });1523 log.warn("no mapping for {s},{s}; skipping", .{ segname, sectname });
1524 continue;1524 continue;
1525 };1525 };
1526 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;1526 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
...@@ -2128,6 +2128,7 @@ fn flush(self: *Zld) !void {...@@ -2128,6 +2128,7 @@ fn flush(self: *Zld) !void {
2128 try self.file.?.pwriteAll(buffer, sect.offset);2128 try self.file.?.pwriteAll(buffer, sect.offset);
2129 }2129 }
21302130
2131 try self.writeGotEntries();
2131 try self.setEntryPoint();2132 try self.setEntryPoint();
2132 try self.writeRebaseInfoTable();2133 try self.writeRebaseInfoTable();
2133 try self.writeBindInfoTable();2134 try self.writeBindInfoTable();
...@@ -2143,7 +2144,8 @@ fn flush(self: *Zld) !void {...@@ -2143,7 +2144,8 @@ fn flush(self: *Zld) !void {
2143 symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);2144 symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
2144 }2145 }
21452146
2146 try self.writeDebugInfo();2147 // try self.writeDebugInfo();
2148 try self.populateStringTable();
2147 try self.writeSymbolTable();2149 try self.writeSymbolTable();
2148 try self.writeDynamicSymbolTable();2150 try self.writeDynamicSymbolTable();
2149 try self.writeStringTable();2151 try self.writeStringTable();
...@@ -2170,60 +2172,52 @@ fn flush(self: *Zld) !void {...@@ -2170,60 +2172,52 @@ fn flush(self: *Zld) !void {
2170 }2172 }
2171}2173}
21722174
2175fn writeGotEntries(self: *Zld) !void {
2176 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2177 const sect = seg.sections.items[self.got_section_index.?];
2178
2179 var buffer = try self.allocator.alloc(u8, self.got_entries.items().len * @sizeOf(u64));
2180 defer self.allocator.free(buffer);
2181
2182 var stream = std.io.fixedBufferStream(buffer);
2183 var writer = stream.writer();
2184
2185 for (self.got_entries.items()) |entry| {
2186 try writer.writeIntLittle(u64, entry.value.target_addr);
2187 }
2188
2189 log.warn("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len });
2190
2191 try self.file.?.pwriteAll(buffer, sect.offset);
2192}
2193
2173fn setEntryPoint(self: *Zld) !void {2194fn setEntryPoint(self: *Zld) !void {
2174 // TODO we should respect the -entry flag passed in by the user to set a custom2195 // TODO we should respect the -entry flag passed in by the user to set a custom
2175 // entrypoint. For now, assume default of `_main`.2196 // entrypoint. For now, assume default of `_main`.
2176 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;2197 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2177 const text = seg.sections.items[self.text_section_index.?];2198 const text = seg.sections.items[self.text_section_index.?];
2178 const entry_syms = self.locals.get("_main") orelse return error.MissingMainEntrypoint;2199 const entry_sym = self.symtab.get("_main") orelse return error.MissingMainEntrypoint;
2179
2180 var entry_sym: ?macho.nlist_64 = null;
2181 for (entry_syms.items) |es| {
2182 switch (es.tt) {
2183 .Global => {
2184 entry_sym = es.inner;
2185 break;
2186 },
2187 .WeakGlobal => {
2188 entry_sym = es.inner;
2189 },
2190 .Local => {},
2191 }
2192 }
2193 if (entry_sym == null) {
2194 log.err("no (weak) global definition of _main found", .{});
2195 return error.MissingMainEntrypoint;
2196 }
2197
2198 const name = try self.allocator.dupe(u8, "_main");
2199 try self.exports.putNoClobber(self.allocator, name, .{
2200 .n_strx = entry_sym.?.n_strx,
2201 .n_value = entry_sym.?.n_value,
2202 .n_type = macho.N_SECT | macho.N_EXT,
2203 .n_desc = entry_sym.?.n_desc,
2204 .n_sect = entry_sym.?.n_sect,
2205 });
2206
2207 const ec = &self.load_commands.items[self.main_cmd_index.?].Main;2200 const ec = &self.load_commands.items[self.main_cmd_index.?].Main;
2208 ec.entryoff = @intCast(u32, entry_sym.?.n_value - seg.inner.vmaddr);2201 ec.entryoff = @intCast(u32, entry_sym.inner.n_value - seg.inner.vmaddr);
2209}2202}
22102203
2211fn writeRebaseInfoTable(self: *Zld) !void {2204fn writeRebaseInfoTable(self: *Zld) !void {
2212 var pointers = std.ArrayList(Pointer).init(self.allocator);2205 var pointers = std.ArrayList(Pointer).init(self.allocator);
2213 defer pointers.deinit();2206 defer pointers.deinit();
22142207
2215 try pointers.ensureCapacity(pointers.items.len + self.local_rebases.items.len);2208 try pointers.ensureCapacity(self.local_rebases.items.len);
2216 pointers.appendSliceAssumeCapacity(self.local_rebases.items);2209 pointers.appendSliceAssumeCapacity(self.local_rebases.items);
22172210
2218 if (self.got_section_index) |idx| {2211 if (self.got_section_index) |idx| {
2219 // TODO this should be cleaned up!2212 // TODO this should be cleaned up!
2220 try pointers.ensureCapacity(pointers.items.len + self.nonlazy_pointers.items().len);
2221 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2213 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2222 const sect = seg.sections.items[idx];2214 const sect = seg.sections.items[idx];
2223 const base_offset = sect.addr - seg.inner.vmaddr;2215 const base_offset = sect.addr - seg.inner.vmaddr;
2224 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);2216 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
2225 const index_offset = @intCast(u32, self.nonlazy_imports.items().len);2217 const index_offset = @intCast(u32, self.got_entries.items().len);
2226 for (self.nonlazy_pointers.items()) |entry| {2218
2219 try pointers.ensureCapacity(pointers.items.len + self.got_entries.items().len);
2220 for (self.got_entries.items()) |entry| {
2227 const index = index_offset + entry.value.index;2221 const index = index_offset + entry.value.index;
2228 pointers.appendAssumeCapacity(.{2222 pointers.appendAssumeCapacity(.{
2229 .offset = base_offset + index * @sizeOf(u64),2223 .offset = base_offset + index * @sizeOf(u64),
...@@ -2269,14 +2263,15 @@ fn writeRebaseInfoTable(self: *Zld) !void {...@@ -2269,14 +2263,15 @@ fn writeRebaseInfoTable(self: *Zld) !void {
2269 }2263 }
22702264
2271 if (self.la_symbol_ptr_section_index) |idx| {2265 if (self.la_symbol_ptr_section_index) |idx| {
2272 try pointers.ensureCapacity(pointers.items.len + self.lazy_imports.items().len);
2273 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;2266 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2274 const sect = seg.sections.items[idx];2267 const sect = seg.sections.items[idx];
2275 const base_offset = sect.addr - seg.inner.vmaddr;2268 const base_offset = sect.addr - seg.inner.vmaddr;
2276 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);2269 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);
2277 for (self.lazy_imports.items()) |entry| {2270
2271 try pointers.ensureCapacity(pointers.items.len + self.stubs.items().len);
2272 for (self.stubs.items()) |entry| {
2278 pointers.appendAssumeCapacity(.{2273 pointers.appendAssumeCapacity(.{
2279 .offset = base_offset + entry.value.index * @sizeOf(u64),2274 .offset = base_offset + entry.value * @sizeOf(u64),
2280 .segment_id = segment_id,2275 .segment_id = segment_id,
2281 });2276 });
2282 }2277 }
...@@ -2297,7 +2292,7 @@ fn writeRebaseInfoTable(self: *Zld) !void {...@@ -2297,7 +2292,7 @@ fn writeRebaseInfoTable(self: *Zld) !void {
2297 dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64)));2292 dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64)));
2298 seg.inner.filesize += dyld_info.rebase_size;2293 seg.inner.filesize += dyld_info.rebase_size;
22992294
2300 log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size });2295 log.warn("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size });
23012296
2302 try self.file.?.pwriteAll(buffer, dyld_info.rebase_off);2297 try self.file.?.pwriteAll(buffer, dyld_info.rebase_off);
2303}2298}
...@@ -2307,16 +2302,23 @@ fn writeBindInfoTable(self: *Zld) !void {...@@ -2307,16 +2302,23 @@ fn writeBindInfoTable(self: *Zld) !void {
2307 defer pointers.deinit();2302 defer pointers.deinit();
23082303
2309 if (self.got_section_index) |idx| {2304 if (self.got_section_index) |idx| {
2310 try pointers.ensureCapacity(pointers.items.len + self.nonlazy_imports.items().len);
2311 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2305 const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2312 const sect = seg.sections.items[idx];2306 const sect = seg.sections.items[idx];
2313 const base_offset = sect.addr - seg.inner.vmaddr;2307 const base_offset = sect.addr - seg.inner.vmaddr;
2314 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);2308 const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
2315 for (self.nonlazy_imports.items()) |entry| {2309
2310 try pointers.ensureCapacity(pointers.items.len + self.got_entries.items().len);
2311 for (self.got_entries.items()) |entry| {
2312 const dylib_ordinal = dylib_ordinal: {
2313 const sym = self.symtab.get(entry.key) orelse continue; // local indirection
2314 if (sym.tag != .Import) continue; // local indirection
2315 break :dylib_ordinal sym.file.? + 1;
2316 };
2317
2316 pointers.appendAssumeCapacity(.{2318 pointers.appendAssumeCapacity(.{
2317 .offset = base_offset + entry.value.index * @sizeOf(u64),2319 .offset = base_offset + entry.value.index * @sizeOf(u64),
2318 .segment_id = segment_id,2320 .segment_id = segment_id,
2319 .dylib_ordinal = entry.value.dylib_ordinal,2321 .dylib_ordinal = dylib_ordinal,
2320 .name = entry.key,2322 .name = entry.key,
2321 });2323 });
2322 }2324 }
...@@ -2327,10 +2329,14 @@ fn writeBindInfoTable(self: *Zld) !void {...@@ -2327,10 +2329,14 @@ fn writeBindInfoTable(self: *Zld) !void {
2327 const sect = seg.sections.items[idx];2329 const sect = seg.sections.items[idx];
2328 const base_offset = sect.addr - seg.inner.vmaddr;2330 const base_offset = sect.addr - seg.inner.vmaddr;
2329 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);2331 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);
2332
2333 const sym = self.symtab.get("__tlv_bootstrap") orelse unreachable;
2334 const dylib_ordinal = sym.file.? + 1;
2335
2330 try pointers.append(.{2336 try pointers.append(.{
2331 .offset = base_offset + self.tlv_bootstrap.?.index * @sizeOf(u64),2337 .offset = base_offset,
2332 .segment_id = segment_id,2338 .segment_id = segment_id,
2333 .dylib_ordinal = self.tlv_bootstrap.?.dylib_ordinal,2339 .dylib_ordinal = dylib_ordinal,
2334 .name = "__tlv_bootstrap",2340 .name = "__tlv_bootstrap",
2335 });2341 });
2336 }2342 }
...@@ -2348,7 +2354,7 @@ fn writeBindInfoTable(self: *Zld) !void {...@@ -2348,7 +2354,7 @@ fn writeBindInfoTable(self: *Zld) !void {
2348 dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));2354 dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));
2349 seg.inner.filesize += dyld_info.bind_size;2355 seg.inner.filesize += dyld_info.bind_size;
23502356
2351 log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size });2357 log.warn("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size });
23522358
2353 try self.file.?.pwriteAll(buffer, dyld_info.bind_off);2359 try self.file.?.pwriteAll(buffer, dyld_info.bind_off);
2354}2360}
...@@ -2356,18 +2362,26 @@ fn writeBindInfoTable(self: *Zld) !void {...@@ -2356,18 +2362,26 @@ fn writeBindInfoTable(self: *Zld) !void {
2356fn writeLazyBindInfoTable(self: *Zld) !void {2362fn writeLazyBindInfoTable(self: *Zld) !void {
2357 var pointers = std.ArrayList(Pointer).init(self.allocator);2363 var pointers = std.ArrayList(Pointer).init(self.allocator);
2358 defer pointers.deinit();2364 defer pointers.deinit();
2359 try pointers.ensureCapacity(self.lazy_imports.items().len);
23602365
2361 if (self.la_symbol_ptr_section_index) |idx| {2366 if (self.la_symbol_ptr_section_index) |idx| {
2362 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;2367 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2363 const sect = seg.sections.items[idx];2368 const sect = seg.sections.items[idx];
2364 const base_offset = sect.addr - seg.inner.vmaddr;2369 const base_offset = sect.addr - seg.inner.vmaddr;
2365 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);2370 const segment_id = @intCast(u16, self.data_segment_cmd_index.?);
2366 for (self.lazy_imports.items()) |entry| {2371
2372 try pointers.ensureCapacity(self.stubs.items().len);
2373
2374 for (self.stubs.items()) |entry| {
2375 const dylib_ordinal = dylib_ordinal: {
2376 const sym = self.symtab.get(entry.key) orelse unreachable;
2377 assert(sym.tag == .Import);
2378 break :dylib_ordinal sym.file.? + 1;
2379 };
2380
2367 pointers.appendAssumeCapacity(.{2381 pointers.appendAssumeCapacity(.{
2368 .offset = base_offset + entry.value.index * @sizeOf(u64),2382 .offset = base_offset + entry.value * @sizeOf(u64),
2369 .segment_id = segment_id,2383 .segment_id = segment_id,
2370 .dylib_ordinal = entry.value.dylib_ordinal,2384 .dylib_ordinal = dylib_ordinal,
2371 .name = entry.key,2385 .name = entry.key,
2372 });2386 });
2373 }2387 }
...@@ -2386,7 +2400,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void {...@@ -2386,7 +2400,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void {
2386 dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));2400 dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));
2387 seg.inner.filesize += dyld_info.lazy_bind_size;2401 seg.inner.filesize += dyld_info.lazy_bind_size;
23882402
2389 log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size });2403 log.warn("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size });
23902404
2391 try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off);2405 try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off);
2392 try self.populateLazyBindOffsetsInStubHelper(buffer);2406 try self.populateLazyBindOffsetsInStubHelper(buffer);
...@@ -2437,7 +2451,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void {...@@ -2437,7 +2451,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void {
2437 else => {},2451 else => {},
2438 }2452 }
2439 }2453 }
2440 assert(self.lazy_imports.items().len <= offsets.items.len);2454 assert(self.stubs.items().len <= offsets.items.len);
24412455
2442 const stub_size: u4 = switch (self.arch.?) {2456 const stub_size: u4 = switch (self.arch.?) {
2443 .x86_64 => 10,2457 .x86_64 => 10,
...@@ -2450,10 +2464,9 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void {...@@ -2450,10 +2464,9 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void {
2450 else => unreachable,2464 else => unreachable,
2451 };2465 };
2452 var buf: [@sizeOf(u32)]u8 = undefined;2466 var buf: [@sizeOf(u32)]u8 = undefined;
2453 for (self.lazy_imports.items()) |entry| {2467 for (self.stubs.items()) |entry| {
2454 const symbol = entry.value;2468 const placeholder_off = self.stub_helper_stubs_start_off.? + entry.value * stub_size + off;
2455 const placeholder_off = self.stub_helper_stubs_start_off.? + symbol.index * stub_size + off;2469 mem.writeIntLittle(u32, &buf, offsets.items[entry.value]);
2456 mem.writeIntLittle(u32, &buf, offsets.items[symbol.index]);
2457 try self.file.?.pwriteAll(&buf, placeholder_off);2470 try self.file.?.pwriteAll(&buf, placeholder_off);
2458 }2471 }
2459}2472}
...@@ -2463,11 +2476,16 @@ fn writeExportInfo(self: *Zld) !void {...@@ -2463,11 +2476,16 @@ fn writeExportInfo(self: *Zld) !void {
2463 defer trie.deinit();2476 defer trie.deinit();
24642477
2465 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;2478 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2466 for (self.exports.items()) |entry| {2479 for (self.symtab.items()) |entry| {
2480 switch (entry.value.tag) {
2481 .Weak, .Strong => {},
2482 else => continue,
2483 }
2467 const name = entry.key;2484 const name = entry.key;
2468 const symbol = entry.value;2485 const symbol = entry.value.inner;
2469 // TODO figure out if we should put all exports into the export trie2486
2470 assert(symbol.n_value >= text_segment.inner.vmaddr);2487 assert(symbol.n_value >= text_segment.inner.vmaddr);
2488
2471 try trie.put(.{2489 try trie.put(.{
2472 .name = name,2490 .name = name,
2473 .vmaddr_offset = symbol.n_value - text_segment.inner.vmaddr,2491 .vmaddr_offset = symbol.n_value - text_segment.inner.vmaddr,
...@@ -2488,7 +2506,7 @@ fn writeExportInfo(self: *Zld) !void {...@@ -2488,7 +2506,7 @@ fn writeExportInfo(self: *Zld) !void {
2488 dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));2506 dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)));
2489 seg.inner.filesize += dyld_info.export_size;2507 seg.inner.filesize += dyld_info.export_size;
24902508
2491 log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size });2509 log.warn("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size });
24922510
2493 try self.file.?.pwriteAll(buffer, dyld_info.export_off);2511 try self.file.?.pwriteAll(buffer, dyld_info.export_off);
2494}2512}
...@@ -2508,7 +2526,7 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2508,7 +2526,7 @@ fn writeDebugInfo(self: *Zld) !void {
2508 const compile_unit = debug_info.inner.findCompileUnit(0x0) catch |err| switch (err) {2526 const compile_unit = debug_info.inner.findCompileUnit(0x0) catch |err| switch (err) {
2509 error.MissingDebugInfo => {2527 error.MissingDebugInfo => {
2510 // TODO audit cases with missing debug info and audit our dwarf.zig module.2528 // TODO audit cases with missing debug info and audit our dwarf.zig module.
2511 log.debug("invalid or missing debug info in {s}; skipping", .{object.name});2529 log.warn("invalid or missing debug info in {s}; skipping", .{object.name});
2512 continue;2530 continue;
2513 },2531 },
2514 else => |e| return e,2532 else => |e| return e,
...@@ -2558,7 +2576,7 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2558,7 +2576,7 @@ fn writeDebugInfo(self: *Zld) !void {
2558 .n_value = mtime,2576 .n_value = mtime,
2559 });2577 });
2560 }2578 }
2561 log.debug("analyzing debug info in '{s}'", .{object.name});2579 log.warn("analyzing debug info in '{s}'", .{object.name});
25622580
2563 for (object.symtab.items) |source_sym| {2581 for (object.symtab.items) |source_sym| {
2564 const symname = object.getString(source_sym.n_strx);2582 const symname = object.getString(source_sym.n_strx);
...@@ -2639,7 +2657,7 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2639,7 +2657,7 @@ fn writeDebugInfo(self: *Zld) !void {
26392657
2640 const stabs_off = symtab.symoff;2658 const stabs_off = symtab.symoff;
2641 const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64);2659 const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64);
2642 log.debug("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off });2660 log.warn("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off });
2643 try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off);2661 try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off);
26442662
2645 linkedit.inner.filesize += stabs_size;2663 linkedit.inner.filesize += stabs_size;
...@@ -2649,66 +2667,56 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2649,66 +2667,56 @@ fn writeDebugInfo(self: *Zld) !void {
2649 dysymtab.nlocalsym = symtab.nsyms;2667 dysymtab.nlocalsym = symtab.nsyms;
2650}2668}
26512669
2670fn populateStringTable(self: *Zld) !void {
2671 for (self.symtab.items()) |*entry| {
2672 const n_strx = try self.makeString(entry.key);
2673 entry.value.inner.n_strx = n_strx;
2674 }
2675}
2676
2652fn writeSymbolTable(self: *Zld) !void {2677fn writeSymbolTable(self: *Zld) !void {
2653 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;2678 const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
2654 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;2679 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
26552680
2681 // TODO figure out how to add locals
2656 var locals = std.ArrayList(macho.nlist_64).init(self.allocator);2682 var locals = std.ArrayList(macho.nlist_64).init(self.allocator);
2657 defer locals.deinit();2683 defer locals.deinit();
26582684
2659 for (self.locals.items()) |entries| {
2660 log.debug("'{s}': {} entries", .{ entries.key, entries.value.items.len });
2661 // var symbol: ?macho.nlist_64 = null;
2662 for (entries.value.items) |entry| {
2663 log.debug(" | {}", .{entry.inner});
2664 log.debug(" | {}", .{entry.tt});
2665 log.debug(" | {s}", .{self.objects.items[entry.object_id].name});
2666 try locals.append(entry.inner);
2667 }
2668 }
2669 const nlocals = locals.items.len;
2670
2671 const nexports = self.exports.items().len;
2672 var exports = std.ArrayList(macho.nlist_64).init(self.allocator);2685 var exports = std.ArrayList(macho.nlist_64).init(self.allocator);
2673 defer exports.deinit();2686 defer exports.deinit();
26742687
2675 try exports.ensureCapacity(nexports);
2676 for (self.exports.items()) |entry| {
2677 exports.appendAssumeCapacity(entry.value);
2678 }
2679
2680 const has_tlv: bool = self.tlv_bootstrap != null;
2681
2682 var nundefs = self.lazy_imports.items().len + self.nonlazy_imports.items().len;
2683 if (has_tlv) nundefs += 1;
2684
2685 var undefs = std.ArrayList(macho.nlist_64).init(self.allocator);2688 var undefs = std.ArrayList(macho.nlist_64).init(self.allocator);
2686 defer undefs.deinit();2689 defer undefs.deinit();
26872690
2688 try undefs.ensureCapacity(nundefs);2691 for (self.symtab.items()) |entry| {
2689 for (self.lazy_imports.items()) |entry| {2692 switch (entry.value.tag) {
2690 undefs.appendAssumeCapacity(entry.value.symbol);2693 .Weak, .Strong => {
2691 }2694 try exports.append(entry.value.inner);
2692 for (self.nonlazy_imports.items()) |entry| {2695 },
2693 undefs.appendAssumeCapacity(entry.value.symbol);2696 .Import => {
2694 }2697 try undefs.append(entry.value.inner);
2695 if (has_tlv) {2698 },
2696 undefs.appendAssumeCapacity(self.tlv_bootstrap.?.symbol);2699 else => unreachable,
2700 }
2697 }2701 }
26982702
2703 const nlocals = locals.items.len;
2704 const nexports = exports.items.len;
2705 const nundefs = undefs.items.len;
2706
2699 const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64);2707 const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64);
2700 const locals_size = nlocals * @sizeOf(macho.nlist_64);2708 const locals_size = nlocals * @sizeOf(macho.nlist_64);
2701 log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off });2709 log.warn("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off });
2702 try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off);2710 try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off);
27032711
2704 const exports_off = locals_off + locals_size;2712 const exports_off = locals_off + locals_size;
2705 const exports_size = nexports * @sizeOf(macho.nlist_64);2713 const exports_size = nexports * @sizeOf(macho.nlist_64);
2706 log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off });2714 log.warn("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off });
2707 try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off);2715 try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off);
27082716
2709 const undefs_off = exports_off + exports_size;2717 const undefs_off = exports_off + exports_size;
2710 const undefs_size = nundefs * @sizeOf(macho.nlist_64);2718 const undefs_size = nundefs * @sizeOf(macho.nlist_64);
2711 log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });2719 log.warn("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
2712 try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off);2720 try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off);
27132721
2714 symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs);2722 symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs);
...@@ -2733,44 +2741,45 @@ fn writeDynamicSymbolTable(self: *Zld) !void {...@@ -2733,44 +2741,45 @@ fn writeDynamicSymbolTable(self: *Zld) !void {
2733 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];2741 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
2734 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;2742 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
27352743
2736 const lazy = self.lazy_imports.items();2744 const nstubs = @intCast(u32, self.stubs.items().len);
2737 const nonlazy = self.nonlazy_imports.items();2745 const ngot_entries = @intCast(u32, self.got_entries.items().len);
2738 const got_locals = self.nonlazy_pointers.items();2746
2739 dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);2747 dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
2740 dysymtab.nindirectsyms = @intCast(u32, lazy.len * 2 + nonlazy.len + got_locals.len);2748 dysymtab.nindirectsyms = nstubs * 2 + ngot_entries;
2749
2741 const needed_size = dysymtab.nindirectsyms * @sizeOf(u32);2750 const needed_size = dysymtab.nindirectsyms * @sizeOf(u32);
2742 seg.inner.filesize += needed_size;2751 seg.inner.filesize += needed_size;
27432752
2744 log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{2753 log.warn("writing indirect symbol table from 0x{x} to 0x{x}", .{
2745 dysymtab.indirectsymoff,2754 dysymtab.indirectsymoff,
2746 dysymtab.indirectsymoff + needed_size,2755 dysymtab.indirectsymoff + needed_size,
2747 });2756 });
27482757
2749 var buf = try self.allocator.alloc(u8, needed_size);2758 var buf = try self.allocator.alloc(u8, needed_size);
2750 defer self.allocator.free(buf);2759 defer self.allocator.free(buf);
2760
2751 var stream = std.io.fixedBufferStream(buf);2761 var stream = std.io.fixedBufferStream(buf);
2752 var writer = stream.writer();2762 var writer = stream.writer();
27532763
2754 stubs.reserved1 = 0;2764 stubs.reserved1 = 0;
2755 for (lazy) |_, i| {2765 for (self.stubs.items()) |entry| {
2756 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i);2766 const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value);
2757 try writer.writeIntLittle(u32, symtab_idx);2767 try writer.writeIntLittle(u32, symtab_idx);
2758 }2768 }
27592769
2760 const base_id = @intCast(u32, lazy.len);2770 got.reserved1 = nstubs;
2761 got.reserved1 = base_id;2771 for (self.got_entries.items()) |entry| {
2762 for (nonlazy) |_, i| {2772 if (entry.value.tag == .import) {
2763 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i + base_id);2773 const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index + nstubs);
2764 try writer.writeIntLittle(u32, symtab_idx);2774 try writer.writeIntLittle(u32, symtab_idx);
2765 }2775 } else {
2766 // TODO there should be one common set of GOT entries.2776 try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);
2767 for (got_locals) |_| {2777 }
2768 try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);
2769 }2778 }
27702779
2771 la_symbol_ptr.reserved1 = got.reserved1 + @intCast(u32, nonlazy.len) + @intCast(u32, got_locals.len);2780 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;
2772 for (lazy) |_, i| {2781 for (self.stubs.items()) |entry| {
2773 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i);2782 const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value);
2774 try writer.writeIntLittle(u32, symtab_idx);2783 try writer.writeIntLittle(u32, symtab_idx);
2775 }2784 }
27762785
...@@ -2784,7 +2793,7 @@ fn writeStringTable(self: *Zld) !void {...@@ -2784,7 +2793,7 @@ fn writeStringTable(self: *Zld) !void {
2784 symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64)));2793 symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64)));
2785 seg.inner.filesize += symtab.strsize;2794 seg.inner.filesize += symtab.strsize;
27862795
2787 log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize });2796 log.warn("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize });
27882797
2789 try self.file.?.pwriteAll(self.strtab.items, symtab.stroff);2798 try self.file.?.pwriteAll(self.strtab.items, symtab.stroff);
27902799
...@@ -2830,7 +2839,7 @@ fn writeDataInCode(self: *Zld) !void {...@@ -2830,7 +2839,7 @@ fn writeDataInCode(self: *Zld) !void {
2830 dice_cmd.datasize = datasize;2839 dice_cmd.datasize = datasize;
2831 seg.inner.filesize += datasize;2840 seg.inner.filesize += datasize;
28322841
2833 log.debug("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize });2842 log.warn("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize });
28342843
2835 try self.file.?.pwriteAll(buf.items, fileoff);2844 try self.file.?.pwriteAll(buf.items, fileoff);
2836}2845}
...@@ -2851,7 +2860,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void {...@@ -2851,7 +2860,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void {
2851 seg.inner.filesize += needed_size;2860 seg.inner.filesize += needed_size;
2852 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?);2861 seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?);
28532862
2854 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });2863 log.warn("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });
28552864
2856 // Pad out the space. We need to do this to calculate valid hashes for everything in the file2865 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
2857 // except for code signature data.2866 // except for code signature data.
...@@ -2877,7 +2886,7 @@ fn writeCodeSignature(self: *Zld) !void {...@@ -2877,7 +2886,7 @@ fn writeCodeSignature(self: *Zld) !void {
2877 var stream = std.io.fixedBufferStream(buffer);2886 var stream = std.io.fixedBufferStream(buffer);
2878 try code_sig.write(stream.writer());2887 try code_sig.write(stream.writer());
28792888
2880 log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len });2889 log.warn("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len });
2881 try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);2890 try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);
2882}2891}
28832892
...@@ -2895,7 +2904,7 @@ fn writeLoadCommands(self: *Zld) !void {...@@ -2895,7 +2904,7 @@ fn writeLoadCommands(self: *Zld) !void {
2895 }2904 }
28962905
2897 const off = @sizeOf(macho.mach_header_64);2906 const off = @sizeOf(macho.mach_header_64);
2898 log.debug("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds });2907 log.warn("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds });
2899 try self.file.?.pwriteAll(buffer, off);2908 try self.file.?.pwriteAll(buffer, off);
2900}2909}
29012910
...@@ -2933,7 +2942,7 @@ fn writeHeader(self: *Zld) !void {...@@ -2933,7 +2942,7 @@ fn writeHeader(self: *Zld) !void {
2933 for (self.load_commands.items) |cmd| {2942 for (self.load_commands.items) |cmd| {
2934 header.sizeofcmds += cmd.cmdsize();2943 header.sizeofcmds += cmd.cmdsize();
2935 }2944 }
2936 log.debug("writing Mach-O header {}", .{header});2945 log.warn("writing Mach-O header {}", .{header});
2937 try self.file.?.pwriteAll(mem.asBytes(&header), 0);2946 try self.file.?.pwriteAll(mem.asBytes(&header), 0);
2938}2947}
29392948
...@@ -2947,7 +2956,7 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 {...@@ -2947,7 +2956,7 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 {
2947fn makeString(self: *Zld, bytes: []const u8) !u32 {2956fn makeString(self: *Zld, bytes: []const u8) !u32 {
2948 try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1);2957 try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1);
2949 const offset = @intCast(u32, self.strtab.items.len);2958 const offset = @intCast(u32, self.strtab.items.len);
2950 log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset });2959 log.warn("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset });
2951 self.strtab.appendSliceAssumeCapacity(bytes);2960 self.strtab.appendSliceAssumeCapacity(bytes);
2952 self.strtab.appendAssumeCapacity(0);2961 self.strtab.appendAssumeCapacity(0);
2953 return offset;2962 return offset;
...@@ -2963,11 +2972,6 @@ pub fn parseName(name: *const [16]u8) []const u8 {...@@ -2963,11 +2972,6 @@ pub fn parseName(name: *const [16]u8) []const u8 {
2963 return name[0..len];2972 return name[0..len];
2964}2973}
29652974
2966fn aarch64IsArithmetic(inst: *const [4]u8) callconv(.Inline) bool {
2967 const group_decode = @truncate(u5, inst[3]);
2968 return ((group_decode >> 2) == 4);
2969}
2970
2971fn printDebug(self: Zld) void {2975fn printDebug(self: Zld) void {
2972 log.warn("symtab", .{});2976 log.warn("symtab", .{});
2973 for (self.symtab.items()) |entry| {2977 for (self.symtab.items()) |entry| {
src/link/MachO/reloc.zig+16-15
...@@ -33,7 +33,8 @@ pub const Relocation = struct {...@@ -33,7 +33,8 @@ pub const Relocation = struct {
33 log.warn(" | offset 0x{x}", .{base.offset});33 log.warn(" | offset 0x{x}", .{base.offset});
34 log.warn(" | source address 0x{x}", .{args.source_addr});34 log.warn(" | source address 0x{x}", .{args.source_addr});
35 log.warn(" | target address 0x{x}", .{args.target_addr});35 log.warn(" | target address 0x{x}", .{args.target_addr});
36 log.warn(" | subtractor address 0x{x}", .{args.subtractor});36 if (args.subtractor) |sub|
37 log.warn(" | subtractor address 0x{x}", .{sub});
3738
38 return switch (base.@"type") {39 return switch (base.@"type") {
39 .branch => @fieldParentPtr(Branch, "base", base).resolve(args.source_addr, args.target_addr),40 .branch => @fieldParentPtr(Branch, "base", base).resolve(args.source_addr, args.target_addr),
...@@ -307,12 +308,12 @@ const RelocIterator = struct {...@@ -307,12 +308,12 @@ const RelocIterator = struct {
307 self.index += 1;308 self.index += 1;
308 if (self.index < self.buffer.len) {309 if (self.index < self.buffer.len) {
309 const reloc = self.buffer[@intCast(u64, self.index)];310 const reloc = self.buffer[@intCast(u64, self.index)];
310 log.warn("{s}", .{@intToEnum(macho.reloc_type_arm64, reloc.r_type)});311 log.debug("{s}", .{@intToEnum(macho.reloc_type_arm64, reloc.r_type)});
311 log.warn(" | offset = {}", .{reloc.r_address});312 log.debug(" | offset = {}", .{reloc.r_address});
312 log.warn(" | PC = {}", .{reloc.r_pcrel == 1});313 log.debug(" | PC = {}", .{reloc.r_pcrel == 1});
313 log.warn(" | length = {}", .{reloc.r_length});314 log.debug(" | length = {}", .{reloc.r_length});
314 log.warn(" | symbolnum = {}", .{reloc.r_symbolnum});315 log.debug(" | symbolnum = {}", .{reloc.r_symbolnum});
315 log.warn(" | extern = {}", .{reloc.r_extern == 1});316 log.debug(" | extern = {}", .{reloc.r_extern == 1});
316 return reloc;317 return reloc;
317 }318 }
318 return null;319 return null;
...@@ -432,7 +433,7 @@ const Parser = struct {...@@ -432,7 +433,7 @@ const Parser = struct {
432 .inst = parsed_inst,433 .inst = parsed_inst,
433 };434 };
434435
435 log.warn(" | emitting {}", .{branch});436 log.debug(" | emitting {}", .{branch});
436 try parser.parsed.append(&branch.base);437 try parser.parsed.append(&branch.base);
437 }438 }
438439
...@@ -471,7 +472,7 @@ const Parser = struct {...@@ -471,7 +472,7 @@ const Parser = struct {
471 .inst = parsed_inst,472 .inst = parsed_inst,
472 };473 };
473474
474 log.warn(" | emitting {}", .{page});475 log.debug(" | emitting {}", .{page});
475476
476 break :ptr &page.base;477 break :ptr &page.base;
477 },478 },
...@@ -489,7 +490,7 @@ const Parser = struct {...@@ -489,7 +490,7 @@ const Parser = struct {
489 .inst = parsed_inst,490 .inst = parsed_inst,
490 };491 };
491492
492 log.warn(" | emitting {}", .{page});493 log.debug(" | emitting {}", .{page});
493494
494 break :ptr &page.base;495 break :ptr &page.base;
495 },496 },
...@@ -507,7 +508,7 @@ const Parser = struct {...@@ -507,7 +508,7 @@ const Parser = struct {
507 .inst = parsed_inst,508 .inst = parsed_inst,
508 };509 };
509510
510 log.warn(" | emitting {}", .{page});511 log.debug(" | emitting {}", .{page});
511512
512 break :ptr &page.base;513 break :ptr &page.base;
513 },514 },
...@@ -564,7 +565,7 @@ const Parser = struct {...@@ -564,7 +565,7 @@ const Parser = struct {
564 .addend = parser.addend,565 .addend = parser.addend,
565 };566 };
566567
567 log.warn(" | emitting {}", .{page_off});568 log.debug(" | emitting {}", .{page_off});
568 try parser.parsed.append(&page_off.base);569 try parser.parsed.append(&page_off.base);
569 }570 }
570571
...@@ -601,7 +602,7 @@ const Parser = struct {...@@ -601,7 +602,7 @@ const Parser = struct {
601 },602 },
602 };603 };
603604
604 log.warn(" | emitting {}", .{page_off});605 log.debug(" | emitting {}", .{page_off});
605 try parser.parsed.append(&page_off.base);606 try parser.parsed.append(&page_off.base);
606 }607 }
607608
...@@ -668,7 +669,7 @@ const Parser = struct {...@@ -668,7 +669,7 @@ const Parser = struct {
668 },669 },
669 };670 };
670671
671 log.warn(" | emitting {}", .{page_off});672 log.debug(" | emitting {}", .{page_off});
672 try parser.parsed.append(&page_off.base);673 try parser.parsed.append(&page_off.base);
673 }674 }
674675
...@@ -729,7 +730,7 @@ const Parser = struct {...@@ -729,7 +730,7 @@ const Parser = struct {
729 .addend = addend,730 .addend = addend,
730 };731 };
731732
732 log.warn(" | emitting {}", .{unsigned});733 log.debug(" | emitting {}", .{unsigned});
733 try parser.parsed.append(&unsigned.base);734 try parser.parsed.append(&unsigned.base);
734 }735 }
735};736};