Skip to content

Commit

Permalink
macho: mark imports and exports
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Nov 17, 2023
1 parent 6c6bf35 commit a6c4a5d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 31 deletions.
35 changes: 35 additions & 0 deletions src/MachO.zig
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ pub fn flush(self: *MachO) !void {

try self.resolveSymbols();

// TODO kill __eh_frame atoms
// TODO convert tentative definitions

try self.markImportsAndExports();

state_log.debug("{}", .{self.dumpState()});

// if (self.options.dead_strip) {
Expand Down Expand Up @@ -1106,6 +1111,36 @@ fn markLive(self: *MachO) void {
}
}

fn markImportsAndExports(self: *MachO) !void {
if (!self.options.dylib)
for (self.dylibs.items) |index| {
for (self.getFile(index).?.getGlobals()) |global_index| {
const global = self.getSymbol(global_index);
const file = global.getFile(self) orelse continue;
if (file != .dylib and !global.getNlist(self).pext()) global.flags.@"export" = true;
}
};

for (self.objects.items) |index| {
for (self.getFile(index).?.getGlobals()) |global_index| {
const global = self.getSymbol(global_index);
const file = global.getFile(self) orelse continue;
if (global.getNlist(self).pext()) continue;
if (file == .dylib and !global.isAbs(self)) {
global.flags.import = true;
continue;
}
if (file.getIndex() == index) {
global.flags.@"export" = true;

if (self.options.dylib) {
global.flags.import = true;
}
}
}
}
}

pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 {
const segname = sect.segName();
const sectname = sect.sectName();
Expand Down
26 changes: 13 additions & 13 deletions src/MachO/Dylib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ fn addObjCGlobal(self: *Dylib, comptime prefix: []const u8, name: []const u8, ma
fn addGlobal(self: *Dylib, name: []const u8, macho_file: *MachO) !Symbol.Index {
const gpa = macho_file.base.allocator;
const index = @as(Symbol.Index, @intCast(self.symtab.items.len));
const sym = try self.symtab.addOne(gpa);
sym.* = MachO.null_sym;
sym.n_strx = try self.insertString(gpa, name);
sym.n_type = macho.N_EXT | macho.N_SECT;
const nlist = try self.symtab.addOne(gpa);
nlist.* = MachO.null_sym;
nlist.n_strx = try self.insertString(gpa, name);
nlist.n_type = macho.N_EXT | macho.N_SECT;
return index;
}

Expand All @@ -285,30 +285,30 @@ fn initSymbols(self: *Dylib, macho_file: *MachO) !void {

pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) void {
for (self.getGlobals(), 0..) |index, i| {
const sym_idx = @as(Symbol.Index, @intCast(i));
const this_sym = self.symtab.items[sym_idx];
const nlist_idx = @as(Symbol.Index, @intCast(i));
const nlist = self.symtab.items[nlist_idx];

if (this_sym.undf()) continue;
if (nlist.undf()) continue;

const global = macho_file.getSymbol(index);
if (self.asFile().getSymbolRank(this_sym, false) < global.getSymbolRank(macho_file)) {
global.value = this_sym.n_value;
if (self.asFile().getSymbolRank(nlist, false) < global.getSymbolRank(macho_file)) {
global.value = nlist.n_value;
global.atom = 0;
global.sym_idx = sym_idx;
global.nlist_idx = nlist_idx;
global.file = self.index;
}
}
}

pub fn markLive(self: *Dylib, macho_file: *MachO) void {
for (self.symbols.items, 0..) |index, i| {
const sym = self.symtab.items[i];
if (!sym.undf()) continue;
const nlist = self.symtab.items[i];
if (!nlist.undf()) continue;

const global = macho_file.getSymbol(index);
const file = global.getFile(macho_file) orelse continue;
const should_drop = switch (file) {
.dylib => |sh| !sh.needed and (sym.weakDef() or sym.pext()),
.dylib => |sh| !sh.needed and (nlist.weakDef() or nlist.pext()),
else => false,
};
if (!should_drop and !file.isAlive()) {
Expand Down
36 changes: 18 additions & 18 deletions src/MachO/Object.zig
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ fn initSymbols(self: *Object, macho_file: *MachO) !void {
symbol.* = .{
.value = local.n_value,
.name = try macho_file.string_intern.insert(gpa, name),
.sym_idx = @intCast(i),
.nlist_idx = @intCast(i),
.atom = if (local.abs()) 0 else self.atoms.items[local.n_sect - 1],
.file = self.index,
};
Expand Down Expand Up @@ -195,8 +195,8 @@ fn sortSymbols(self: *Object, allocator: Allocator) !Symbol.Index {
self.symtab.appendAssumeCapacity(symtab.items[index.index]);
}

const first_global = for (self.symtab.items, 0..) |sym, i| {
if (sym.ext()) break i;
const first_global = for (self.symtab.items, 0..) |nlist, i| {
if (nlist.ext()) break i;
} else self.symtab.items.len;
return @intCast(first_global);
}
Expand Down Expand Up @@ -226,40 +226,40 @@ fn parseRelocs(self: *Object, allocator: Allocator, sect: macho.section_64) !Ato

pub fn resolveSymbols(self: *Object, macho_file: *MachO) void {
for (self.getGlobals(), 0..) |index, i| {
const sym_idx = @as(Symbol.Index, @intCast(self.first_global + i));
const this_sym = self.symtab.items[sym_idx];
const nlist_idx = @as(Symbol.Index, @intCast(self.first_global + i));
const nlist = self.symtab.items[nlist_idx];

if (this_sym.undf()) continue;
if (!this_sym.tentative() and !this_sym.abs()) {
const atom_index = self.atoms.items[this_sym.n_sect - 1];
if (nlist.undf()) continue;
if (!nlist.tentative() and !nlist.abs()) {
const atom_index = self.atoms.items[nlist.n_sect - 1];
const atom = macho_file.getAtom(atom_index) orelse continue;
if (!atom.flags.alive) continue;
}

const global = macho_file.getSymbol(index);
if (self.asFile().getSymbolRank(this_sym, !self.alive) < global.getSymbolRank(macho_file)) {
const atom = if (this_sym.tentative() or this_sym.abs())
if (self.asFile().getSymbolRank(nlist, !self.alive) < global.getSymbolRank(macho_file)) {
const atom = if (nlist.tentative() or nlist.abs())
0
else
self.atoms.items[this_sym.n_sect - 1];
global.value = this_sym.n_value;
self.atoms.items[nlist.n_sect - 1];
global.value = nlist.n_value;
global.atom = atom;
global.sym_idx = sym_idx;
global.nlist_idx = nlist_idx;
global.file = self.index;
if (this_sym.weakDef() or this_sym.pext()) global.flags.weak = true;
if (nlist.weakDef() or nlist.pext()) global.flags.weak = true;
}
}
}

pub fn markLive(self: *Object, macho_file: *MachO) void {
for (self.getGlobals(), 0..) |index, i| {
const sym_idx = self.first_global + i;
const sym = self.symtab.items[sym_idx];
if (sym.weakDef() or sym.pext()) continue;
const nlist_idx = self.first_global + i;
const nlist = self.symtab.items[nlist_idx];
if (nlist.weakDef() or nlist.pext()) continue;

const global = macho_file.getSymbol(index);
const file = global.getFile(macho_file) orelse continue;
const should_keep = sym.undf() or (sym.tentative() and global.getSourceSymbol(macho_file).tentative());
const should_keep = nlist.undf() or (nlist.tentative() and global.getNlist(macho_file).tentative());
if (should_keep and !file.isAlive()) {
file.setAlive();
file.markLive(macho_file);
Expand Down

0 comments on commit a6c4a5d

Please sign in to comment.