aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-04-09 15:39:24 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-04-13 10:56:03 +0200
commitb377e0b370252e08d55dd384e23ed3fd05aea5c5 (patch)
tree16328acb2bd39becee88a9471efee52994b57fb2 /src/link
parentb0a4e1fa46267e913ab9de77cf4b61907d418810 (diff)
downloadzig-b377e0b370252e08d55dd384e23ed3fd05aea5c5.tar.gz
zig-b377e0b370252e08d55dd384e23ed3fd05aea5c5.zip
zld: fix indirect symtab
Diffstat (limited to 'src/link')
-rw-r--r--src/link/MachO/Zld.zig42
1 files changed, 12 insertions, 30 deletions
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index afae4640e2..61fee54f54 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -2082,7 +2082,6 @@ fn flush(self: *Zld) !void {
try self.populateStringTable();
try self.writeDebugInfo();
try self.writeSymbolTable();
- try self.writeDynamicSymbolTable();
try self.writeStringTable();
{
@@ -2604,6 +2603,10 @@ fn writeSymbolTable(self: *Zld) !void {
var undefs = std.ArrayList(macho.nlist_64).init(self.allocator);
defer undefs.deinit();
+ var undefs_ids = std.StringHashMap(u32).init(self.allocator);
+ defer undefs_ids.deinit();
+
+ var undef_id: u32 = 0;
for (self.symtab.items()) |entry| {
switch (entry.value.tag) {
.Weak, .Strong => {
@@ -2611,6 +2614,8 @@ fn writeSymbolTable(self: *Zld) !void {
},
.Import => {
try undefs.append(entry.value.inner);
+ try undefs_ids.putNoClobber(entry.key, undef_id);
+ undef_id += 1;
},
else => unreachable,
}
@@ -2645,17 +2650,13 @@ fn writeSymbolTable(self: *Zld) !void {
dysymtab.nextdefsym = @intCast(u32, nexports);
dysymtab.iundefsym = dysymtab.nlocalsym + dysymtab.nextdefsym;
dysymtab.nundefsym = @intCast(u32, nundefs);
-}
-fn writeDynamicSymbolTable(self: *Zld) !void {
- const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
const stubs = &text_segment.sections.items[self.stubs_section_index.?];
const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
const got = &data_const_segment.sections.items[self.got_section_index.?];
const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
- const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
const nstubs = @intCast(u32, self.stubs.items().len);
const ngot_entries = @intCast(u32, self.got_entries.items().len);
@@ -2679,15 +2680,15 @@ fn writeDynamicSymbolTable(self: *Zld) !void {
stubs.reserved1 = 0;
for (self.stubs.items()) |entry| {
- const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value);
- try writer.writeIntLittle(u32, symtab_idx);
+ const id = undefs_ids.get(entry.key) orelse unreachable;
+ try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
}
got.reserved1 = nstubs;
for (self.got_entries.items()) |entry| {
if (entry.value.tag == .import) {
- const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index + nstubs);
- try writer.writeIntLittle(u32, symtab_idx);
+ const id = undefs_ids.get(entry.key) orelse unreachable;
+ try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
} else {
try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);
}
@@ -2695,8 +2696,8 @@ fn writeDynamicSymbolTable(self: *Zld) !void {
la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;
for (self.stubs.items()) |entry| {
- const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value);
- try writer.writeIntLittle(u32, symtab_idx);
+ const id = undefs_ids.get(entry.key) orelse unreachable;
+ try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
}
try self.file.?.pwriteAll(buf, dysymtab.indirectsymoff);
@@ -2887,22 +2888,3 @@ pub fn parseName(name: *const [16]u8) []const u8 {
const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;
return name[0..len];
}
-
-fn printDebug(self: Zld) void {
- log.warn("symtab", .{});
- for (self.symtab.items()) |entry| {
- log.warn(" | {s} => {any}", .{ entry.key, entry.value });
- }
-
- log.warn("\n", .{});
- log.warn("GOT entries", .{});
- for (self.got_entries.items()) |entry| {
- log.warn(" | {s} => {any}", .{ entry.key, entry.value });
- }
-
- log.warn("\n", .{});
- log.warn("stubs", .{});
- for (self.stubs.items()) |entry| {
- log.warn(" | {s} => {any}", .{ entry.key, entry.value });
- }
-}