diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2020-09-30 08:19:47 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2020-10-04 15:31:47 +0200 |
| commit | 635984abc7ab508b8e81448bb081be41aad046d0 (patch) | |
| tree | 4ebfc378c4c707276e30055c35b086b8be23feae /src/link | |
| parent | ccf9bba61f4134d9f57e50d64cef201c064d6b9a (diff) | |
| download | zig-635984abc7ab508b8e81448bb081be41aad046d0.tar.gz zig-635984abc7ab508b8e81448bb081be41aad046d0.zip | |
Move writing symbol table and export trie into functions
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/MachO.zig | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index ab52353eed..4a37a4d468 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -236,33 +236,26 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { .Lib => return error.TODOImplementWritingLibFiles, } - // Unfortunately these have to be buffered and done at the end because ELF does not allow - // mixing local and global symbols within a symbol table. + try self.writeExportTrie(); + + // Unfortunately these have to be buffered and done at the end because MachO does not allow + // mixing local, global and undefined symbols within a symbol table. try self.writeAllGlobalSymbols(); try self.writeAllUndefSymbols(); - { - const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; - symtab.nsyms = @intCast(u32, self.local_symbols.items.len + self.global_symbols.items.len + self.undef_symbols.items.len); - const allocated_size = self.allocatedSize(symtab.stroff); - const needed_size = self.string_table.items.len; - log.debug("allocated_size = 0x{x}, needed_size = 0x{x}\n", .{ allocated_size, needed_size }); - - if (needed_size > allocated_size) { - symtab.strsize = 0; - symtab.stroff = @intCast(u32, self.findFreeSpace(needed_size, 1)); - } - symtab.strsize = @intCast(u32, needed_size); + try self.writeStringTable(); - log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize }); - - try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff); - } { - const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; + // update Symtab and Dysymtab commands with symbol counts + // TODO this could probably be done incrementally const nlocals = @intCast(u32, self.local_symbols.items.len); const nglobals = @intCast(u32, self.global_symbols.items.len); const nundefs = @intCast(u32, self.undef_symbols.items.len); + + const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; + symtab.nsyms = nlocals + nglobals + nundefs; + + const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; dysymtab.nlocalsym = nlocals; dysymtab.iextdefsym = nlocals; dysymtab.nextdefsym = nglobals; @@ -1020,6 +1013,26 @@ pub fn populateMissingMetadata(self: *MachO) !void { }); self.cmd_table_dirty = true; } + if (self.dyld_info_cmd_index == null) { + self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len); + try self.load_commands.append(self.base.allocator, .{ + .DyldInfo = .{ + .cmd = macho.LC_DYLD_INFO_ONLY, + .cmdsize = @sizeOf(macho.dyld_info_command), + .rebase_off = 0, + .rebase_size = 0, + .bind_off = 0, + .bind_size = 0, + .weak_bind_off = 0, + .weak_bind_size = 0, + .lazy_bind_off = 0, + .lazy_bind_size = 0, + .export_off = 0, + .export_size = 0, + }, + }); + self.cmd_table_dirty = true; + } if (self.symtab_cmd_index == null) { self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); try self.load_commands.append(self.base.allocator, .{ @@ -1366,6 +1379,38 @@ fn writeAllUndefSymbols(self: *MachO) !void { try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off); } +fn writeExportTrie(self: *MachO) !void { + // TODO + // single branch export trie + var buf = [_]u8{0} ** 24; + buf[0] = 0; // root node + buf[1] = 1; // 1 branch from root + mem.copy(u8, buf[2..], "_start"); + buf[8] = 0; + buf[9] = 9 + 1; + const written = try std.debug.leb.writeULEB128Mem(buf[12..], self.entry_addr.?); + buf[10] = @intCast(u8, written) + 1; + buf[11] = 0; + log.debug("WAT = {}, {x}\n", .{ written, buf[0..] }); +} + +fn writeStringTable(self: *MachO) !void { + const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; + const allocated_size = self.allocatedSize(symtab.stroff); + const needed_size = self.string_table.items.len; + log.debug("allocated_size = 0x{x}, needed_size = 0x{x}\n", .{ allocated_size, needed_size }); + + if (needed_size > allocated_size) { + symtab.strsize = 0; + symtab.stroff = @intCast(u32, self.findFreeSpace(needed_size, 1)); + } + symtab.strsize = @intCast(u32, needed_size); + + log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize }); + + try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff); +} + /// Writes Mach-O file header. /// Should be invoked last as it needs up-to-date values of ncmds and sizeof_cmds bookkeeping /// variables. |
