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) = .{},
162162error_flags: File.ErrorFlags = File.ErrorFlags{},
163163
164164load_commands_dirty: bool = false,
165sections_order_dirty: bool = false,
165166
166167has_dices: bool = false,
167168has_stabs: bool = false,
......@@ -806,6 +807,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
806807 defer tracy.end();
807808
808809 try self.setEntryPoint();
810 try self.updateSectionOrdinals();
809811 try self.writeLinkeditSegment();
810812
811813 if (self.d_sym) |*ds| {
......@@ -3817,6 +3819,7 @@ fn allocateSection(
38173819 try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
38183820
38193821 self.load_commands_dirty = true;
3822 self.sections_order_dirty = true;
38203823
38213824 return index;
38223825}
......@@ -3998,6 +4001,44 @@ fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset {
39984001 };
39994002}
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
40014042fn writeDyldInfoData(self: *MachO) !void {
40024043 const tracy = trace(@src());
40034044 defer tracy.end();