authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-29 10:25:50+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-29 11:21:44+02:00
log069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5
treeaf4091c3d707ac5b6cdaf0b375712ccaf05ea30c
parent75a13a456b2cec9a81b9dabf54014f0e2a072c67

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)

2 files changed, 35 insertions(+), 11 deletions(-)

src/link/MachO/Trie.zig+3-2
......@@ -334,8 +334,9 @@ pub fn finalize(self: *Trie) !void {
334334 self.ordered_nodes.shrinkRetainingCapacity(0);
335335 try self.ordered_nodes.ensureCapacity(self.allocator, self.node_count);
336336
337 const Fifo = std.fifo.LinearFifo(*Node, .{ .Static = std.math.maxInt(u8) });
338 var fifo = Fifo.init();
337 var fifo = std.fifo.LinearFifo(*Node, .Dynamic).init(self.allocator);
338 defer fifo.deinit();
339
339340 try fifo.writeItem(self.root.?);
340341
341342 while (fifo.readItem()) |next| {
src/link/MachO/Zld.zig+32-9
......@@ -2660,17 +2660,40 @@ fn writeExportInfo(self: *Zld) !void {
26602660 defer trie.deinit();
26612661
26622662 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2663 const base_address = text_segment.inner.vmaddr;
26632664
2664 // TODO export items for dylibs
2665 const sym = self.globals.get("_main") orelse return error.MissingMainEntrypoint;
2666 const reg = sym.cast(Symbol.Regular) orelse unreachable;
2667 assert(reg.address >= text_segment.inner.vmaddr);
2665 // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER.
2666 log.debug("writing export trie", .{});
26682667
2669 try trie.put(.{
2670 .name = sym.name,
2671 .vmaddr_offset = reg.address - text_segment.inner.vmaddr,
2672 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
2673 });
2668 const Sorter = struct {
2669 fn lessThan(_: void, a: []const u8, b: []const u8) bool {
2670 return mem.lessThan(u8, a, b);
2671 }
2672 };
2673
2674 var sorted_globals = std.ArrayList([]const u8).init(self.allocator);
2675 defer sorted_globals.deinit();
2676
2677 for (self.globals.values()) |sym| {
2678 const reg = sym.cast(Symbol.Regular) orelse continue;
2679 if (reg.linkage != .global) continue;
2680 try sorted_globals.append(sym.name);
2681 }
2682
2683 std.sort.sort([]const u8, sorted_globals.items, {}, Sorter.lessThan);
2684
2685 for (sorted_globals.items) |sym_name| {
2686 const sym = self.globals.get(sym_name) orelse unreachable;
2687 const reg = sym.cast(Symbol.Regular) orelse unreachable;
2688
2689 log.debug(" | putting '{s}' defined at 0x{x}", .{ reg.base.name, reg.address });
2690
2691 try trie.put(.{
2692 .name = sym.name,
2693 .vmaddr_offset = reg.address - base_address,
2694 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
2695 });
2696 }
26742697
26752698 try trie.finalize();
26762699