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 {...@@ -3289,9 +3289,9 @@ fn setEntryPoint(self: *MachO) !void {
3289 if (self.base.options.output_mode != .Exe) return;3289 if (self.base.options.output_mode != .Exe) return;
32903290
3291 const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment;3291 const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment;
3292 const entry_name = self.base.options.entry orelse "_main";3292 const global = self.getEntryPoint() orelse {
3293 const global = self.globals.get(entry_name) orelse {3293 const name = self.base.options.entry orelse "_main";
3294 log.err("entrypoint '{s}' not found", .{entry_name});3294 log.err("entrypoint '{s}' not found", .{name});
3295 return error.MissingMainEntrypoint;3295 return error.MissingMainEntrypoint;
3296 };3296 };
3297 const sym = self.getSymbol(global);3297 const sym = self.getSymbol(global);
...@@ -5492,15 +5492,27 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void {...@@ -5492,15 +5492,27 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void {
54925492
5493 const gpa = self.base.allocator;5493 const gpa = self.base.allocator;
54945494
5495 // Add all exports as GC roots5495 if (self.base.options.output_mode == .Exe) {
5496 for (self.globals.values()) |global| {5496 // Add entrypoint as GC root
5497 const sym = self.getSymbol(global);5497 if (self.getEntryPoint()) |global| {
5498 if (!sym.sect()) continue;5498 if (self.getAtomForSymbol(global)) |gc_root| {
5499 const gc_root = self.getAtomForSymbol(global) orelse {5499 _ = try gc_roots.getOrPut(gc_root);
5500 log.debug("skipping {s}", .{self.getSymbolName(global)});5500 } else {
5501 continue;5501 log.debug("skipping {s}", .{self.getSymbolName(global)});
5502 };5502 }
5503 _ = try gc_roots.getOrPut(gc_root);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 }
5504 }5516 }
55055517
5506 // Add any atom targeting an import as GC root5518 // Add any atom targeting an import as GC root
...@@ -5836,19 +5848,37 @@ fn writeDyldInfoData(self: *MachO) !void {...@@ -5836,19 +5848,37 @@ fn writeDyldInfoData(self: *MachO) !void {
5836 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].segment;5848 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].segment;
5837 const base_address = text_segment.inner.vmaddr;5849 const base_address = text_segment.inner.vmaddr;
58385850
5839 for (self.globals.values()) |global| {5851 if (self.base.options.output_mode == .Exe) {
5840 const sym = self.getSymbol(global);5852 for (&[_]SymbolWithLoc{
5841 if (sym.undf()) continue;5853 self.getEntryPoint().?, // We would already errored out if no entrypoint was found.
5842 if (!sym.ext()) continue;5854 self.globals.get("__mh_execute_header").?,
5843 if (sym.n_desc == N_DESC_GCED) continue;5855 }) |global| {
5844 const sym_name = self.getSymbolName(global);5856 const sym = self.getSymbol(global);
5845 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });5857 const sym_name = self.getSymbolName(global);
58465858 log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value });
5847 try trie.put(gpa, .{5859 try trie.put(gpa, .{
5848 .name = sym_name,5860 .name = sym_name,
5849 .vmaddr_offset = sym.n_value - base_address,5861 .vmaddr_offset = sym.n_value - base_address,
5850 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,5862 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
5851 });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 }
5852 }5882 }
58535883
5854 try trie.finalize(gpa);5884 try trie.finalize(gpa);
...@@ -6602,6 +6632,13 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom...@@ -6602,6 +6632,13 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom
6602 return self.tlv_ptr_entries.items[tlv_ptr_index].atom;6632 return self.tlv_ptr_entries.items[tlv_ptr_index].atom;
6603}6633}
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
6605pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize {6642pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize {
6606 if (!@hasDecl(@TypeOf(predicate), "predicate"))6643 if (!@hasDecl(@TypeOf(predicate), "predicate"))
6607 @compileError("Predicate is required to define fn predicate(@This(), T) bool");6644 @compileError("Predicate is required to define fn predicate(@This(), T) bool");