authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-25 22:48:04+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-25 22:48:04+01:00
logf1e324216d934ee6be0d8a4ab579353e2fc73bad
treedf681bbf67afab5c22e02a85759fe82bb5692d8b
parent4ce212739bf2d018a0b00fac2d7ff35d5a51c2fe

zld: parse archive's table of contents


1 files changed, 23 insertions(+), 1 deletions(-)

src/link/MachO/Archive.zig+23-1
......@@ -20,6 +20,11 @@ name: []u8,
2020
2121objects: std.ArrayListUnmanaged(Object) = .{},
2222
23/// Parsed table of contents.
24/// Each symbol name points to a list of all definition
25/// sites within the current static archive.
26toc: std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(u32)) = .{},
27
2328// Archive files start with the ARMAG identifying string. Then follows a
2429// `struct ar_hdr', and as many bytes of member file data as its `ar_size'
2530// member indicates, for each member file.
......@@ -88,6 +93,11 @@ pub fn deinit(self: *Archive) void {
8893 object.deinit();
8994 }
9095 self.objects.deinit(self.allocator);
96 for (self.toc.items()) |*entry| {
97 self.allocator.free(entry.key);
98 entry.value.deinit(self.allocator);
99 }
100 self.toc.deinit(self.allocator);
91101 self.file.close();
92102}
93103
......@@ -159,8 +169,20 @@ fn readTableOfContents(self: *Archive, reader: anytype) ![]u32 {
159169 };
160170 const object_offset = try symtab_reader.readIntLittle(u32);
161171
162 // TODO Store the table of contents for later reuse.
172 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));
173 const owned_name = try self.allocator.dupe(u8, sym_name);
174 const res = try self.toc.getOrPut(self.allocator, owned_name);
175 defer if (res.found_existing) self.allocator.free(owned_name);
176
177 if (!res.found_existing) {
178 res.entry.value = .{};
179 }
180
181 try res.entry.value.append(self.allocator, object_offset);
163182
183 // TODO This will go once we properly use archive's TOC to pick
184 // an object which defines a missing symbol rather than pasting in
185 // all of the objects always.
164186 // Here, we assume that symbols are NOT sorted in any way, and
165187 // they point to objects in sequence.
166188 if (object_offsets.items[last] != object_offset) {