authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-07-18 00:25:28+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-07-22 16:58:21+02:00
log2dfc78dc0369052033c8469e00bf599e12e73f52
treeea9d99fa366cc2ac5c14e22257cbbb3ad83201b2
parent0f1b5d45bc9df17fab5c42c22e816797b555be5a

macho: limit export info to entrypoint and mh symbol when executable


1 files changed, 62 insertions(+), 25 deletions(-)

src/link/MachO.zig+62-25
......@@ -3289,9 +3289,9 @@ fn setEntryPoint(self: *MachO) !void {
32893289 if (self.base.options.output_mode != .Exe) return;
32903290
32913291 const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment;
3292 const entry_name = self.base.options.entry orelse "_main";
3293 const global = self.globals.get(entry_name) orelse {
3294 log.err("entrypoint '{s}' not found", .{entry_name});
3292 const global = self.getEntryPoint() orelse {
3293 const name = self.base.options.entry orelse "_main";
3294 log.err("entrypoint '{s}' not found", .{name});
32953295 return error.MissingMainEntrypoint;
32963296 };
32973297 const sym = self.getSymbol(global);
......@@ -5492,15 +5492,27 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void {
54925492
54935493 const gpa = self.base.allocator;
54945494
5495 // Add all exports as GC roots
5496 for (self.globals.values()) |global| {
5497 const sym = self.getSymbol(global);
5498 if (!sym.sect()) continue;
5499 const gc_root = self.getAtomForSymbol(global) orelse {
5500 log.debug("skipping {s}", .{self.getSymbolName(global)});
5501 continue;
5502 };
5503 _ = try gc_roots.getOrPut(gc_root);
5495 if (self.base.options.output_mode == .Exe) {
5496 // Add entrypoint as GC root
5497 if (self.getEntryPoint()) |global| {
5498 if (self.getAtomForSymbol(global)) |gc_root| {
5499 _ = try gc_roots.getOrPut(gc_root);
5500 } else {
5501 log.debug("skipping {s}", .{self.getSymbolName(global)});
5502 }
5503 }
5504 } else {
5505 assert(self.base.options.output_mode == .Lib);
5506 // Add exports as GC roots
5507 for (self.globals.values()) |global| {
5508 const sym = self.getSymbol(global);
5509 if (!sym.sect()) continue;
5510 const gc_root = self.getAtomForSymbol(global) orelse {
5511 log.debug("skipping {s}", .{self.getSymbolName(global)});
5512 continue;
5513 };
5514 _ = try gc_roots.getOrPut(gc_root);
5515 }
55045516 }
55055517
55065518 // Add any atom targeting an import as GC root
......@@ -5836,19 +5848,37 @@ fn writeDyldInfoData(self: *MachO) !void {
58365848 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].segment;
58375849 const base_address = text_segment.inner.vmaddr;
58385850
5839 for (self.globals.values()) |global| {
5840 const sym = self.getSymbol(global);
5841 if (sym.undf()) continue;
5842 if (!sym.ext()) continue;
5843 if (sym.n_desc == N_DESC_GCED) continue;
5844 const sym_name = self.getSymbolName(global);
5845 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
5846
5847 try trie.put(gpa, .{
5848 .name = sym_name,
5849 .vmaddr_offset = sym.n_value - base_address,
5850 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
5851 });
5851 if (self.base.options.output_mode == .Exe) {
5852 for (&[_]SymbolWithLoc{
5853 self.getEntryPoint().?, // We would already errored out if no entrypoint was found.
5854 self.globals.get("__mh_execute_header").?,
5855 }) |global| {
5856 const sym = self.getSymbol(global);
5857 const sym_name = self.getSymbolName(global);
5858 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
5859 try trie.put(gpa, .{
5860 .name = sym_name,
5861 .vmaddr_offset = sym.n_value - base_address,
5862 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
5863 });
5864 }
5865 } else {
5866 assert(self.base.options.output_mode == .Lib);
5867 for (self.globals.values()) |global| {
5868 const sym = self.getSymbol(global);
5869
5870 if (sym.undf()) continue;
5871 if (!sym.ext()) continue;
5872 if (sym.n_desc == N_DESC_GCED) continue;
5873
5874 const sym_name = self.getSymbolName(global);
5875 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
5876 try trie.put(gpa, .{
5877 .name = sym_name,
5878 .vmaddr_offset = sym.n_value - base_address,
5879 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
5880 });
5881 }
58525882 }
58535883
58545884 try trie.finalize(gpa);
......@@ -6602,6 +6632,13 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom
66026632 return self.tlv_ptr_entries.items[tlv_ptr_index].atom;
66036633}
66046634
6635/// Returns symbol location corresponding to the set entrypoint.
6636/// Asserts output mode is executable.
6637pub fn getEntryPoint(self: MachO) ?SymbolWithLoc {
6638 const entry_name = self.base.options.entry orelse "_main";
6639 return self.globals.get(entry_name);
6640}
6641
66056642pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize {
66066643 if (!@hasDecl(@TypeOf(predicate), "predicate"))
66076644 @compileError("Predicate is required to define fn predicate(@This(), T) bool");