| ... | @@ -162,6 +162,7 @@ stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{}, | ... | @@ -162,6 +162,7 @@ stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{}, |
| 162 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 162 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 163 | | 163 | |
| 164 | load_commands_dirty: bool = false, | 164 | load_commands_dirty: bool = false, |
| | 165 | sections_order_dirty: bool = false, |
| 165 | | 166 | |
| 166 | has_dices: bool = false, | 167 | has_dices: bool = false, |
| 167 | has_stabs: bool = false, | 168 | has_stabs: bool = false, |
| ... | @@ -806,6 +807,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -806,6 +807,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 806 | defer tracy.end(); | 807 | defer tracy.end(); |
| 807 | | 808 | |
| 808 | try self.setEntryPoint(); | 809 | try self.setEntryPoint(); |
| | 810 | try self.updateSectionOrdinals(); |
| 809 | try self.writeLinkeditSegment(); | 811 | try self.writeLinkeditSegment(); |
| 810 | | 812 | |
| 811 | if (self.d_sym) |*ds| { | 813 | if (self.d_sym) |*ds| { |
| ... | @@ -3817,6 +3819,7 @@ fn allocateSection( | ... | @@ -3817,6 +3819,7 @@ fn allocateSection( |
| 3817 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | 3819 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); |
| 3818 | | 3820 | |
| 3819 | self.load_commands_dirty = true; | 3821 | self.load_commands_dirty = true; |
| | 3822 | self.sections_order_dirty = true; |
| 3820 | | 3823 | |
| 3821 | return index; | 3824 | return index; |
| 3822 | } | 3825 | } |
| ... | @@ -3998,6 +4001,44 @@ fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset { | ... | @@ -3998,6 +4001,44 @@ fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset { |
| 3998 | }; | 4001 | }; |
| 3999 | } | 4002 | } |
| 4000 | | 4003 | |
| | 4004 | fn updateSectionOrdinals(self: *MachO) !void { |
| | 4005 | if (!self.sections_order_dirty) return; |
| | 4006 | |
| | 4007 | const tracy = trace(@src()); |
| | 4008 | defer tracy.end(); |
| | 4009 | |
| | 4010 | var ordinal_remap = std.AutoHashMap(u8, u8).init(self.base.allocator); |
| | 4011 | defer ordinal_remap.deinit(); |
| | 4012 | var ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{}; |
| | 4013 | |
| | 4014 | var new_ordinal: u8 = 0; |
| | 4015 | for (self.load_commands.items) |lc, lc_id| { |
| | 4016 | if (lc != .Segment) break; |
| | 4017 | |
| | 4018 | for (lc.Segment.sections.items) |_, sect_id| { |
| | 4019 | const match = MatchingSection{ |
| | 4020 | .seg = @intCast(u16, lc_id), |
| | 4021 | .sect = @intCast(u16, sect_id), |
| | 4022 | }; |
| | 4023 | const old_ordinal = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| | 4024 | new_ordinal += 1; |
| | 4025 | try ordinal_remap.putNoClobber(old_ordinal, new_ordinal); |
| | 4026 | try ordinals.putNoClobber(self.base.allocator, match, {}); |
| | 4027 | } |
| | 4028 | } |
| | 4029 | |
| | 4030 | for (self.locals.items) |*sym| { |
| | 4031 | if (sym.n_sect == 0) continue; |
| | 4032 | sym.n_sect = ordinal_remap.get(sym.n_sect).?; |
| | 4033 | } |
| | 4034 | for (self.globals.items) |*sym| { |
| | 4035 | sym.n_sect = ordinal_remap.get(sym.n_sect).?; |
| | 4036 | } |
| | 4037 | |
| | 4038 | self.section_ordinals.deinit(self.base.allocator); |
| | 4039 | self.section_ordinals = ordinals; |
| | 4040 | } |
| | 4041 | |
| 4001 | fn writeDyldInfoData(self: *MachO) !void { | 4042 | fn writeDyldInfoData(self: *MachO) !void { |
| 4002 | const tracy = trace(@src()); | 4043 | const tracy = trace(@src()); |
| 4003 | defer tracy.end(); | 4044 | defer tracy.end(); |