diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-06-29 10:25:50 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-06-29 11:21:44 +0200 |
| commit | 069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5 (patch) | |
| tree | af4091c3d707ac5b6cdaf0b375712ccaf05ea30c /src/link | |
| parent | 75a13a456b2cec9a81b9dabf54014f0e2a072c67 (diff) | |
| download | zig-069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5.tar.gz zig-069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5.zip | |
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)
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/MachO/Trie.zig | 5 | ||||
| -rw-r--r-- | 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(); |
