| ... | @@ -2082,7 +2082,6 @@ fn flush(self: *Zld) !void { | ... | @@ -2082,7 +2082,6 @@ fn flush(self: *Zld) !void { |
| 2082 | try self.populateStringTable(); | 2082 | try self.populateStringTable(); |
| 2083 | try self.writeDebugInfo(); | 2083 | try self.writeDebugInfo(); |
| 2084 | try self.writeSymbolTable(); | 2084 | try self.writeSymbolTable(); |
| 2085 | try self.writeDynamicSymbolTable(); | | |
| 2086 | try self.writeStringTable(); | 2085 | try self.writeStringTable(); |
| 2087 | | 2086 | |
| 2088 | { | 2087 | { |
| ... | @@ -2604,6 +2603,10 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2604,6 +2603,10 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2604 | var undefs = std.ArrayList(macho.nlist_64).init(self.allocator); | 2603 | var undefs = std.ArrayList(macho.nlist_64).init(self.allocator); |
| 2605 | defer undefs.deinit(); | 2604 | defer undefs.deinit(); |
| 2606 | | 2605 | |
| | 2606 | var undefs_ids = std.StringHashMap(u32).init(self.allocator); |
| | 2607 | defer undefs_ids.deinit(); |
| | 2608 | |
| | 2609 | var undef_id: u32 = 0; |
| 2607 | for (self.symtab.items()) |entry| { | 2610 | for (self.symtab.items()) |entry| { |
| 2608 | switch (entry.value.tag) { | 2611 | switch (entry.value.tag) { |
| 2609 | .Weak, .Strong => { | 2612 | .Weak, .Strong => { |
| ... | @@ -2611,6 +2614,8 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2611,6 +2614,8 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2611 | }, | 2614 | }, |
| 2612 | .Import => { | 2615 | .Import => { |
| 2613 | try undefs.append(entry.value.inner); | 2616 | try undefs.append(entry.value.inner); |
| | 2617 | try undefs_ids.putNoClobber(entry.key, undef_id); |
| | 2618 | undef_id += 1; |
| 2614 | }, | 2619 | }, |
| 2615 | else => unreachable, | 2620 | else => unreachable, |
| 2616 | } | 2621 | } |
| ... | @@ -2645,17 +2650,13 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2645,17 +2650,13 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2645 | dysymtab.nextdefsym = @intCast(u32, nexports); | 2650 | dysymtab.nextdefsym = @intCast(u32, nexports); |
| 2646 | dysymtab.iundefsym = dysymtab.nlocalsym + dysymtab.nextdefsym; | 2651 | dysymtab.iundefsym = dysymtab.nlocalsym + dysymtab.nextdefsym; |
| 2647 | dysymtab.nundefsym = @intCast(u32, nundefs); | 2652 | dysymtab.nundefsym = @intCast(u32, nundefs); |
| 2648 | } | | |
| 2649 | | 2653 | |
| 2650 | fn writeDynamicSymbolTable(self: *Zld) !void { | | |
| 2651 | const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | | |
| 2652 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2654 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2653 | const stubs = &text_segment.sections.items[self.stubs_section_index.?]; | 2655 | const stubs = &text_segment.sections.items[self.stubs_section_index.?]; |
| 2654 | const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2656 | const data_const_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2655 | const got = &data_const_segment.sections.items[self.got_section_index.?]; | 2657 | const got = &data_const_segment.sections.items[self.got_section_index.?]; |
| 2656 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2658 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2657 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 2659 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2658 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; | | |
| 2659 | | 2660 | |
| 2660 | const nstubs = @intCast(u32, self.stubs.items().len); | 2661 | const nstubs = @intCast(u32, self.stubs.items().len); |
| 2661 | const ngot_entries = @intCast(u32, self.got_entries.items().len); | 2662 | const ngot_entries = @intCast(u32, self.got_entries.items().len); |
| ... | @@ -2679,15 +2680,15 @@ fn writeDynamicSymbolTable(self: *Zld) !void { | ... | @@ -2679,15 +2680,15 @@ fn writeDynamicSymbolTable(self: *Zld) !void { |
| 2679 | | 2680 | |
| 2680 | stubs.reserved1 = 0; | 2681 | stubs.reserved1 = 0; |
| 2681 | for (self.stubs.items()) |entry| { | 2682 | for (self.stubs.items()) |entry| { |
| 2682 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value); | 2683 | const id = undefs_ids.get(entry.key) orelse unreachable; |
| 2683 | try writer.writeIntLittle(u32, symtab_idx); | 2684 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2684 | } | 2685 | } |
| 2685 | | 2686 | |
| 2686 | got.reserved1 = nstubs; | 2687 | got.reserved1 = nstubs; |
| 2687 | for (self.got_entries.items()) |entry| { | 2688 | for (self.got_entries.items()) |entry| { |
| 2688 | if (entry.value.tag == .import) { | 2689 | if (entry.value.tag == .import) { |
| 2689 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index + nstubs); | 2690 | const id = undefs_ids.get(entry.key) orelse unreachable; |
| 2690 | try writer.writeIntLittle(u32, symtab_idx); | 2691 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2691 | } else { | 2692 | } else { |
| 2692 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); | 2693 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); |
| 2693 | } | 2694 | } |
| ... | @@ -2695,8 +2696,8 @@ fn writeDynamicSymbolTable(self: *Zld) !void { | ... | @@ -2695,8 +2696,8 @@ fn writeDynamicSymbolTable(self: *Zld) !void { |
| 2695 | | 2696 | |
| 2696 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; | 2697 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 2697 | for (self.stubs.items()) |entry| { | 2698 | for (self.stubs.items()) |entry| { |
| 2698 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value); | 2699 | const id = undefs_ids.get(entry.key) orelse unreachable; |
| 2699 | try writer.writeIntLittle(u32, symtab_idx); | 2700 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2700 | } | 2701 | } |
| 2701 | | 2702 | |
| 2702 | try self.file.?.pwriteAll(buf, dysymtab.indirectsymoff); | 2703 | try self.file.?.pwriteAll(buf, dysymtab.indirectsymoff); |
| ... | @@ -2887,22 +2888,3 @@ pub fn parseName(name: *const [16]u8) []const u8 { | ... | @@ -2887,22 +2888,3 @@ pub fn parseName(name: *const [16]u8) []const u8 { |
| 2887 | const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len; | 2888 | const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len; |
| 2888 | return name[0..len]; | 2889 | return name[0..len]; |
| 2889 | } | 2890 | } |
| 2890 | | | |
| 2891 | fn printDebug(self: Zld) void { | | |
| 2892 | log.warn("symtab", .{}); | | |
| 2893 | for (self.symtab.items()) |entry| { | | |
| 2894 | log.warn(" | {s} => {any}", .{ entry.key, entry.value }); | | |
| 2895 | } | | |
| 2896 | | | |
| 2897 | log.warn("\n", .{}); | | |
| 2898 | log.warn("GOT entries", .{}); | | |
| 2899 | for (self.got_entries.items()) |entry| { | | |
| 2900 | log.warn(" | {s} => {any}", .{ entry.key, entry.value }); | | |
| 2901 | } | | |
| 2902 | | | |
| 2903 | log.warn("\n", .{}); | | |
| 2904 | log.warn("stubs", .{}); | | |
| 2905 | for (self.stubs.items()) |entry| { | | |
| 2906 | log.warn(" | {s} => {any}", .{ entry.key, entry.value }); | | |
| 2907 | } | | |
| 2908 | } | | |