aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-09-05 00:19:45 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-09-05 00:19:45 +0200
commitd92b5416e86f2b6bf0cf530c8f98da572bf9efde (patch)
tree40445f7051dadc283b3b336fd120fb9c8270eee8 /src
parent7e87f93e068af192a3c39bdeebfe8e9b612311b0 (diff)
downloadzig-d92b5416e86f2b6bf0cf530c8f98da572bf9efde.tar.gz
zig-d92b5416e86f2b6bf0cf530c8f98da572bf9efde.zip
macho: add a small routine to update section ordinals at the end
The actual ordinals may change when adding new sections to the segments.
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 4ee81e7c43..ce6fe49d35 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -162,6 +162,7 @@ stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{},
error_flags: File.ErrorFlags = File.ErrorFlags{},
load_commands_dirty: bool = false,
+sections_order_dirty: bool = false,
has_dices: bool = false,
has_stabs: bool = false,
@@ -806,6 +807,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
defer tracy.end();
try self.setEntryPoint();
+ try self.updateSectionOrdinals();
try self.writeLinkeditSegment();
if (self.d_sym) |*ds| {
@@ -3817,6 +3819,7 @@ fn allocateSection(
try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
self.load_commands_dirty = true;
+ self.sections_order_dirty = true;
return index;
}
@@ -3998,6 +4001,44 @@ fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset {
};
}
+fn updateSectionOrdinals(self: *MachO) !void {
+ if (!self.sections_order_dirty) return;
+
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ var ordinal_remap = std.AutoHashMap(u8, u8).init(self.base.allocator);
+ defer ordinal_remap.deinit();
+ var ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{};
+
+ var new_ordinal: u8 = 0;
+ for (self.load_commands.items) |lc, lc_id| {
+ if (lc != .Segment) break;
+
+ for (lc.Segment.sections.items) |_, sect_id| {
+ const match = MatchingSection{
+ .seg = @intCast(u16, lc_id),
+ .sect = @intCast(u16, sect_id),
+ };
+ const old_ordinal = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
+ new_ordinal += 1;
+ try ordinal_remap.putNoClobber(old_ordinal, new_ordinal);
+ try ordinals.putNoClobber(self.base.allocator, match, {});
+ }
+ }
+
+ for (self.locals.items) |*sym| {
+ if (sym.n_sect == 0) continue;
+ sym.n_sect = ordinal_remap.get(sym.n_sect).?;
+ }
+ for (self.globals.items) |*sym| {
+ sym.n_sect = ordinal_remap.get(sym.n_sect).?;
+ }
+
+ self.section_ordinals.deinit(self.base.allocator);
+ self.section_ordinals = ordinals;
+}
+
fn writeDyldInfoData(self: *MachO) !void {
const tracy = trace(@src());
defer tracy.end();