| ... | @@ -1940,10 +1940,7 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { | ... | @@ -1940,10 +1940,7 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 1940 | try self.base.file.?.pwriteAll(&code, off); | 1940 | try self.base.file.?.pwriteAll(&code, off); |
| 1941 | } | 1941 | } |
| 1942 | | 1942 | |
| 1943 | fn writeLocalSymbol(self: *MachO, index: usize) !void { | 1943 | fn relocateSymbolTable(self: *MachO) !void { |
| 1944 | const tracy = trace(@src()); | | |
| 1945 | defer tracy.end(); | | |
| 1946 | | | |
| 1947 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 1944 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1948 | const nlocals = self.local_symbols.items.len; | 1945 | const nlocals = self.local_symbols.items.len; |
| 1949 | const nglobals = self.global_symbols.items.len; | 1946 | const nglobals = self.global_symbols.items.len; |
| ... | @@ -1972,7 +1969,13 @@ fn writeLocalSymbol(self: *MachO, index: usize) !void { | ... | @@ -1972,7 +1969,13 @@ fn writeLocalSymbol(self: *MachO, index: usize) !void { |
| 1972 | symtab.nsyms = @intCast(u32, nsyms); | 1969 | symtab.nsyms = @intCast(u32, nsyms); |
| 1973 | self.cmd_table_dirty = true; | 1970 | self.cmd_table_dirty = true; |
| 1974 | } | 1971 | } |
| | 1972 | } |
| 1975 | | 1973 | |
| | 1974 | fn writeLocalSymbol(self: *MachO, index: usize) !void { |
| | 1975 | const tracy = trace(@src()); |
| | 1976 | defer tracy.end(); |
| | 1977 | try self.relocateSymbolTable(); |
| | 1978 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1976 | const off = symtab.symoff + @sizeOf(macho.nlist_64) * index; | 1979 | const off = symtab.symoff + @sizeOf(macho.nlist_64) * index; |
| 1977 | log.debug("writing local symbol {} at 0x{x}", .{ index, off }); | 1980 | log.debug("writing local symbol {} at 0x{x}", .{ index, off }); |
| 1978 | try self.base.file.?.pwriteAll(mem.asBytes(&self.local_symbols.items[index]), off); | 1981 | try self.base.file.?.pwriteAll(mem.asBytes(&self.local_symbols.items[index]), off); |
| ... | @@ -1982,45 +1985,22 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { | ... | @@ -1982,45 +1985,22 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 1982 | const tracy = trace(@src()); | 1985 | const tracy = trace(@src()); |
| 1983 | defer tracy.end(); | 1986 | defer tracy.end(); |
| 1984 | | 1987 | |
| | 1988 | try self.relocateSymbolTable(); |
| 1985 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 1989 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 1986 | const nlocals = self.local_symbols.items.len; | 1990 | const nlocals = self.local_symbols.items.len; |
| 1987 | const nglobals = self.global_symbols.items.len; | 1991 | const nglobals = self.global_symbols.items.len; |
| 1988 | const nundefs = self.undef_symbols.items.len; | 1992 | const nundefs = self.undef_symbols.items.len; |
| 1989 | const nsyms = nlocals + nglobals + nundefs; | | |
| 1990 | | | |
| 1991 | if (symtab.nsyms < nsyms) { | | |
| 1992 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | | |
| 1993 | const needed_size = nsyms * @sizeOf(macho.nlist_64); | | |
| 1994 | if (needed_size > self.allocatedSize(&linkedit_segment, symtab.symoff)) { | | |
| 1995 | // Move the entire symbol table to a new location | | |
| 1996 | const new_symoff = self.findFreeSpace(&linkedit_segment, needed_size, @alignOf(macho.nlist_64)); | | |
| 1997 | const existing_size = symtab.nsyms * @sizeOf(macho.nlist_64); | | |
| 1998 | | | |
| 1999 | log.debug("relocating symbol table from 0x{x}-0x{x} to 0x{x}-0x{x}", .{ | | |
| 2000 | symtab.symoff, | | |
| 2001 | symtab.symoff + existing_size, | | |
| 2002 | new_symoff, | | |
| 2003 | new_symoff + existing_size, | | |
| 2004 | }); | | |
| 2005 | | | |
| 2006 | const amt = try self.base.file.?.copyRangeAll(symtab.symoff, self.base.file.?, new_symoff, existing_size); | | |
| 2007 | if (amt != existing_size) return error.InputOutput; | | |
| 2008 | symtab.symoff = @intCast(u32, new_symoff); | | |
| 2009 | } | | |
| 2010 | symtab.nsyms = @intCast(u32, nsyms); | | |
| 2011 | self.cmd_table_dirty = true; | | |
| 2012 | } | | |
| 2013 | | 1993 | |
| 2014 | const locals_off = symtab.symoff; | 1994 | const locals_off = symtab.symoff; |
| 2015 | const locals_size = self.local_symbols.items.len * @sizeOf(macho.nlist_64); | 1995 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| 2016 | | 1996 | |
| 2017 | const globals_off = locals_off + locals_size; | 1997 | const globals_off = locals_off + locals_size; |
| 2018 | const globals_size = self.global_symbols.items.len * @sizeOf(macho.nlist_64); | 1998 | const globals_size = nglobals * @sizeOf(macho.nlist_64); |
| 2019 | log.debug("writing global symbols from 0x{x} to 0x{x}\n", .{ globals_off, globals_size + globals_off }); | 1999 | log.debug("writing global symbols from 0x{x} to 0x{x}\n", .{ globals_off, globals_size + globals_off }); |
| 2020 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.global_symbols.items), globals_off); | 2000 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.global_symbols.items), globals_off); |
| 2021 | | 2001 | |
| 2022 | const undefs_off = globals_off + globals_size; | 2002 | const undefs_off = globals_off + globals_size; |
| 2023 | const undefs_size = self.undef_symbols.items.len * @sizeOf(macho.nlist_64); | 2003 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 2024 | log.debug("writing undef symbols from 0x{x} to 0x{x}\n", .{ undefs_off, undefs_size + undefs_off }); | 2004 | log.debug("writing undef symbols from 0x{x} to 0x{x}\n", .{ undefs_off, undefs_size + undefs_off }); |
| 2025 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), undefs_off); | 2005 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), undefs_off); |
| 2026 | | 2006 | |