Commit f1e324216d

Jakub Konka <kubkon@jakubkonka.com>
2021-03-25 22:48:04
zld: parse archive's table of contents
1 parent 4ce2127
Changed files (1)
src
link
src/link/MachO/Archive.zig
@@ -20,6 +20,11 @@ name: []u8,
 
 objects: std.ArrayListUnmanaged(Object) = .{},
 
+/// Parsed table of contents.
+/// Each symbol name points to a list of all definition
+/// sites within the current static archive.
+toc: std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(u32)) = .{},
+
 // Archive files start with the ARMAG identifying string.  Then follows a
 // `struct ar_hdr', and as many bytes of member file data as its `ar_size'
 // member indicates, for each member file.
@@ -88,6 +93,11 @@ pub fn deinit(self: *Archive) void {
         object.deinit();
     }
     self.objects.deinit(self.allocator);
+    for (self.toc.items()) |*entry| {
+        self.allocator.free(entry.key);
+        entry.value.deinit(self.allocator);
+    }
+    self.toc.deinit(self.allocator);
     self.file.close();
 }
 
@@ -159,8 +169,20 @@ fn readTableOfContents(self: *Archive, reader: anytype) ![]u32 {
         };
         const object_offset = try symtab_reader.readIntLittle(u32);
 
-        // TODO Store the table of contents for later reuse.
+        const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));
+        const owned_name = try self.allocator.dupe(u8, sym_name);
+        const res = try self.toc.getOrPut(self.allocator, owned_name);
+        defer if (res.found_existing) self.allocator.free(owned_name);
+
+        if (!res.found_existing) {
+            res.entry.value = .{};
+        }
+
+        try res.entry.value.append(self.allocator, object_offset);
 
+        // TODO This will go once we properly use archive's TOC to pick
+        // an object which defines a missing symbol rather than pasting in
+        // all of the objects always.
         // Here, we assume that symbols are NOT sorted in any way, and
         // they point to objects in sequence.
         if (object_offsets.items[last] != object_offset) {