| ... | ... | @@ -49,11 +49,8 @@ imports_count_dirty: bool = true, |
| 49 | 49 | /// Virtual address of the entry point procedure relative to image base. |
| 50 | 50 | entry_addr: ?u32 = null, |
| 51 | 51 | |
| 52 | | /// Table of Decls that are currently alive. |
| 53 | | /// We store them here so that we can properly dispose of any allocated |
| 54 | | /// memory within the atom in the incremental linker. |
| 55 | | /// TODO consolidate this. |
| 56 | | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 52 | /// Table of tracked Decls. |
| 53 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 57 | 54 | |
| 58 | 55 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 59 | 56 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| ... | ... | @@ -98,9 +95,9 @@ const Entry = struct { |
| 98 | 95 | sym_index: u32, |
| 99 | 96 | }; |
| 100 | 97 | |
| 101 | | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 102 | | const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 103 | | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 98 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 99 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 100 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 104 | 101 | |
| 105 | 102 | const default_file_alignment: u16 = 0x200; |
| 106 | 103 | const default_size_of_stack_reserve: u32 = 0x1000000; |
| ... | ... | @@ -137,6 +134,10 @@ const DeclMetadata = struct { |
| 137 | 134 | /// A list of all exports aliases of this Decl. |
| 138 | 135 | exports: std.ArrayListUnmanaged(u32) = .{}, |
| 139 | 136 | |
| 137 | fn deinit(m: *DeclMetadata, allocator: Allocator) void { |
| 138 | m.exports.deinit(allocator); |
| 139 | } |
| 140 | |
| 140 | 141 | fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 { |
| 141 | 142 | for (m.exports.items) |exp| { |
| 142 | 143 | if (mem.eql(u8, name, coff_file.getSymbolName(.{ |
| ... | ... | @@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void { |
| 293 | 294 | } |
| 294 | 295 | self.import_tables.deinit(gpa); |
| 295 | 296 | |
| 296 | | { |
| 297 | | var it = self.decls.iterator(); |
| 298 | | while (it.next()) |entry| { |
| 299 | | entry.value_ptr.exports.deinit(gpa); |
| 300 | | } |
| 301 | | self.decls.deinit(gpa); |
| 297 | for (self.decls.values()) |*metadata| { |
| 298 | metadata.deinit(gpa); |
| 302 | 299 | } |
| 300 | self.decls.deinit(gpa); |
| 303 | 301 | |
| 304 | 302 | self.atom_by_index_table.deinit(gpa); |
| 305 | 303 | |
| 306 | | { |
| 307 | | var it = self.unnamed_const_atoms.valueIterator(); |
| 308 | | while (it.next()) |atoms| { |
| 309 | | atoms.deinit(gpa); |
| 310 | | } |
| 311 | | self.unnamed_const_atoms.deinit(gpa); |
| 304 | for (self.unnamed_const_atoms.values()) |*atoms| { |
| 305 | atoms.deinit(gpa); |
| 312 | 306 | } |
| 307 | self.unnamed_const_atoms.deinit(gpa); |
| 313 | 308 | |
| 314 | | { |
| 315 | | var it = self.relocs.valueIterator(); |
| 316 | | while (it.next()) |relocs| { |
| 317 | | relocs.deinit(gpa); |
| 318 | | } |
| 319 | | self.relocs.deinit(gpa); |
| 309 | for (self.relocs.values()) |*relocs| { |
| 310 | relocs.deinit(gpa); |
| 320 | 311 | } |
| 312 | self.relocs.deinit(gpa); |
| 321 | 313 | |
| 322 | | { |
| 323 | | var it = self.base_relocs.valueIterator(); |
| 324 | | while (it.next()) |relocs| { |
| 325 | | relocs.deinit(gpa); |
| 326 | | } |
| 327 | | self.base_relocs.deinit(gpa); |
| 314 | for (self.base_relocs.values()) |*relocs| { |
| 315 | relocs.deinit(gpa); |
| 328 | 316 | } |
| 317 | self.base_relocs.deinit(gpa); |
| 329 | 318 | } |
| 330 | 319 | |
| 331 | 320 | fn populateMissingMetadata(self: *Coff) !void { |
| ... | ... | @@ -800,8 +789,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { |
| 800 | 789 | |
| 801 | 790 | fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { |
| 802 | 791 | // TODO: reverse-lookup might come in handy here |
| 803 | | var it = self.relocs.valueIterator(); |
| 804 | | while (it.next()) |relocs| { |
| 792 | for (self.relocs.values()) |*relocs| { |
| 805 | 793 | for (relocs.items) |*reloc| { |
| 806 | 794 | if (!reloc.target.eql(target)) continue; |
| 807 | 795 | reloc.dirty = true; |
| ... | ... | @@ -810,8 +798,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { |
| 810 | 798 | } |
| 811 | 799 | |
| 812 | 800 | fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 813 | | var it = self.relocs.valueIterator(); |
| 814 | | while (it.next()) |relocs| { |
| 801 | for (self.relocs.values()) |*relocs| { |
| 815 | 802 | for (relocs.items) |*reloc| { |
| 816 | 803 | const target_vaddr = reloc.getTargetAddress(self) orelse continue; |
| 817 | 804 | if (target_vaddr < addr) continue; |
| ... | ... | @@ -821,7 +808,7 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 821 | 808 | } |
| 822 | 809 | |
| 823 | 810 | fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { |
| 824 | | const relocs = self.relocs.get(atom_index) orelse return; |
| 811 | const relocs = self.relocs.getPtr(atom_index) orelse return; |
| 825 | 812 | |
| 826 | 813 | log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); |
| 827 | 814 | |
| ... | ... | @@ -1196,7 +1183,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1196 | 1183 | |
| 1197 | 1184 | log.debug("freeDecl {*}", .{decl}); |
| 1198 | 1185 | |
| 1199 | | if (self.decls.fetchRemove(decl_index)) |const_kv| { |
| 1186 | if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| { |
| 1200 | 1187 | var kv = const_kv; |
| 1201 | 1188 | self.freeAtom(kv.value.atom); |
| 1202 | 1189 | self.freeUnnamedConsts(decl_index); |
| ... | ... | @@ -1423,32 +1410,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1423 | 1410 | } |
| 1424 | 1411 | |
| 1425 | 1412 | try self.writeImportTables(); |
| 1426 | | { |
| 1427 | | var it = self.relocs.keyIterator(); |
| 1428 | | while (it.next()) |atom_index_ptr| { |
| 1429 | | const atom_index = atom_index_ptr.*; |
| 1430 | | const relocs = self.relocs.get(atom_index).?; |
| 1431 | | const needs_update = for (relocs.items) |reloc| { |
| 1432 | | if (reloc.dirty) break true; |
| 1433 | | } else false; |
| 1434 | 1413 | |
| 1435 | | if (!needs_update) continue; |
| 1414 | for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { |
| 1415 | const needs_update = for (relocs.items) |reloc| { |
| 1416 | if (reloc.dirty) break true; |
| 1417 | } else false; |
| 1436 | 1418 | |
| 1437 | | const atom = self.getAtom(atom_index); |
| 1438 | | const sym = atom.getSymbol(self); |
| 1439 | | const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; |
| 1440 | | const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; |
| 1419 | if (!needs_update) continue; |
| 1441 | 1420 | |
| 1442 | | var code = std.ArrayList(u8).init(gpa); |
| 1443 | | defer code.deinit(); |
| 1444 | | try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); |
| 1421 | const atom = self.getAtom(atom_index); |
| 1422 | const sym = atom.getSymbol(self); |
| 1423 | const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; |
| 1424 | const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; |
| 1445 | 1425 | |
| 1446 | | const amt = try self.base.file.?.preadAll(code.items, file_offset); |
| 1447 | | if (amt != code.items.len) return error.InputOutput; |
| 1426 | var code = std.ArrayList(u8).init(gpa); |
| 1427 | defer code.deinit(); |
| 1428 | try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); |
| 1448 | 1429 | |
| 1449 | | try self.writeAtom(atom_index, code.items); |
| 1450 | | } |
| 1430 | const amt = try self.base.file.?.preadAll(code.items, file_offset); |
| 1431 | if (amt != code.items.len) return error.InputOutput; |
| 1432 | |
| 1433 | try self.writeAtom(atom_index, code.items); |
| 1451 | 1434 | } |
| 1435 | |
| 1452 | 1436 | try self.writeBaseRelocations(); |
| 1453 | 1437 | |
| 1454 | 1438 | if (self.getEntryPoint()) |entry_sym_loc| { |