authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-05 00:19:45+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-05 00:19:45+02:00
logd92b5416e86f2b6bf0cf530c8f98da572bf9efde
tree40445f7051dadc283b3b336fd120fb9c8270eee8
parent7e87f93e068af192a3c39bdeebfe8e9b612311b0

macho: add a small routine to update section ordinals at the end

The actual ordinals may change when adding new sections to the segments.

1 files changed, 41 insertions(+), 0 deletions(-)

src/link/MachO.zig+41
...@@ -162,6 +162,7 @@ stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{},...@@ -162,6 +162,7 @@ stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{},
162error_flags: File.ErrorFlags = File.ErrorFlags{},162error_flags: File.ErrorFlags = File.ErrorFlags{},
163163
164load_commands_dirty: bool = false,164load_commands_dirty: bool = false,
165sections_order_dirty: bool = false,
165166
166has_dices: bool = false,167has_dices: bool = false,
167has_stabs: bool = false,168has_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();
807808
808 try self.setEntryPoint();809 try self.setEntryPoint();
810 try self.updateSectionOrdinals();
809 try self.writeLinkeditSegment();811 try self.writeLinkeditSegment();
810812
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, .{});
38183820
3819 self.load_commands_dirty = true;3821 self.load_commands_dirty = true;
3822 self.sections_order_dirty = true;
38203823
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}
40004003
4004fn 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
4001fn writeDyldInfoData(self: *MachO) !void {4042fn writeDyldInfoData(self: *MachO) !void {
4002 const tracy = trace(@src());4043 const tracy = trace(@src());
4003 defer tracy.end();4044 defer tracy.end();