| ... | @@ -30,6 +30,7 @@ const TypedValue = @import("../TypedValue.zig"); | ... | @@ -30,6 +30,7 @@ const TypedValue = @import("../TypedValue.zig"); |
| 30 | pub const base_tag: link.File.Tag = .coff; | 30 | pub const base_tag: link.File.Tag = .coff; |
| 31 | | 31 | |
| 32 | const msdos_stub = @embedFile("msdos-stub.bin"); | 32 | const msdos_stub = @embedFile("msdos-stub.bin"); |
| | 33 | const N_DATA_DIRS: u5 = 16; |
| 33 | | 34 | |
| 34 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. | 35 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. |
| 35 | llvm_object: ?*LlvmObject = null, | 36 | llvm_object: ?*LlvmObject = null, |
| ... | @@ -43,7 +44,7 @@ page_size: u32, | ... | @@ -43,7 +44,7 @@ page_size: u32, |
| 43 | objects: std.ArrayListUnmanaged(Object) = .{}, | 44 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| 44 | | 45 | |
| 45 | sections: std.MultiArrayList(Section) = .{}, | 46 | sections: std.MultiArrayList(Section) = .{}, |
| 46 | data_directories: [16]coff.ImageDataDirectory, | 47 | data_directories: [N_DATA_DIRS]coff.ImageDataDirectory, |
| 47 | | 48 | |
| 48 | text_section_index: ?u16 = null, | 49 | text_section_index: ?u16 = null, |
| 49 | got_section_index: ?u16 = null, | 50 | got_section_index: ?u16 = null, |
| ... | @@ -114,7 +115,7 @@ const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayL | ... | @@ -114,7 +115,7 @@ const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayL |
| 114 | | 115 | |
| 115 | const default_file_alignment: u16 = 0x200; | 116 | const default_file_alignment: u16 = 0x200; |
| 116 | const default_image_base_dll: u64 = 0x10000000; | 117 | const default_image_base_dll: u64 = 0x10000000; |
| 117 | const default_image_base_exe: u64 = 0x10000; | 118 | const default_image_base_exe: u64 = 0x400000; |
| 118 | const default_size_of_stack_reserve: u32 = 0x1000000; | 119 | const default_size_of_stack_reserve: u32 = 0x1000000; |
| 119 | const default_size_of_stack_commit: u32 = 0x1000; | 120 | const default_size_of_stack_commit: u32 = 0x1000; |
| 120 | const default_size_of_heap_reserve: u32 = 0x100000; | 121 | const default_size_of_heap_reserve: u32 = 0x100000; |
| ... | @@ -210,7 +211,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff { | ... | @@ -210,7 +211,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff { |
| 210 | }, | 211 | }, |
| 211 | .ptr_width = ptr_width, | 212 | .ptr_width = ptr_width, |
| 212 | .page_size = page_size, | 213 | .page_size = page_size, |
| 213 | .data_directories = comptime mem.zeroes([16]coff.ImageDataDirectory), | 214 | .data_directories = comptime mem.zeroes([N_DATA_DIRS]coff.ImageDataDirectory), |
| 214 | }; | 215 | }; |
| 215 | | 216 | |
| 216 | const use_llvm = build_options.have_llvm and options.use_llvm; | 217 | const use_llvm = build_options.have_llvm and options.use_llvm; |
| ... | @@ -487,8 +488,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32, se | ... | @@ -487,8 +488,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32, se |
| 487 | @panic("TODO move section"); | 488 | @panic("TODO move section"); |
| 488 | } | 489 | } |
| 489 | maybe_last_atom.* = atom; | 490 | maybe_last_atom.* = atom; |
| 490 | header.virtual_size = needed_size; | 491 | // header.virtual_size = needed_size; |
| 491 | header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment); | 492 | // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment); |
| 492 | } | 493 | } |
| 493 | | 494 | |
| 494 | // if (header.getAlignment().? < alignment) { | 495 | // if (header.getAlignment().? < alignment) { |
| ... | @@ -1196,10 +1197,9 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -1196,10 +1197,9 @@ fn writeHeader(self: *Coff) !void { |
| 1196 | | 1197 | |
| 1197 | try buffer.ensureTotalCapacity(self.getSizeOfHeaders()); | 1198 | try buffer.ensureTotalCapacity(self.getSizeOfHeaders()); |
| 1198 | writer.writeAll(msdos_stub) catch unreachable; | 1199 | writer.writeAll(msdos_stub) catch unreachable; |
| 1199 | writer.writeByteNTimes(0, 4) catch unreachable; // align to 8 bytes | 1200 | mem.writeIntLittle(u32, buffer.items[0x3c..][0..4], msdos_stub.len); |
| 1200 | writer.writeAll("PE\x00\x00") catch unreachable; | | |
| 1201 | mem.writeIntLittle(u32, buffer.items[0x3c..][0..4], msdos_stub.len + 4); | | |
| 1202 | | 1201 | |
| | 1202 | writer.writeAll("PE\x00\x00") catch unreachable; |
| 1203 | var flags = coff.CoffHeaderFlags{ | 1203 | var flags = coff.CoffHeaderFlags{ |
| 1204 | .EXECUTABLE_IMAGE = 1, | 1204 | .EXECUTABLE_IMAGE = 1, |
| 1205 | .DEBUG_STRIPPED = 1, // TODO | 1205 | .DEBUG_STRIPPED = 1, // TODO |
| ... | @@ -1345,10 +1345,10 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { | ... | @@ -1345,10 +1345,10 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 1345 | if (start < headers_size) | 1345 | if (start < headers_size) |
| 1346 | return headers_size; | 1346 | return headers_size; |
| 1347 | | 1347 | |
| 1348 | const end = start + padToIdeal(size); | 1348 | const end = start + size; |
| 1349 | | 1349 | |
| 1350 | if (self.strtab_offset) |off| { | 1350 | if (self.strtab_offset) |off| { |
| 1351 | const increased_size = padToIdeal(@intCast(u32, self.strtab.len())); | 1351 | const increased_size = @intCast(u32, self.strtab.len()); |
| 1352 | const test_end = off + increased_size; | 1352 | const test_end = off + increased_size; |
| 1353 | if (end > off and start < test_end) { | 1353 | if (end > off and start < test_end) { |
| 1354 | return test_end; | 1354 | return test_end; |
| ... | @@ -1356,7 +1356,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { | ... | @@ -1356,7 +1356,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 1356 | } | 1356 | } |
| 1357 | | 1357 | |
| 1358 | for (self.sections.items(.header)) |header| { | 1358 | for (self.sections.items(.header)) |header| { |
| 1359 | const increased_size = padToIdeal(header.size_of_raw_data); | 1359 | const increased_size = header.size_of_raw_data; |
| 1360 | const test_end = header.pointer_to_raw_data + increased_size; | 1360 | const test_end = header.pointer_to_raw_data + increased_size; |
| 1361 | if (end > header.pointer_to_raw_data and start < test_end) { | 1361 | if (end > header.pointer_to_raw_data and start < test_end) { |
| 1362 | return test_end; | 1362 | return test_end; |
| ... | @@ -1389,7 +1389,7 @@ pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { | ... | @@ -1389,7 +1389,7 @@ pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1389 | } | 1389 | } |
| 1390 | | 1390 | |
| 1391 | inline fn getSizeOfHeaders(self: Coff) u32 { | 1391 | inline fn getSizeOfHeaders(self: Coff) u32 { |
| 1392 | const msdos_hdr_size = msdos_stub.len + 8; | 1392 | const msdos_hdr_size = msdos_stub.len + 4; |
| 1393 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() + | 1393 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() + |
| 1394 | self.getDataDirectoryHeadersSize() + self.getSectionHeadersSize()); | 1394 | self.getDataDirectoryHeadersSize() + self.getSectionHeadersSize()); |
| 1395 | } | 1395 | } |
| ... | @@ -1410,7 +1410,7 @@ inline fn getSectionHeadersSize(self: Coff) u32 { | ... | @@ -1410,7 +1410,7 @@ inline fn getSectionHeadersSize(self: Coff) u32 { |
| 1410 | } | 1410 | } |
| 1411 | | 1411 | |
| 1412 | inline fn getDataDirectoryHeadersOffset(self: Coff) u32 { | 1412 | inline fn getDataDirectoryHeadersOffset(self: Coff) u32 { |
| 1413 | const msdos_hdr_size = msdos_stub.len + 8; | 1413 | const msdos_hdr_size = msdos_stub.len + 4; |
| 1414 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize()); | 1414 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize()); |
| 1415 | } | 1415 | } |
| 1416 | | 1416 | |
| ... | @@ -1419,13 +1419,11 @@ inline fn getSectionHeadersOffset(self: Coff) u32 { | ... | @@ -1419,13 +1419,11 @@ inline fn getSectionHeadersOffset(self: Coff) u32 { |
| 1419 | } | 1419 | } |
| 1420 | | 1420 | |
| 1421 | inline fn getSizeOfImage(self: Coff) u32 { | 1421 | inline fn getSizeOfImage(self: Coff) u32 { |
| 1422 | var max_image_size: u32 = 0; | 1422 | var image_size: u32 = mem.alignForwardGeneric(u32, self.getSizeOfHeaders(), self.page_size); |
| 1423 | for (self.sections.items(.header)) |header| { | 1423 | for (self.sections.items(.header)) |header| { |
| 1424 | if (header.virtual_address + header.virtual_size > max_image_size) { | 1424 | image_size += mem.alignForwardGeneric(u32, header.virtual_size, self.page_size); |
| 1425 | max_image_size = header.virtual_address + header.virtual_size; | | |
| 1426 | } | | |
| 1427 | } | 1425 | } |
| 1428 | return mem.alignForwardGeneric(u32, @maximum(max_image_size, self.getSizeOfHeaders()), self.page_size); | 1426 | return image_size; |
| 1429 | } | 1427 | } |
| 1430 | | 1428 | |
| 1431 | /// Returns symbol location corresponding to the set entrypoint (if any). | 1429 | /// Returns symbol location corresponding to the set entrypoint (if any). |