| ... | @@ -49,11 +49,8 @@ imports_count_dirty: bool = true, | ... | @@ -49,11 +49,8 @@ imports_count_dirty: bool = true, |
| 49 | /// Virtual address of the entry point procedure relative to image base. | 49 | /// Virtual address of the entry point procedure relative to image base. |
| 50 | entry_addr: ?u32 = null, | 50 | entry_addr: ?u32 = null, |
| 51 | | 51 | |
| 52 | /// Table of Decls that are currently alive. | 52 | /// Table of tracked Decls. |
| 53 | /// We store them here so that we can properly dispose of any allocated | 53 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 54 | /// memory within the atom in the incremental linker. | | |
| 55 | /// TODO consolidate this. | | |
| 56 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, | | |
| 57 | | 54 | |
| 58 | /// List of atoms that are either synthetic or map directly to the Zig source program. | 55 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 59 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 56 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| ... | @@ -98,9 +95,9 @@ const Entry = struct { | ... | @@ -98,9 +95,9 @@ const Entry = struct { |
| 98 | sym_index: u32, | 95 | sym_index: u32, |
| 99 | }; | 96 | }; |
| 100 | | 97 | |
| 101 | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); | 98 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 102 | const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 99 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 103 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); | 100 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 104 | | 101 | |
| 105 | const default_file_alignment: u16 = 0x200; | 102 | const default_file_alignment: u16 = 0x200; |
| 106 | const default_size_of_stack_reserve: u32 = 0x1000000; | 103 | const default_size_of_stack_reserve: u32 = 0x1000000; |
| ... | @@ -137,6 +134,10 @@ const DeclMetadata = struct { | ... | @@ -137,6 +134,10 @@ const DeclMetadata = struct { |
| 137 | /// A list of all exports aliases of this Decl. | 134 | /// A list of all exports aliases of this Decl. |
| 138 | exports: std.ArrayListUnmanaged(u32) = .{}, | 135 | exports: std.ArrayListUnmanaged(u32) = .{}, |
| 139 | | 136 | |
| | 137 | fn deinit(m: *DeclMetadata, allocator: Allocator) void { |
| | 138 | m.exports.deinit(allocator); |
| | 139 | } |
| | 140 | |
| 140 | fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 { | 141 | fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 { |
| 141 | for (m.exports.items) |exp| { | 142 | for (m.exports.items) |exp| { |
| 142 | if (mem.eql(u8, name, coff_file.getSymbolName(.{ | 143 | if (mem.eql(u8, name, coff_file.getSymbolName(.{ |
| ... | @@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void { | ... | @@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void { |
| 293 | } | 294 | } |
| 294 | self.import_tables.deinit(gpa); | 295 | self.import_tables.deinit(gpa); |
| 295 | | 296 | |
| 296 | { | 297 | for (self.decls.values()) |*metadata| { |
| 297 | var it = self.decls.iterator(); | 298 | metadata.deinit(gpa); |
| 298 | while (it.next()) |entry| { | | |
| 299 | entry.value_ptr.exports.deinit(gpa); | | |
| 300 | } | | |
| 301 | self.decls.deinit(gpa); | | |
| 302 | } | 299 | } |
| | 300 | self.decls.deinit(gpa); |
| 303 | | 301 | |
| 304 | self.atom_by_index_table.deinit(gpa); | 302 | self.atom_by_index_table.deinit(gpa); |
| 305 | | 303 | |
| 306 | { | 304 | for (self.unnamed_const_atoms.values()) |*atoms| { |
| 307 | var it = self.unnamed_const_atoms.valueIterator(); | 305 | atoms.deinit(gpa); |
| 308 | while (it.next()) |atoms| { | | |
| 309 | atoms.deinit(gpa); | | |
| 310 | } | | |
| 311 | self.unnamed_const_atoms.deinit(gpa); | | |
| 312 | } | 306 | } |
| | 307 | self.unnamed_const_atoms.deinit(gpa); |
| 313 | | 308 | |
| 314 | { | 309 | for (self.relocs.values()) |*relocs| { |
| 315 | var it = self.relocs.valueIterator(); | 310 | relocs.deinit(gpa); |
| 316 | while (it.next()) |relocs| { | | |
| 317 | relocs.deinit(gpa); | | |
| 318 | } | | |
| 319 | self.relocs.deinit(gpa); | | |
| 320 | } | 311 | } |
| | 312 | self.relocs.deinit(gpa); |
| 321 | | 313 | |
| 322 | { | 314 | for (self.base_relocs.values()) |*relocs| { |
| 323 | var it = self.base_relocs.valueIterator(); | 315 | relocs.deinit(gpa); |
| 324 | while (it.next()) |relocs| { | | |
| 325 | relocs.deinit(gpa); | | |
| 326 | } | | |
| 327 | self.base_relocs.deinit(gpa); | | |
| 328 | } | 316 | } |
| | 317 | self.base_relocs.deinit(gpa); |
| 329 | } | 318 | } |
| 330 | | 319 | |
| 331 | fn populateMissingMetadata(self: *Coff) !void { | 320 | fn populateMissingMetadata(self: *Coff) !void { |
| ... | @@ -455,7 +444,44 @@ fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.Section | ... | @@ -455,7 +444,44 @@ fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.Section |
| 455 | return index; | 444 | return index; |
| 456 | } | 445 | } |
| 457 | | 446 | |
| 458 | fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { | 447 | fn growSection(self: *Coff, sect_id: u32, needed_size: u32) !void { |
| | 448 | const header = &self.sections.items(.header)[sect_id]; |
| | 449 | const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; |
| | 450 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| | 451 | |
| | 452 | if (needed_size > sect_capacity) { |
| | 453 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); |
| | 454 | const current_size = if (maybe_last_atom_index) |last_atom_index| blk: { |
| | 455 | const last_atom = self.getAtom(last_atom_index); |
| | 456 | const sym = last_atom.getSymbol(self); |
| | 457 | break :blk (sym.value + last_atom.size) - header.virtual_address; |
| | 458 | } else 0; |
| | 459 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ |
| | 460 | self.getSectionName(header), |
| | 461 | header.pointer_to_raw_data, |
| | 462 | new_offset, |
| | 463 | }); |
| | 464 | const amt = try self.base.file.?.copyRangeAll( |
| | 465 | header.pointer_to_raw_data, |
| | 466 | self.base.file.?, |
| | 467 | new_offset, |
| | 468 | current_size, |
| | 469 | ); |
| | 470 | if (amt != current_size) return error.InputOutput; |
| | 471 | header.pointer_to_raw_data = new_offset; |
| | 472 | } |
| | 473 | |
| | 474 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); |
| | 475 | if (needed_size > sect_vm_capacity) { |
| | 476 | try self.growSectionVirtualMemory(sect_id, needed_size); |
| | 477 | self.markRelocsDirtyByAddress(header.virtual_address + needed_size); |
| | 478 | } |
| | 479 | |
| | 480 | header.virtual_size = @max(header.virtual_size, needed_size); |
| | 481 | header.size_of_raw_data = needed_size; |
| | 482 | } |
| | 483 | |
| | 484 | fn growSectionVirtualMemory(self: *Coff, sect_id: u32, needed_size: u32) !void { |
| 459 | const header = &self.sections.items(.header)[sect_id]; | 485 | const header = &self.sections.items(.header)[sect_id]; |
| 460 | const increased_size = padToIdeal(needed_size); | 486 | const increased_size = padToIdeal(needed_size); |
| 461 | const old_aligned_end = header.virtual_address + mem.alignForwardGeneric(u32, header.virtual_size, self.page_size); | 487 | const old_aligned_end = header.virtual_address + mem.alignForwardGeneric(u32, header.virtual_size, self.page_size); |
| ... | @@ -562,38 +588,8 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme | ... | @@ -562,38 +588,8 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme |
| 562 | else | 588 | else |
| 563 | true; | 589 | true; |
| 564 | if (expand_section) { | 590 | if (expand_section) { |
| 565 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); | | |
| 566 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; | 591 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; |
| 567 | if (needed_size > sect_capacity) { | 592 | try self.growSection(sect_id, needed_size); |
| 568 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); | | |
| 569 | const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { | | |
| 570 | const last_atom = self.getAtom(last_atom_index); | | |
| 571 | const sym = last_atom.getSymbol(self); | | |
| 572 | break :blk (sym.value + last_atom.size) - header.virtual_address; | | |
| 573 | } else 0; | | |
| 574 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ | | |
| 575 | self.getSectionName(header), | | |
| 576 | header.pointer_to_raw_data, | | |
| 577 | new_offset, | | |
| 578 | }); | | |
| 579 | const amt = try self.base.file.?.copyRangeAll( | | |
| 580 | header.pointer_to_raw_data, | | |
| 581 | self.base.file.?, | | |
| 582 | new_offset, | | |
| 583 | current_size, | | |
| 584 | ); | | |
| 585 | if (amt != current_size) return error.InputOutput; | | |
| 586 | header.pointer_to_raw_data = new_offset; | | |
| 587 | } | | |
| 588 | | | |
| 589 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); | | |
| 590 | if (needed_size > sect_vm_capacity) { | | |
| 591 | try self.growSectionVM(sect_id, needed_size); | | |
| 592 | self.markRelocsDirtyByAddress(header.virtual_address + needed_size); | | |
| 593 | } | | |
| 594 | | | |
| 595 | header.virtual_size = @max(header.virtual_size, needed_size); | | |
| 596 | header.size_of_raw_data = needed_size; | | |
| 597 | maybe_last_atom_index.* = atom_index; | 593 | maybe_last_atom_index.* = atom_index; |
| 598 | } | 594 | } |
| 599 | | 595 | |
| ... | @@ -771,7 +767,7 @@ fn shrinkAtom(self: *Coff, atom_index: Atom.Index, new_block_size: u32) void { | ... | @@ -771,7 +767,7 @@ fn shrinkAtom(self: *Coff, atom_index: Atom.Index, new_block_size: u32) void { |
| 771 | // capacity, insert a free list node for it. | 767 | // capacity, insert a free list node for it. |
| 772 | } | 768 | } |
| 773 | | 769 | |
| 774 | fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { | 770 | fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { |
| 775 | const atom = self.getAtom(atom_index); | 771 | const atom = self.getAtom(atom_index); |
| 776 | const sym = atom.getSymbol(self); | 772 | const sym = atom.getSymbol(self); |
| 777 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); | 773 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); |
| ... | @@ -781,8 +777,8 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { | ... | @@ -781,8 +777,8 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { |
| 781 | file_offset, | 777 | file_offset, |
| 782 | file_offset + code.len, | 778 | file_offset + code.len, |
| 783 | }); | 779 | }); |
| | 780 | self.resolveRelocs(atom_index, code); |
| 784 | try self.base.file.?.pwriteAll(code, file_offset); | 781 | try self.base.file.?.pwriteAll(code, file_offset); |
| 785 | try self.resolveRelocs(atom_index); | | |
| 786 | } | 782 | } |
| 787 | | 783 | |
| 788 | fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { | 784 | fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { |
| ... | @@ -800,8 +796,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { | ... | @@ -800,8 +796,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { |
| 800 | | 796 | |
| 801 | fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { | 797 | fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { |
| 802 | // TODO: reverse-lookup might come in handy here | 798 | // TODO: reverse-lookup might come in handy here |
| 803 | var it = self.relocs.valueIterator(); | 799 | for (self.relocs.values()) |*relocs| { |
| 804 | while (it.next()) |relocs| { | | |
| 805 | for (relocs.items) |*reloc| { | 800 | for (relocs.items) |*reloc| { |
| 806 | if (!reloc.target.eql(target)) continue; | 801 | if (!reloc.target.eql(target)) continue; |
| 807 | reloc.dirty = true; | 802 | reloc.dirty = true; |
| ... | @@ -810,8 +805,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { | ... | @@ -810,8 +805,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { |
| 810 | } | 805 | } |
| 811 | | 806 | |
| 812 | fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { | 807 | fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 813 | var it = self.relocs.valueIterator(); | 808 | for (self.relocs.values()) |*relocs| { |
| 814 | while (it.next()) |relocs| { | | |
| 815 | for (relocs.items) |*reloc| { | 809 | for (relocs.items) |*reloc| { |
| 816 | const target_vaddr = reloc.getTargetAddress(self) orelse continue; | 810 | const target_vaddr = reloc.getTargetAddress(self) orelse continue; |
| 817 | if (target_vaddr < addr) continue; | 811 | if (target_vaddr < addr) continue; |
| ... | @@ -820,14 +814,16 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { | ... | @@ -820,14 +814,16 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 820 | } | 814 | } |
| 821 | } | 815 | } |
| 822 | | 816 | |
| 823 | fn resolveRelocs(self: *Coff, atom_index: Atom.Index) !void { | 817 | fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { |
| 824 | const relocs = self.relocs.get(atom_index) orelse return; | 818 | const relocs = self.relocs.getPtr(atom_index) orelse return; |
| 825 | | 819 | |
| 826 | log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); | 820 | log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); |
| 827 | | 821 | |
| 828 | for (relocs.items) |*reloc| { | 822 | for (relocs.items) |*reloc| { |
| 829 | if (!reloc.dirty) continue; | 823 | if (!reloc.dirty) continue; |
| 830 | try reloc.resolve(atom_index, self); | 824 | if (reloc.resolve(atom_index, code, self)) { |
| | 825 | reloc.dirty = false; |
| | 826 | } |
| 831 | } | 827 | } |
| 832 | } | 828 | } |
| 833 | | 829 | |
| ... | @@ -944,7 +940,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -944,7 +940,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live |
| 944 | &code_buffer, | 940 | &code_buffer, |
| 945 | .none, | 941 | .none, |
| 946 | ); | 942 | ); |
| 947 | const code = switch (res) { | 943 | var code = switch (res) { |
| 948 | .ok => code_buffer.items, | 944 | .ok => code_buffer.items, |
| 949 | .fail => |em| { | 945 | .fail => |em| { |
| 950 | decl.analysis = .codegen_failure; | 946 | decl.analysis = .codegen_failure; |
| ... | @@ -994,7 +990,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In | ... | @@ -994,7 +990,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In |
| 994 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .none, .{ | 990 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .none, .{ |
| 995 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, | 991 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, |
| 996 | }); | 992 | }); |
| 997 | const code = switch (res) { | 993 | var code = switch (res) { |
| 998 | .ok => code_buffer.items, | 994 | .ok => code_buffer.items, |
| 999 | .fail => |em| { | 995 | .fail => |em| { |
| 1000 | decl.analysis = .codegen_failure; | 996 | decl.analysis = .codegen_failure; |
| ... | @@ -1057,7 +1053,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -1057,7 +1053,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1057 | }, &code_buffer, .none, .{ | 1053 | }, &code_buffer, .none, .{ |
| 1058 | .parent_atom_index = atom.getSymbolIndex().?, | 1054 | .parent_atom_index = atom.getSymbolIndex().?, |
| 1059 | }); | 1055 | }); |
| 1060 | const code = switch (res) { | 1056 | var code = switch (res) { |
| 1061 | .ok => code_buffer.items, | 1057 | .ok => code_buffer.items, |
| 1062 | .fail => |em| { | 1058 | .fail => |em| { |
| 1063 | decl.analysis = .codegen_failure; | 1059 | decl.analysis = .codegen_failure; |
| ... | @@ -1110,7 +1106,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 { | ... | @@ -1110,7 +1106,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 { |
| 1110 | return index; | 1106 | return index; |
| 1111 | } | 1107 | } |
| 1112 | | 1108 | |
| 1113 | fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, complex_type: coff.ComplexType) !void { | 1109 | fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void { |
| 1114 | const gpa = self.base.allocator; | 1110 | const gpa = self.base.allocator; |
| 1115 | const mod = self.base.options.module.?; | 1111 | const mod = self.base.options.module.?; |
| 1116 | const decl = mod.declPtr(decl_index); | 1112 | const decl = mod.declPtr(decl_index); |
| ... | @@ -1195,7 +1191,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { | ... | @@ -1195,7 +1191,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1195 | | 1191 | |
| 1196 | log.debug("freeDecl {*}", .{decl}); | 1192 | log.debug("freeDecl {*}", .{decl}); |
| 1197 | | 1193 | |
| 1198 | if (self.decls.fetchRemove(decl_index)) |const_kv| { | 1194 | if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| { |
| 1199 | var kv = const_kv; | 1195 | var kv = const_kv; |
| 1200 | self.freeAtom(kv.value.atom); | 1196 | self.freeAtom(kv.value.atom); |
| 1201 | self.freeUnnamedConsts(decl_index); | 1197 | self.freeUnnamedConsts(decl_index); |
| ... | @@ -1422,12 +1418,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1422,12 +1418,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1422 | } | 1418 | } |
| 1423 | | 1419 | |
| 1424 | try self.writeImportTables(); | 1420 | try self.writeImportTables(); |
| 1425 | { | 1421 | |
| 1426 | var it = self.relocs.keyIterator(); | 1422 | for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { |
| 1427 | while (it.next()) |atom| { | 1423 | const needs_update = for (relocs.items) |reloc| { |
| 1428 | try self.resolveRelocs(atom.*); | 1424 | if (reloc.dirty) break true; |
| 1429 | } | 1425 | } else false; |
| | 1426 | |
| | 1427 | if (!needs_update) continue; |
| | 1428 | |
| | 1429 | const atom = self.getAtom(atom_index); |
| | 1430 | const sym = atom.getSymbol(self); |
| | 1431 | const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; |
| | 1432 | const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; |
| | 1433 | |
| | 1434 | var code = std.ArrayList(u8).init(gpa); |
| | 1435 | defer code.deinit(); |
| | 1436 | try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); |
| | 1437 | |
| | 1438 | const amt = try self.base.file.?.preadAll(code.items, file_offset); |
| | 1439 | if (amt != code.items.len) return error.InputOutput; |
| | 1440 | |
| | 1441 | try self.writeAtom(atom_index, code.items); |
| 1430 | } | 1442 | } |
| | 1443 | |
| 1431 | try self.writeBaseRelocations(); | 1444 | try self.writeBaseRelocations(); |
| 1432 | | 1445 | |
| 1433 | if (self.getEntryPoint()) |entry_sym_loc| { | 1446 | if (self.getEntryPoint()) |entry_sym_loc| { |
| ... | @@ -1576,25 +1589,8 @@ fn writeBaseRelocations(self: *Coff) !void { | ... | @@ -1576,25 +1589,8 @@ fn writeBaseRelocations(self: *Coff) !void { |
| 1576 | } | 1589 | } |
| 1577 | | 1590 | |
| 1578 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; | 1591 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; |
| 1579 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); | | |
| 1580 | const needed_size = @intCast(u32, buffer.items.len); | 1592 | const needed_size = @intCast(u32, buffer.items.len); |
| 1581 | if (needed_size > sect_capacity) { | 1593 | try self.growSection(self.reloc_section_index.?, needed_size); |
| 1582 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); | | |
| 1583 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ | | |
| 1584 | self.getSectionName(header), | | |
| 1585 | header.pointer_to_raw_data, | | |
| 1586 | new_offset, | | |
| 1587 | }); | | |
| 1588 | header.pointer_to_raw_data = new_offset; | | |
| 1589 | | | |
| 1590 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); | | |
| 1591 | if (needed_size > sect_vm_capacity) { | | |
| 1592 | // TODO: we want to enforce .reloc after every alloc section. | | |
| 1593 | try self.growSectionVM(self.reloc_section_index.?, needed_size); | | |
| 1594 | } | | |
| 1595 | } | | |
| 1596 | header.virtual_size = @max(header.virtual_size, needed_size); | | |
| 1597 | header.size_of_raw_data = needed_size; | | |
| 1598 | | 1594 | |
| 1599 | try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data); | 1595 | try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data); |
| 1600 | | 1596 | |
| ... | @@ -1633,20 +1629,7 @@ fn writeImportTables(self: *Coff) !void { | ... | @@ -1633,20 +1629,7 @@ fn writeImportTables(self: *Coff) !void { |
| 1633 | } | 1629 | } |
| 1634 | | 1630 | |
| 1635 | const needed_size = iat_size + dir_table_size + lookup_table_size + names_table_size + dll_names_size; | 1631 | const needed_size = iat_size + dir_table_size + lookup_table_size + names_table_size + dll_names_size; |
| 1636 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); | 1632 | try self.growSection(self.idata_section_index.?, needed_size); |
| 1637 | if (needed_size > sect_capacity) { | | |
| 1638 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); | | |
| 1639 | log.debug("moving .idata from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset }); | | |
| 1640 | header.pointer_to_raw_data = new_offset; | | |
| 1641 | | | |
| 1642 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); | | |
| 1643 | if (needed_size > sect_vm_capacity) { | | |
| 1644 | try self.growSectionVM(self.idata_section_index.?, needed_size); | | |
| 1645 | } | | |
| 1646 | | | |
| 1647 | header.virtual_size = @max(header.virtual_size, needed_size); | | |
| 1648 | header.size_of_raw_data = needed_size; | | |
| 1649 | } | | |
| 1650 | | 1633 | |
| 1651 | // Do the actual writes | 1634 | // Do the actual writes |
| 1652 | var buffer = std.ArrayList(u8).init(gpa); | 1635 | var buffer = std.ArrayList(u8).init(gpa); |