From 069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 29 Jun 2021 10:25:50 +0200 Subject: [PATCH] zld: put all global symbols in the export trie * sort the symbols by name to optimise the export trie first * insert only symbols with global linkage (private exts or weak should not make the cut) --- src/link/MachO/Trie.zig | 5 +++-- src/link/MachO/Zld.zig | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/link/MachO/Trie.zig b/src/link/MachO/Trie.zig index 9ef1e486e1..8aa2262bff 100644 --- a/src/link/MachO/Trie.zig +++ b/src/link/MachO/Trie.zig @@ -334,8 +334,9 @@ pub fn finalize(self: *Trie) !void { self.ordered_nodes.shrinkRetainingCapacity(0); try self.ordered_nodes.ensureCapacity(self.allocator, self.node_count); - const Fifo = std.fifo.LinearFifo(*Node, .{ .Static = std.math.maxInt(u8) }); - var fifo = Fifo.init(); + var fifo = std.fifo.LinearFifo(*Node, .Dynamic).init(self.allocator); + defer fifo.deinit(); + try fifo.writeItem(self.root.?); while (fifo.readItem()) |next| { diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 59c09aacef..afb562920d 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -2660,17 +2660,40 @@ fn writeExportInfo(self: *Zld) !void { defer trie.deinit(); const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; + const base_address = text_segment.inner.vmaddr; - // TODO export items for dylibs - const sym = self.globals.get("_main") orelse return error.MissingMainEntrypoint; - const reg = sym.cast(Symbol.Regular) orelse unreachable; - assert(reg.address >= text_segment.inner.vmaddr); + // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER. + log.debug("writing export trie", .{}); - try trie.put(.{ - .name = sym.name, - .vmaddr_offset = reg.address - text_segment.inner.vmaddr, - .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, - }); + const Sorter = struct { + fn lessThan(_: void, a: []const u8, b: []const u8) bool { + return mem.lessThan(u8, a, b); + } + }; + + var sorted_globals = std.ArrayList([]const u8).init(self.allocator); + defer sorted_globals.deinit(); + + for (self.globals.values()) |sym| { + const reg = sym.cast(Symbol.Regular) orelse continue; + if (reg.linkage != .global) continue; + try sorted_globals.append(sym.name); + } + + std.sort.sort([]const u8, sorted_globals.items, {}, Sorter.lessThan); + + for (sorted_globals.items) |sym_name| { + const sym = self.globals.get(sym_name) orelse unreachable; + const reg = sym.cast(Symbol.Regular) orelse unreachable; + + log.debug(" | putting '{s}' defined at 0x{x}", .{ reg.base.name, reg.address }); + + try trie.put(.{ + .name = sym.name, + .vmaddr_offset = reg.address - base_address, + .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, + }); + } try trie.finalize();