| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const MachO = @This(); |
| 2 | |
| 2 | 3 | const std = @import("std"); |
| 3 | 4 | const Allocator = std.mem.Allocator; |
| 4 | 5 | const assert = std.debug.assert; |
| ... | ... | @@ -1172,7 +1173,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1172 | 1173 | text_segment.nsects += 1; |
| 1173 | 1174 | |
| 1174 | 1175 | const program_code_size_hint = self.base.options.program_code_size_hint; |
| 1175 | | // const program_code_size_hint = 128; |
| 1176 | 1176 | const file_size = mem.alignForwardGeneric(u64, program_code_size_hint, self.page_size); |
| 1177 | 1177 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); // TODO maybe findFreeSpace should return u32 directly? |
| 1178 | 1178 | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| ... | ... | @@ -1294,22 +1294,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1294 | 1294 | }); |
| 1295 | 1295 | self.cmd_table_dirty = true; |
| 1296 | 1296 | } |
| 1297 | | { |
| 1298 | | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1299 | | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo; |
| 1300 | | if (dyld_info.export_off == 0) { |
| 1301 | | const nsyms = self.base.options.symbol_count_hint; |
| 1302 | | const file_size = @sizeOf(u64) * nsyms; |
| 1303 | | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1304 | | log.debug("found export trie free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1305 | | dyld_info.export_off = off; |
| 1306 | | dyld_info.export_size = @intCast(u32, file_size); |
| 1307 | | |
| 1308 | | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1309 | | linkedit.vmsize += segment_size; |
| 1310 | | linkedit.fileoff = off; |
| 1311 | | } |
| 1312 | | } |
| 1313 | 1297 | if (self.symtab_cmd_index == null) { |
| 1314 | 1298 | self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1315 | 1299 | try self.load_commands.append(self.base.allocator, .{ |
| ... | ... | @@ -1352,35 +1336,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1352 | 1336 | }); |
| 1353 | 1337 | self.cmd_table_dirty = true; |
| 1354 | 1338 | } |
| 1355 | | { |
| 1356 | | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1357 | | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1358 | | if (symtab.symoff == 0) { |
| 1359 | | const nsyms = self.base.options.symbol_count_hint; |
| 1360 | | const file_size = @sizeOf(macho.nlist_64) * nsyms; |
| 1361 | | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1362 | | log.debug("found symbol table free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1363 | | symtab.symoff = off; |
| 1364 | | symtab.nsyms = @intCast(u32, nsyms); |
| 1365 | | |
| 1366 | | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1367 | | linkedit.vmsize += segment_size; |
| 1368 | | // TODO this is needed to please codesign_allocate |
| 1369 | | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo; |
| 1370 | | dyld_info.export_size = off - dyld_info.export_off; |
| 1371 | | } |
| 1372 | | if (symtab.stroff == 0) { |
| 1373 | | try self.string_table.append(self.base.allocator, 0); |
| 1374 | | const file_size = @intCast(u32, self.string_table.items.len); |
| 1375 | | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1376 | | log.debug("found string table free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1377 | | symtab.stroff = off; |
| 1378 | | symtab.strsize = file_size; |
| 1379 | | |
| 1380 | | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1381 | | linkedit.vmsize += segment_size; |
| 1382 | | } |
| 1383 | | } |
| 1384 | 1339 | if (self.dylinker_cmd_index == null) { |
| 1385 | 1340 | self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1386 | 1341 | const cmdsize = mem.alignForwardGeneric(u64, @sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH), @sizeOf(u64)); |
| ... | ... | @@ -1458,6 +1413,51 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1458 | 1413 | }, |
| 1459 | 1414 | }); |
| 1460 | 1415 | } |
| 1416 | { |
| 1417 | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1418 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo; |
| 1419 | if (dyld_info.export_off == 0) { |
| 1420 | const nsyms = self.base.options.symbol_count_hint; |
| 1421 | const file_size = @sizeOf(u64) * nsyms; |
| 1422 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1423 | log.debug("found export trie free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1424 | dyld_info.export_off = off; |
| 1425 | dyld_info.export_size = @intCast(u32, file_size); |
| 1426 | |
| 1427 | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1428 | linkedit.vmsize += segment_size; |
| 1429 | linkedit.fileoff = off; |
| 1430 | } |
| 1431 | } |
| 1432 | { |
| 1433 | const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1434 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1435 | if (symtab.symoff == 0) { |
| 1436 | const nsyms = self.base.options.symbol_count_hint; |
| 1437 | const file_size = @sizeOf(macho.nlist_64) * nsyms; |
| 1438 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1439 | log.debug("found symbol table free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1440 | symtab.symoff = off; |
| 1441 | symtab.nsyms = @intCast(u32, nsyms); |
| 1442 | |
| 1443 | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1444 | linkedit.vmsize += segment_size; |
| 1445 | // TODO this is needed to please codesign_allocate |
| 1446 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo; |
| 1447 | dyld_info.export_size = off - dyld_info.export_off; |
| 1448 | } |
| 1449 | if (symtab.stroff == 0) { |
| 1450 | try self.string_table.append(self.base.allocator, 0); |
| 1451 | const file_size = @intCast(u32, self.string_table.items.len); |
| 1452 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); |
| 1453 | log.debug("found string table free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 1454 | symtab.stroff = off; |
| 1455 | symtab.strsize = file_size; |
| 1456 | |
| 1457 | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1458 | linkedit.vmsize += segment_size; |
| 1459 | } |
| 1460 | } |
| 1461 | 1461 | if (self.dyld_stub_binder_index == null) { |
| 1462 | 1462 | self.dyld_stub_binder_index = @intCast(u16, self.undef_symbols.items.len); |
| 1463 | 1463 | const name = try self.makeString("dyld_stub_binder"); |
| ... | ... | @@ -1759,7 +1759,9 @@ fn writeStringTable(self: *MachO) !void { |
| 1759 | 1759 | symtab.stroff = @intCast(u32, self.findFreeSpace(needed_size, 1)); |
| 1760 | 1760 | } |
| 1761 | 1761 | symtab.strsize = @intCast(u32, needed_size); |
| 1762 | | log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + needed_size }); |
| 1762 | |
| 1763 | log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 1764 | |
| 1763 | 1765 | try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff); |
| 1764 | 1766 | |
| 1765 | 1767 | // TODO rework how we preallocate space for the entire __LINKEDIT segment instead of |
| ... | ... | @@ -1871,7 +1873,6 @@ fn writeMachOHeader(self: *MachO) !void { |
| 1871 | 1873 | }, |
| 1872 | 1874 | } |
| 1873 | 1875 | hdr.reserved = 0; |
| 1874 | | hdr.reserved = 0; |
| 1875 | 1876 | |
| 1876 | 1877 | log.debug("writing Mach-O header {}\n", .{hdr}); |
| 1877 | 1878 | |