authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-21 18:31:26+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-21 18:31:26+01:00
logde5421a0a666000908527503af8f511b9b3095ed
treeb042401508bb2b6c151925abe094c157e8d440e5
parenta1b3606f0e53755778e408188a08a98b950e62ac

macho: deduplicate symbol table relocation codepath


1 files changed, 11 insertions(+), 31 deletions(-)

src/link/MachO.zig+11-31
...@@ -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}
19421942
1943fn writeLocalSymbol(self: *MachO, index: usize) !void {1943fn 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}
19751973
1974fn 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();
19841987
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 }
20131993
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);
20161996
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);
20212001
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);
20262006