Skip to content

Commit

Permalink
macho: store index into LiteralPool in atom rather than new target di…
Browse files Browse the repository at this point in the history
…rectly
  • Loading branch information
kubkon committed May 21, 2024
1 parent ce1f05f commit 1d974fb
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 34 deletions.
8 changes: 6 additions & 2 deletions src/MachO.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1247,10 +1247,10 @@ pub fn dedupLiterals(self: *MachO) !void {
}

for (self.objects.items) |index| {
self.getFile(index).?.object.dedupLiterals(self);
self.getFile(index).?.object.dedupLiterals(lp, self);
}
if (self.getInternalObject()) |object| {
object.dedupLiterals(self);
object.dedupLiterals(lp, self);
}
}

Expand Down Expand Up @@ -3185,6 +3185,7 @@ pub const LiteralPool = struct {

const InsertResult = struct {
found_existing: bool,
index: Index,
atom: *Atom.Index,
};

Expand All @@ -3202,6 +3203,7 @@ pub const LiteralPool = struct {
}
return .{
.found_existing = gop.found_existing,
.index = @intCast(gop.index),
.atom = &lp.values.items[gop.index],
};
}
Expand Down Expand Up @@ -3240,6 +3242,8 @@ pub const LiteralPool = struct {
return key.hash(ctx.lp);
}
};

pub const Index = u32;
};

const Section = struct {
Expand Down
17 changes: 11 additions & 6 deletions src/MachO/Atom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,18 @@ pub fn getThunk(self: Atom, macho_file: *MachO) *Thunk {
return macho_file.getThunk(extra.thunk);
}

pub fn getLiteralPoolIndex(self: Atom, macho_file: *MachO) ?MachO.LiteralPool.Index {
if (!self.flags.literal_pool) return null;
return self.getExtra(macho_file).?.literal_index;
}

const AddExtraOpts = struct {
thunk: ?u32 = null,
rel_index: ?u32 = null,
rel_count: ?u32 = null,
unwind_index: ?u32 = null,
unwind_count: ?u32 = null,
literal_leader: ?u32 = null,
literal_index: ?u32 = null,
};

pub fn addExtra(atom: *Atom, opts: AddExtraOpts, macho_file: *MachO) !void {
Expand Down Expand Up @@ -890,9 +895,6 @@ pub const Flags = packed struct {
/// Specifies if the atom has been visited during garbage collection.
visited: bool = false,

/// Specifies if the atom should be deduplicated.
literal_dedup: bool = false,

/// Whether this atom has a range extension thunk.
thunk: bool = false,

Expand All @@ -901,6 +903,9 @@ pub const Flags = packed struct {

/// Whether this atom has any unwind records.
unwind: bool = false,

/// Whether this atom has LiteralPool entry.
literal_pool: bool = false,
};

pub const Extra = struct {
Expand All @@ -919,8 +924,8 @@ pub const Extra = struct {
/// Count of relocations belonging to this atom.
unwind_count: u32 = 0,

/// Index of the leader atom for this literal.
literal_leader: u32 = 0,
/// Index into LiteralPool entry for this atom.
literal_index: u32 = 0,
};

const aarch64 = @import("../aarch64.zig");
Expand Down
25 changes: 11 additions & 14 deletions src/MachO/InternalObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,9 @@ pub fn resolveLiterals(self: InternalObject, lp: *MachO.LiteralPool, macho_file:
const res = try lp.insert(gpa, header.type(), data);
if (!res.found_existing) {
res.atom.* = atom_index;
continue;
}
atom.flags.literal_dedup = true;
try atom.addExtra(.{ .literal_leader = res.atom.* }, macho_file);
atom.flags.literal_pool = true;
try atom.addExtra(.{ .literal_index = res.index }, macho_file);
} else if (Object.isPtrLiteral(header)) {
const atom = macho_file.getAtom(atom_index).?;
const relocs = atom.getRelocs(macho_file);
Expand All @@ -142,20 +141,18 @@ pub fn resolveLiterals(self: InternalObject, lp: *MachO.LiteralPool, macho_file:
buffer.clearRetainingCapacity();
if (!res.found_existing) {
res.atom.* = atom_index;
continue;
}
atom.flags.literal_dedup = true;
try atom.addExtra(.{ .literal_leader = res.atom.* }, macho_file);
atom.flags.literal_pool = true;
try atom.addExtra(.{ .literal_index = res.index }, macho_file);
}
}
}

pub fn dedupLiterals(self: InternalObject, macho_file: *MachO) void {
pub fn dedupLiterals(self: InternalObject, lp: MachO.LiteralPool, macho_file: *MachO) void {
for (self.atoms.items) |atom_index| {
const atom = macho_file.getAtom(atom_index) orelse continue;
if (!atom.flags.alive) continue;
if (!atom.flags.relocs) continue;
if (atom.flags.literal_dedup) continue;

const relocs = blk: {
const extra = atom.getExtra(macho_file).?;
Expand All @@ -165,15 +162,15 @@ pub fn dedupLiterals(self: InternalObject, macho_file: *MachO) void {
for (relocs) |*rel| switch (rel.tag) {
.local => {
const target = macho_file.getAtom(rel.target).?;
if (target.flags.literal_dedup) {
rel.target = target.getExtra(macho_file).?.literal_leader;
if (target.getLiteralPoolIndex(macho_file)) |lp_index| {
rel.target = lp.values.items[lp_index];
}
},
.@"extern" => {
const target_sym = rel.getTargetSymbol(macho_file);
if (target_sym.getAtom(macho_file)) |target_atom| {
if (target_atom.flags.literal_dedup) {
target_sym.atom = target_atom.getExtra(macho_file).?.literal_leader;
if (target_atom.getLiteralPoolIndex(macho_file)) |lp_index| {
target_sym.atom = lp.values.items[lp_index];
}
}
},
Expand All @@ -185,8 +182,8 @@ pub fn dedupLiterals(self: InternalObject, macho_file: *MachO) void {
if (!sym.flags.objc_stubs) continue;
var extra = sym.getExtra(macho_file).?;
const atom = macho_file.getAtom(extra.objc_selrefs).?;
if (atom.flags.literal_dedup) {
extra.objc_selrefs = atom.getExtra(macho_file).?.literal_leader;
if (atom.getLiteralPoolIndex(macho_file)) |lp_index| {
extra.objc_selrefs = lp.values.items[lp_index];
sym.setExtra(extra, macho_file);
}
}
Expand Down
21 changes: 9 additions & 12 deletions src/MachO/Object.zig
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
const res = try lp.insert(gpa, header.type(), atom_data);
if (!res.found_existing) {
res.atom.* = sub.atom;
continue;
}
atom.flags.literal_dedup = true;
try atom.addExtra(.{ .literal_leader = res.atom.* }, macho_file);
atom.flags.literal_pool = true;
try atom.addExtra(.{ .literal_index = res.index }, macho_file);
}
} else if (isPtrLiteral(header)) {
for (subs.items) |sub| {
Expand All @@ -555,21 +554,19 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
buffer.clearRetainingCapacity();
if (!res.found_existing) {
res.atom.* = sub.atom;
continue;
}
atom.flags.literal_dedup = true;
try atom.addExtra(.{ .literal_leader = res.atom.* }, macho_file);
atom.flags.literal_pool = true;
try atom.addExtra(.{ .literal_index = res.index }, macho_file);
}
}
}
}

pub fn dedupLiterals(self: Object, macho_file: *MachO) void {
pub fn dedupLiterals(self: Object, lp: MachO.LiteralPool, macho_file: *MachO) void {
for (self.atoms.items) |atom_index| {
const atom = macho_file.getAtom(atom_index) orelse continue;
if (!atom.flags.alive) continue;
if (!atom.flags.relocs) continue;
if (atom.flags.literal_dedup) continue;

const relocs = blk: {
const extra = atom.getExtra(macho_file).?;
Expand All @@ -579,15 +576,15 @@ pub fn dedupLiterals(self: Object, macho_file: *MachO) void {
for (relocs) |*rel| switch (rel.tag) {
.local => {
const target = macho_file.getAtom(rel.target).?;
if (target.flags.literal_dedup) {
rel.target = target.getExtra(macho_file).?.literal_leader;
if (target.getLiteralPoolIndex(macho_file)) |lp_index| {
rel.target = lp.values.items[lp_index];
}
},
.@"extern" => {
const target_sym = rel.getTargetSymbol(macho_file);
if (target_sym.getAtom(macho_file)) |target_atom| {
if (target_atom.flags.literal_dedup) {
target_sym.atom = target_atom.getExtra(macho_file).?.literal_leader;
if (target_atom.getLiteralPoolIndex(macho_file)) |lp_index| {
target_sym.atom = lp.values.items[lp_index];
}
}
},
Expand Down

0 comments on commit 1d974fb

Please sign in to comment.