| ... | @@ -69,7 +69,10 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, | ... | @@ -69,7 +69,10 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, |
| 69 | /// Table of atoms indexed by the symbol index. | 69 | /// Table of atoms indexed by the symbol index. |
| 70 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, | 70 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, |
| 71 | | 71 | |
| 72 | const page_size: u16 = 0x1000; | 72 | const default_section_alignment: u16 = 0x1000; |
| | 73 | const default_file_alignment: u16 = 0x200; |
| | 74 | const default_image_base_dll: u64 = 0x10000000; |
| | 75 | const default_image_base_exe: u64 = 0x10000; |
| 73 | | 76 | |
| 74 | const Section = struct { | 77 | const Section = struct { |
| 75 | header: coff.SectionHeader, | 78 | header: coff.SectionHeader, |
| ... | @@ -701,7 +704,7 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -701,7 +704,7 @@ fn writeHeader(self: *Coff) !void { |
| 701 | writer.writeAll("PE\x00\x00") catch unreachable; | 704 | writer.writeAll("PE\x00\x00") catch unreachable; |
| 702 | buffer.items[0x3c] = @intCast(u8, msdos_stub.len + 4); | 705 | buffer.items[0x3c] = @intCast(u8, msdos_stub.len + 4); |
| 703 | | 706 | |
| 704 | var num_data_directories: u32 = 1; | 707 | var num_data_directories: u32 = 0; |
| 705 | var size_of_optional_header = switch (self.ptr_width) { | 708 | var size_of_optional_header = switch (self.ptr_width) { |
| 706 | .p32 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE32)), | 709 | .p32 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE32)), |
| 707 | .p64 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE64)), | 710 | .p64 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE64)), |
| ... | @@ -732,7 +735,25 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -732,7 +735,25 @@ fn writeHeader(self: *Coff) !void { |
| 732 | try buffer.ensureUnusedCapacity(@sizeOf(coff.CoffHeader)); | 735 | try buffer.ensureUnusedCapacity(@sizeOf(coff.CoffHeader)); |
| 733 | writer.writeAll(mem.asBytes(&coff_header)) catch unreachable; | 736 | writer.writeAll(mem.asBytes(&coff_header)) catch unreachable; |
| 734 | | 737 | |
| | 738 | const dll_flags: coff.DllFlags = .{ |
| | 739 | .HIGH_ENTROPY_VA = 0, // TODO handle ASLR |
| | 740 | .DYNAMIC_BASE = 0, // TODO handle ASLR |
| | 741 | .TERMINAL_SERVER_AWARE = 1, // We are not a legacy app |
| | 742 | .NX_COMPAT = 1, // We are compatible with Data Execution Prevention |
| | 743 | }; |
| 735 | const subsystem: coff.Subsystem = .WINDOWS_CUI; | 744 | const subsystem: coff.Subsystem = .WINDOWS_CUI; |
| | 745 | const size_of_headers: u32 = @intCast( |
| | 746 | u32, |
| | 747 | msdos_stub.len + 8 + size_of_optional_header + self.sections.slice().len * @sizeOf(coff.SectionHeader), |
| | 748 | ); |
| | 749 | const size_of_image_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_section_alignment); |
| | 750 | const size_of_headers_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_file_alignment); |
| | 751 | const image_base = self.base.options.image_base_override orelse switch (self.base.options.output_mode) { |
| | 752 | .Exe => default_image_base_exe, |
| | 753 | .Lib => default_image_base_dll, |
| | 754 | else => unreachable, |
| | 755 | }; |
| | 756 | |
| 736 | switch (self.ptr_width) { | 757 | switch (self.ptr_width) { |
| 737 | .p32 => { | 758 | .p32 => { |
| 738 | try buffer.ensureUnusedCapacity(@sizeOf(coff.OptionalHeaderPE32)); | 759 | try buffer.ensureUnusedCapacity(@sizeOf(coff.OptionalHeaderPE32)); |
| ... | @@ -746,21 +767,21 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -746,21 +767,21 @@ fn writeHeader(self: *Coff) !void { |
| 746 | .address_of_entry_point = self.entry_addr orelse 0, | 767 | .address_of_entry_point = self.entry_addr orelse 0, |
| 747 | .base_of_code = 0, | 768 | .base_of_code = 0, |
| 748 | .base_of_data = 0, | 769 | .base_of_data = 0, |
| 749 | .image_base = 0, | 770 | .image_base = @intCast(u32, image_base), |
| 750 | .section_alignment = 0, | 771 | .section_alignment = default_section_alignment, |
| 751 | .file_alignment = 0, | 772 | .file_alignment = default_file_alignment, |
| 752 | .major_operating_system_version = 0, | 773 | .major_operating_system_version = 6, |
| 753 | .minor_operating_system_version = 0, | 774 | .minor_operating_system_version = 0, |
| 754 | .major_image_version = 0, | 775 | .major_image_version = 0, |
| 755 | .minor_image_version = 0, | 776 | .minor_image_version = 0, |
| 756 | .major_subsystem_version = 0, | 777 | .major_subsystem_version = 6, |
| 757 | .minor_subsystem_version = 0, | 778 | .minor_subsystem_version = 0, |
| 758 | .win32_version_value = 0, | 779 | .win32_version_value = 0, |
| 759 | .size_of_image = 0, | 780 | .size_of_image = size_of_image_aligned, |
| 760 | .size_of_headers = 0, | 781 | .size_of_headers = size_of_headers_aligned, |
| 761 | .checksum = 0, | 782 | .checksum = 0, |
| 762 | .subsystem = subsystem, | 783 | .subsystem = subsystem, |
| 763 | .dll_flags = .{}, | 784 | .dll_flags = dll_flags, |
| 764 | .size_of_stack_reserve = 0, | 785 | .size_of_stack_reserve = 0, |
| 765 | .size_of_stack_commit = 0, | 786 | .size_of_stack_commit = 0, |
| 766 | .size_of_heap_reserve = 0, | 787 | .size_of_heap_reserve = 0, |
| ... | @@ -781,21 +802,21 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -781,21 +802,21 @@ fn writeHeader(self: *Coff) !void { |
| 781 | .size_of_uninitialized_data = 0, | 802 | .size_of_uninitialized_data = 0, |
| 782 | .address_of_entry_point = self.entry_addr orelse 0, | 803 | .address_of_entry_point = self.entry_addr orelse 0, |
| 783 | .base_of_code = 0, | 804 | .base_of_code = 0, |
| 784 | .image_base = 0, | 805 | .image_base = image_base, |
| 785 | .section_alignment = 0, | 806 | .section_alignment = default_section_alignment, |
| 786 | .file_alignment = 0, | 807 | .file_alignment = default_file_alignment, |
| 787 | .major_operating_system_version = 0, | 808 | .major_operating_system_version = 6, |
| 788 | .minor_operating_system_version = 0, | 809 | .minor_operating_system_version = 0, |
| 789 | .major_image_version = 0, | 810 | .major_image_version = 0, |
| 790 | .minor_image_version = 0, | 811 | .minor_image_version = 0, |
| 791 | .major_subsystem_version = 0, | 812 | .major_subsystem_version = 6, |
| 792 | .minor_subsystem_version = 0, | 813 | .minor_subsystem_version = 0, |
| 793 | .win32_version_value = 0, | 814 | .win32_version_value = 0, |
| 794 | .size_of_image = 0, | 815 | .size_of_image = size_of_image_aligned, |
| 795 | .size_of_headers = 0, | 816 | .size_of_headers = size_of_headers_aligned, |
| 796 | .checksum = 0, | 817 | .checksum = 0, |
| 797 | .subsystem = subsystem, | 818 | .subsystem = subsystem, |
| 798 | .dll_flags = .{}, | 819 | .dll_flags = dll_flags, |
| 799 | .size_of_stack_reserve = 0, | 820 | .size_of_stack_reserve = 0, |
| 800 | .size_of_stack_commit = 0, | 821 | .size_of_stack_commit = 0, |
| 801 | .size_of_heap_reserve = 0, | 822 | .size_of_heap_reserve = 0, |
| ... | @@ -808,11 +829,17 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -808,11 +829,17 @@ fn writeHeader(self: *Coff) !void { |
| 808 | } | 829 | } |
| 809 | | 830 | |
| 810 | try buffer.ensureUnusedCapacity(num_data_directories * @sizeOf(coff.ImageDataDirectory)); | 831 | try buffer.ensureUnusedCapacity(num_data_directories * @sizeOf(coff.ImageDataDirectory)); |
| 811 | writer.writeAll(mem.asBytes(&coff.ImageDataDirectory{ | 832 | { |
| 812 | .virtual_address = 0, | 833 | var i: usize = 0; |
| 813 | .size = 0, | 834 | while (i < num_data_directories) : (i += 1) { |
| 814 | })) catch unreachable; | 835 | writer.writeAll(mem.asBytes(&coff.ImageDataDirectory{ |
| | 836 | .virtual_address = 0, |
| | 837 | .size = 0, |
| | 838 | })) catch unreachable; |
| | 839 | } |
| | 840 | } |
| 815 | | 841 | |
| | 842 | try self.base.file.?.pwriteAll(&[_]u8{0}, size_of_headers_aligned); |
| 816 | try self.base.file.?.pwriteAll(buffer.items, 0); | 843 | try self.base.file.?.pwriteAll(buffer.items, 0); |
| 817 | } | 844 | } |
| 818 | | 845 | |