aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-06-29 10:25:50 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-06-29 11:21:44 +0200
commit069fcf1c95dafa7c711b4f5c7d1041eaab54a9e5 (patch)
treeaf4091c3d707ac5b6cdaf0b375712ccaf05ea30c /src/link
parent75a13a456b2cec9a81b9dabf54014f0e2a072c67 (diff)
downloadzig-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.zig5
-rw-r--r--src/link/MachO/Zld.zig41
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();