mirror of
https://github.com/ziglang/zig.git
synced 2026-01-04 04:25:05 +00:00
macho: refactor markExports, markImportsExports and claimUnresolved
This commit is contained in:
parent
352e27c55c
commit
bdbb1dbe15
@ -379,6 +379,10 @@ pub fn deinit(self: *MachO) void {
|
||||
}
|
||||
|
||||
pub fn flush(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
|
||||
// TODO: I think this is just a temp and can be removed once we can emit static archives
|
||||
if (self.base.isStaticLib() and build_options.have_llvm) {
|
||||
return self.base.linkAsArchive(arena, prog_node);
|
||||
}
|
||||
try self.flushModule(arena, prog_node);
|
||||
}
|
||||
|
||||
@ -391,6 +395,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
|
||||
|
||||
if (self.llvm_object) |llvm_object| {
|
||||
try self.base.emitLlvmObject(arena, llvm_object, prog_node);
|
||||
// TODO: I think this is just a temp and can be removed once we can emit static archives
|
||||
if (self.base.isStaticLib() and build_options.have_llvm) return;
|
||||
}
|
||||
|
||||
var sub_prog_node = prog_node.start("MachO Flush", 0);
|
||||
@ -571,7 +577,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
|
||||
},
|
||||
};
|
||||
|
||||
try self.markImportsAndExports();
|
||||
self.markImportsAndExports();
|
||||
self.deadStripDylibs();
|
||||
|
||||
for (self.dylibs.items, 1..) |index, ord| {
|
||||
@ -1509,46 +1515,11 @@ fn createObjcSections(self: *MachO) !void {
|
||||
}
|
||||
|
||||
fn claimUnresolved(self: *MachO) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
|
||||
var objects = try std.ArrayList(File.Index).initCapacity(gpa, self.objects.items.len + 1);
|
||||
defer objects.deinit();
|
||||
if (self.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
|
||||
objects.appendSliceAssumeCapacity(self.objects.items);
|
||||
|
||||
for (objects.items) |index| {
|
||||
const file = self.getFile(index).?;
|
||||
|
||||
for (file.getSymbols(), 0..) |sym_index, i| {
|
||||
const nlist_idx = @as(Symbol.Index, @intCast(i));
|
||||
const nlist = switch (file) {
|
||||
.object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
.zig_object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
else => unreachable,
|
||||
};
|
||||
if (!nlist.ext()) continue;
|
||||
if (!nlist.undf()) continue;
|
||||
|
||||
const sym = self.getSymbol(sym_index);
|
||||
if (sym.getFile(self) != null) continue;
|
||||
|
||||
const is_import = switch (self.undefined_treatment) {
|
||||
.@"error" => false,
|
||||
.warn, .suppress => nlist.weakRef(),
|
||||
.dynamic_lookup => true,
|
||||
};
|
||||
if (is_import) {
|
||||
sym.value = 0;
|
||||
sym.atom = 0;
|
||||
sym.nlist_idx = 0;
|
||||
sym.file = self.internal_object.?;
|
||||
sym.flags.weak = false;
|
||||
sym.flags.weak_ref = nlist.weakRef();
|
||||
sym.flags.import = is_import;
|
||||
sym.visibility = .global;
|
||||
try self.getInternalObject().?.symbols.append(self.base.comp.gpa, sym_index);
|
||||
}
|
||||
}
|
||||
if (self.getZigObject()) |zo| {
|
||||
try zo.asFile().claimUnresolved(self);
|
||||
}
|
||||
for (self.objects.items) |index| {
|
||||
try self.getFile(index).?.claimUnresolved(self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1574,26 +1545,12 @@ fn checkDuplicates(self: *MachO) !void {
|
||||
try self.reportDuplicates(dupes);
|
||||
}
|
||||
|
||||
fn markImportsAndExports(self: *MachO) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
var objects = try std.ArrayList(File.Index).initCapacity(gpa, self.objects.items.len + 1);
|
||||
defer objects.deinit();
|
||||
if (self.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
|
||||
objects.appendSliceAssumeCapacity(self.objects.items);
|
||||
|
||||
for (objects.items) |index| {
|
||||
for (self.getFile(index).?.getSymbols()) |sym_index| {
|
||||
const sym = self.getSymbol(sym_index);
|
||||
const file = sym.getFile(self) orelse continue;
|
||||
if (sym.visibility != .global) continue;
|
||||
if (file == .dylib and !sym.flags.abs) {
|
||||
sym.flags.import = true;
|
||||
continue;
|
||||
}
|
||||
if (file.getIndex() == index) {
|
||||
sym.flags.@"export" = true;
|
||||
}
|
||||
}
|
||||
fn markImportsAndExports(self: *MachO) void {
|
||||
if (self.getZigObject()) |zo| {
|
||||
zo.asFile().markImportsExports(self);
|
||||
}
|
||||
for (self.objects.items) |index| {
|
||||
self.getFile(index).?.markImportsExports(self);
|
||||
}
|
||||
|
||||
for (self.undefined_symbols.items) |index| {
|
||||
|
||||
@ -144,8 +144,32 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, handle_index:
|
||||
}
|
||||
|
||||
pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
|
||||
_ = comp;
|
||||
_ = module_obj_path;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
|
||||
defer positionals.deinit();
|
||||
|
||||
try positionals.ensureUnusedCapacity(comp.objects.len);
|
||||
positionals.appendSliceAssumeCapacity(comp.objects);
|
||||
|
||||
for (comp.c_object_table.keys()) |key| {
|
||||
try positionals.append(.{ .path = key.status.success.object_path });
|
||||
}
|
||||
|
||||
if (module_obj_path) |path| try positionals.append(.{ .path = path });
|
||||
|
||||
for (positionals.items) |obj| {
|
||||
// TODO: parse for archive meaning don't unpack objects
|
||||
_ = obj;
|
||||
}
|
||||
|
||||
if (comp.link_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// First, we flush relocatable object file generated with our backends.
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
zo.resolveSymbols(macho_file);
|
||||
zo.asFile().claimUnresolvedRelocatable(macho_file);
|
||||
}
|
||||
|
||||
var err = try macho_file.addErrorWithNotes(0);
|
||||
try err.addMsg(macho_file, "TODO implement flushStaticLib", .{});
|
||||
@ -158,6 +182,7 @@ const link = @import("../../link.zig");
|
||||
const log = std.log.scoped(.link);
|
||||
const macho = std.macho;
|
||||
const mem = std.mem;
|
||||
const relocatable = @import("relocatable.zig");
|
||||
const std = @import("std");
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
@ -44,6 +44,97 @@ pub const File = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn claimUnresolved(file: File, macho_file: *MachO) error{OutOfMemory}!void {
|
||||
assert(file == .object or file == .zig_object);
|
||||
|
||||
for (file.getSymbols(), 0..) |sym_index, i| {
|
||||
const nlist_idx = @as(Symbol.Index, @intCast(i));
|
||||
const nlist = switch (file) {
|
||||
.object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
.zig_object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
else => unreachable,
|
||||
};
|
||||
if (!nlist.ext()) continue;
|
||||
if (!nlist.undf()) continue;
|
||||
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
if (sym.getFile(macho_file) != null) continue;
|
||||
|
||||
const is_import = switch (macho_file.undefined_treatment) {
|
||||
.@"error" => false,
|
||||
.warn, .suppress => nlist.weakRef(),
|
||||
.dynamic_lookup => true,
|
||||
};
|
||||
if (is_import) {
|
||||
sym.value = 0;
|
||||
sym.atom = 0;
|
||||
sym.nlist_idx = 0;
|
||||
sym.file = macho_file.internal_object.?;
|
||||
sym.flags.weak = false;
|
||||
sym.flags.weak_ref = nlist.weakRef();
|
||||
sym.flags.import = is_import;
|
||||
sym.visibility = .global;
|
||||
try macho_file.getInternalObject().?.symbols.append(macho_file.base.comp.gpa, sym_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn claimUnresolvedRelocatable(file: File, macho_file: *MachO) void {
|
||||
assert(file == .object or file == .zig_object);
|
||||
|
||||
for (file.getSymbols(), 0..) |sym_index, i| {
|
||||
const nlist_idx = @as(Symbol.Index, @intCast(i));
|
||||
const nlist = switch (file) {
|
||||
.object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
.zig_object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
else => unreachable,
|
||||
};
|
||||
if (!nlist.ext()) continue;
|
||||
if (!nlist.undf()) continue;
|
||||
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
if (sym.getFile(macho_file) != null) continue;
|
||||
|
||||
sym.value = 0;
|
||||
sym.atom = 0;
|
||||
sym.nlist_idx = nlist_idx;
|
||||
sym.file = file.getIndex();
|
||||
sym.flags.weak_ref = nlist.weakRef();
|
||||
sym.flags.import = true;
|
||||
sym.visibility = .global;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn markImportsExports(file: File, macho_file: *MachO) void {
|
||||
assert(file == .object or file == .zig_object);
|
||||
|
||||
for (file.getSymbols()) |sym_index| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const other_file = sym.getFile(macho_file) orelse continue;
|
||||
if (sym.visibility != .global) continue;
|
||||
if (other_file == .dylib and !sym.flags.abs) {
|
||||
sym.flags.import = true;
|
||||
continue;
|
||||
}
|
||||
if (other_file.getIndex() == file.getIndex()) {
|
||||
sym.flags.@"export" = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn markExportsRelocatable(file: File, macho_file: *MachO) void {
|
||||
assert(file == .object or file == .zig_object);
|
||||
|
||||
for (file.getSymbols()) |sym_index| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const other_file = sym.getFile(macho_file) orelse continue;
|
||||
if (sym.visibility != .global) continue;
|
||||
if (other_file.getIndex() == file.getIndex()) {
|
||||
sym.flags.@"export" = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Encodes symbol rank so that the following ordering applies:
|
||||
/// * strong in object
|
||||
/// * weak in object
|
||||
@ -110,6 +201,7 @@ pub const File = union(enum) {
|
||||
pub const HandleIndex = Index;
|
||||
};
|
||||
|
||||
const assert = std.debug.assert;
|
||||
const macho = std.macho;
|
||||
const std = @import("std");
|
||||
|
||||
|
||||
@ -46,8 +46,8 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u
|
||||
|
||||
try macho_file.addUndefinedGlobals();
|
||||
try macho_file.resolveSymbols();
|
||||
try markExports(macho_file);
|
||||
try claimUnresolved(macho_file);
|
||||
markExports(macho_file);
|
||||
claimUnresolved(macho_file);
|
||||
try initOutputSections(macho_file);
|
||||
try macho_file.sortSections();
|
||||
try macho_file.addAtomsToSections();
|
||||
@ -86,54 +86,21 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u
|
||||
try writeHeader(macho_file, ncmds, sizeofcmds);
|
||||
}
|
||||
|
||||
fn markExports(macho_file: *MachO) error{OutOfMemory}!void {
|
||||
var objects = try std.ArrayList(File.Index).initCapacity(macho_file.base.comp.gpa, macho_file.objects.items.len + 1);
|
||||
defer objects.deinit();
|
||||
if (macho_file.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
|
||||
objects.appendSliceAssumeCapacity(macho_file.objects.items);
|
||||
|
||||
for (objects.items) |index| {
|
||||
for (macho_file.getFile(index).?.getSymbols()) |sym_index| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const file = sym.getFile(macho_file) orelse continue;
|
||||
if (sym.visibility != .global) continue;
|
||||
if (file.getIndex() == index) {
|
||||
sym.flags.@"export" = true;
|
||||
}
|
||||
}
|
||||
fn markExports(macho_file: *MachO) void {
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
zo.asFile().markExportsRelocatable(macho_file);
|
||||
}
|
||||
for (macho_file.objects.items) |index| {
|
||||
macho_file.getFile(index).?.markExportsRelocatable(macho_file);
|
||||
}
|
||||
}
|
||||
|
||||
fn claimUnresolved(macho_file: *MachO) error{OutOfMemory}!void {
|
||||
var objects = try std.ArrayList(File.Index).initCapacity(macho_file.base.comp.gpa, macho_file.objects.items.len + 1);
|
||||
defer objects.deinit();
|
||||
if (macho_file.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
|
||||
objects.appendSliceAssumeCapacity(macho_file.objects.items);
|
||||
|
||||
for (objects.items) |index| {
|
||||
const file = macho_file.getFile(index).?;
|
||||
|
||||
for (file.getSymbols(), 0..) |sym_index, i| {
|
||||
const nlist_idx = @as(Symbol.Index, @intCast(i));
|
||||
const nlist = switch (file) {
|
||||
.object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
.zig_object => |x| x.symtab.items(.nlist)[nlist_idx],
|
||||
else => unreachable,
|
||||
};
|
||||
if (!nlist.ext()) continue;
|
||||
if (!nlist.undf()) continue;
|
||||
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
if (sym.getFile(macho_file) != null) continue;
|
||||
|
||||
sym.value = 0;
|
||||
sym.atom = 0;
|
||||
sym.nlist_idx = nlist_idx;
|
||||
sym.file = index;
|
||||
sym.flags.weak_ref = nlist.weakRef();
|
||||
sym.flags.import = true;
|
||||
sym.visibility = .global;
|
||||
}
|
||||
pub fn claimUnresolved(macho_file: *MachO) void {
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
zo.asFile().claimUnresolvedRelocatable(macho_file);
|
||||
}
|
||||
for (macho_file.objects.items) |index| {
|
||||
macho_file.getFile(index).?.claimUnresolvedRelocatable(macho_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user