authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-09-30 08:19:47+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-10-04 15:31:47+02:00
log635984abc7ab508b8e81448bb081be41aad046d0
tree4ebfc378c4c707276e30055c35b086b8be23feae
parentccf9bba61f4134d9f57e50d64cef201c064d6b9a

Move writing symbol table and export trie into functions


1 files changed, 64 insertions(+), 19 deletions(-)

src/link/MachO.zig+64-19
...@@ -236,33 +236,26 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -236,33 +236,26 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
236 .Lib => return error.TODOImplementWritingLibFiles,236 .Lib => return error.TODOImplementWritingLibFiles,
237 }237 }
238238
239 // Unfortunately these have to be buffered and done at the end because ELF does not allow239 try self.writeExportTrie();
240 // mixing local and global symbols within a symbol table.240
241 // Unfortunately these have to be buffered and done at the end because MachO does not allow
242 // mixing local, global and undefined symbols within a symbol table.
241 try self.writeAllGlobalSymbols();243 try self.writeAllGlobalSymbols();
242 try self.writeAllUndefSymbols();244 try self.writeAllUndefSymbols();
243245
244 {246 try self.writeStringTable();
245 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
246 symtab.nsyms = @intCast(u32, self.local_symbols.items.len + self.global_symbols.items.len + self.undef_symbols.items.len);
247 const allocated_size = self.allocatedSize(symtab.stroff);
248 const needed_size = self.string_table.items.len;
249 log.debug("allocated_size = 0x{x}, needed_size = 0x{x}\n", .{ allocated_size, needed_size });
250
251 if (needed_size > allocated_size) {
252 symtab.strsize = 0;
253 symtab.stroff = @intCast(u32, self.findFreeSpace(needed_size, 1));
254 }
255 symtab.strsize = @intCast(u32, needed_size);
256247
257 log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize });
258
259 try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff);
260 }
261 {248 {
262 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;249 // update Symtab and Dysymtab commands with symbol counts
250 // TODO this could probably be done incrementally
263 const nlocals = @intCast(u32, self.local_symbols.items.len);251 const nlocals = @intCast(u32, self.local_symbols.items.len);
264 const nglobals = @intCast(u32, self.global_symbols.items.len);252 const nglobals = @intCast(u32, self.global_symbols.items.len);
265 const nundefs = @intCast(u32, self.undef_symbols.items.len);253 const nundefs = @intCast(u32, self.undef_symbols.items.len);
254
255 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
256 symtab.nsyms = nlocals + nglobals + nundefs;
257
258 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
266 dysymtab.nlocalsym = nlocals;259 dysymtab.nlocalsym = nlocals;
267 dysymtab.iextdefsym = nlocals;260 dysymtab.iextdefsym = nlocals;
268 dysymtab.nextdefsym = nglobals;261 dysymtab.nextdefsym = nglobals;
...@@ -1020,6 +1013,26 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1020,6 +1013,26 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1020 });1013 });
1021 self.cmd_table_dirty = true;1014 self.cmd_table_dirty = true;
1022 }1015 }
1016 if (self.dyld_info_cmd_index == null) {
1017 self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len);
1018 try self.load_commands.append(self.base.allocator, .{
1019 .DyldInfo = .{
1020 .cmd = macho.LC_DYLD_INFO_ONLY,
1021 .cmdsize = @sizeOf(macho.dyld_info_command),
1022 .rebase_off = 0,
1023 .rebase_size = 0,
1024 .bind_off = 0,
1025 .bind_size = 0,
1026 .weak_bind_off = 0,
1027 .weak_bind_size = 0,
1028 .lazy_bind_off = 0,
1029 .lazy_bind_size = 0,
1030 .export_off = 0,
1031 .export_size = 0,
1032 },
1033 });
1034 self.cmd_table_dirty = true;
1035 }
1023 if (self.symtab_cmd_index == null) {1036 if (self.symtab_cmd_index == null) {
1024 self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len);1037 self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len);
1025 try self.load_commands.append(self.base.allocator, .{1038 try self.load_commands.append(self.base.allocator, .{
...@@ -1366,6 +1379,38 @@ fn writeAllUndefSymbols(self: *MachO) !void {...@@ -1366,6 +1379,38 @@ fn writeAllUndefSymbols(self: *MachO) !void {
1366 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off);1379 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off);
1367}1380}
13681381
1382fn writeExportTrie(self: *MachO) !void {
1383 // TODO
1384 // single branch export trie
1385 var buf = [_]u8{0} ** 24;
1386 buf[0] = 0; // root node
1387 buf[1] = 1; // 1 branch from root
1388 mem.copy(u8, buf[2..], "_start");
1389 buf[8] = 0;
1390 buf[9] = 9 + 1;
1391 const written = try std.debug.leb.writeULEB128Mem(buf[12..], self.entry_addr.?);
1392 buf[10] = @intCast(u8, written) + 1;
1393 buf[11] = 0;
1394 log.debug("WAT = {}, {x}\n", .{ written, buf[0..] });
1395}
1396
1397fn writeStringTable(self: *MachO) !void {
1398 const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
1399 const allocated_size = self.allocatedSize(symtab.stroff);
1400 const needed_size = self.string_table.items.len;
1401 log.debug("allocated_size = 0x{x}, needed_size = 0x{x}\n", .{ allocated_size, needed_size });
1402
1403 if (needed_size > allocated_size) {
1404 symtab.strsize = 0;
1405 symtab.stroff = @intCast(u32, self.findFreeSpace(needed_size, 1));
1406 }
1407 symtab.strsize = @intCast(u32, needed_size);
1408
1409 log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize });
1410
1411 try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff);
1412}
1413
1369/// Writes Mach-O file header.1414/// Writes Mach-O file header.
1370/// Should be invoked last as it needs up-to-date values of ncmds and sizeof_cmds bookkeeping1415/// Should be invoked last as it needs up-to-date values of ncmds and sizeof_cmds bookkeeping
1371/// variables.1416/// variables.