| ... | ... | @@ -20,6 +20,11 @@ name: []u8, |
| 20 | 20 | |
| 21 | 21 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| 22 | 22 | |
| 23 | /// Parsed table of contents. |
| 24 | /// Each symbol name points to a list of all definition |
| 25 | /// sites within the current static archive. |
| 26 | toc: std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(u32)) = .{}, |
| 27 | |
| 23 | 28 | // Archive files start with the ARMAG identifying string. Then follows a |
| 24 | 29 | // `struct ar_hdr', and as many bytes of member file data as its `ar_size' |
| 25 | 30 | // member indicates, for each member file. |
| ... | ... | @@ -88,6 +93,11 @@ pub fn deinit(self: *Archive) void { |
| 88 | 93 | object.deinit(); |
| 89 | 94 | } |
| 90 | 95 | 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); |
| 91 | 101 | self.file.close(); |
| 92 | 102 | } |
| 93 | 103 | |
| ... | ... | @@ -159,8 +169,20 @@ fn readTableOfContents(self: *Archive, reader: anytype) ![]u32 { |
| 159 | 169 | }; |
| 160 | 170 | const object_offset = try symtab_reader.readIntLittle(u32); |
| 161 | 171 | |
| 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); |
| 163 | 182 | |
| 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. |
| 164 | 186 | // Here, we assume that symbols are NOT sorted in any way, and |
| 165 | 187 | // they point to objects in sequence. |
| 166 | 188 | if (object_offsets.items[last] != object_offset) { |