aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-07-18 00:25:28 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-07-22 16:58:21 +0200
commit2dfc78dc0369052033c8469e00bf599e12e73f52 (patch)
treeea9d99fa366cc2ac5c14e22257cbbb3ad83201b2 /src
parent0f1b5d45bc9df17fab5c42c22e816797b555be5a (diff)
downloadzig-2dfc78dc0369052033c8469e00bf599e12e73f52.tar.gz
zig-2dfc78dc0369052033c8469e00bf599e12e73f52.zip
macho: limit export info to entrypoint and mh symbol when executable
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig87
1 files changed, 62 insertions, 25 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index d96dc83d42..1fb0981dc4 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -3289,9 +3289,9 @@ fn setEntryPoint(self: *MachO) !void {
if (self.base.options.output_mode != .Exe) return;
const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment;
- const entry_name = self.base.options.entry orelse "_main";
- const global = self.globals.get(entry_name) orelse {
- log.err("entrypoint '{s}' not found", .{entry_name});
+ const global = self.getEntryPoint() orelse {
+ const name = self.base.options.entry orelse "_main";
+ log.err("entrypoint '{s}' not found", .{name});
return error.MissingMainEntrypoint;
};
const sym = self.getSymbol(global);
@@ -5492,15 +5492,27 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void {
const gpa = self.base.allocator;
- // Add all exports as GC roots
- for (self.globals.values()) |global| {
- const sym = self.getSymbol(global);
- if (!sym.sect()) continue;
- const gc_root = self.getAtomForSymbol(global) orelse {
- log.debug("skipping {s}", .{self.getSymbolName(global)});
- continue;
- };
- _ = try gc_roots.getOrPut(gc_root);
+ if (self.base.options.output_mode == .Exe) {
+ // Add entrypoint as GC root
+ if (self.getEntryPoint()) |global| {
+ if (self.getAtomForSymbol(global)) |gc_root| {
+ _ = try gc_roots.getOrPut(gc_root);
+ } else {
+ log.debug("skipping {s}", .{self.getSymbolName(global)});
+ }
+ }
+ } else {
+ assert(self.base.options.output_mode == .Lib);
+ // Add exports as GC roots
+ for (self.globals.values()) |global| {
+ const sym = self.getSymbol(global);
+ if (!sym.sect()) continue;
+ const gc_root = self.getAtomForSymbol(global) orelse {
+ log.debug("skipping {s}", .{self.getSymbolName(global)});
+ continue;
+ };
+ _ = try gc_roots.getOrPut(gc_root);
+ }
}
// Add any atom targeting an import as GC root
@@ -5836,19 +5848,37 @@ fn writeDyldInfoData(self: *MachO) !void {
const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].segment;
const base_address = text_segment.inner.vmaddr;
- for (self.globals.values()) |global| {
- const sym = self.getSymbol(global);
- if (sym.undf()) continue;
- if (!sym.ext()) continue;
- if (sym.n_desc == N_DESC_GCED) continue;
- const sym_name = self.getSymbolName(global);
- log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
-
- try trie.put(gpa, .{
- .name = sym_name,
- .vmaddr_offset = sym.n_value - base_address,
- .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
- });
+ if (self.base.options.output_mode == .Exe) {
+ for (&[_]SymbolWithLoc{
+ self.getEntryPoint().?, // We would already errored out if no entrypoint was found.
+ self.globals.get("__mh_execute_header").?,
+ }) |global| {
+ const sym = self.getSymbol(global);
+ const sym_name = self.getSymbolName(global);
+ log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
+ try trie.put(gpa, .{
+ .name = sym_name,
+ .vmaddr_offset = sym.n_value - base_address,
+ .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
+ });
+ }
+ } else {
+ assert(self.base.options.output_mode == .Lib);
+ for (self.globals.values()) |global| {
+ const sym = self.getSymbol(global);
+
+ if (sym.undf()) continue;
+ if (!sym.ext()) continue;
+ if (sym.n_desc == N_DESC_GCED) continue;
+
+ const sym_name = self.getSymbolName(global);
+ log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
+ try trie.put(gpa, .{
+ .name = sym_name,
+ .vmaddr_offset = sym.n_value - base_address,
+ .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
+ });
+ }
}
try trie.finalize(gpa);
@@ -6602,6 +6632,13 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom
return self.tlv_ptr_entries.items[tlv_ptr_index].atom;
}
+/// Returns symbol location corresponding to the set entrypoint.
+/// Asserts output mode is executable.
+pub fn getEntryPoint(self: MachO) ?SymbolWithLoc {
+ const entry_name = self.base.options.entry orelse "_main";
+ return self.globals.get(entry_name);
+}
+
pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize {
if (!@hasDecl(@TypeOf(predicate), "predicate"))
@compileError("Predicate is required to define fn predicate(@This(), T) bool");