mirror of
https://github.com/ziglang/zig.git
synced 2026-02-03 21:23:36 +00:00
coff: move header writing logic into flush
This commit is contained in:
parent
06371950cf
commit
3c10221030
@ -144,39 +144,10 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
|
||||
});
|
||||
self.base.file = file;
|
||||
|
||||
// TODO Write object specific relocations, COFF symbol table, then enable object file output.
|
||||
switch (options.output_mode) {
|
||||
.Exe => {},
|
||||
.Obj => return error.TODOImplementWritingObjFiles,
|
||||
.Lib => return error.TODOImplementWritingLibFiles,
|
||||
}
|
||||
|
||||
var coff_file_header_offset: u32 = 0;
|
||||
if (options.output_mode == .Exe) {
|
||||
// Write the MS-DOS stub and the PE signature
|
||||
try self.base.file.?.pwriteAll(msdos_stub ++ "PE\x00\x00", 0);
|
||||
coff_file_header_offset = msdos_stub.len + 4;
|
||||
}
|
||||
|
||||
// COFF file header
|
||||
const coff_file_header_offset: u32 = if (options.output_mode == .Exe) msdos_stub.len + 4 else 0;
|
||||
const default_offset_table_size = file_alignment;
|
||||
const data_directory_count = 0;
|
||||
var hdr_data: [112 + data_directory_count * 8 + section_table_size]u8 = undefined;
|
||||
var index: usize = 0;
|
||||
|
||||
const machine = self.base.options.target.cpu.arch.toCoffMachine();
|
||||
if (machine == .Unknown) {
|
||||
return error.UnsupportedCOFFArchitecture;
|
||||
}
|
||||
mem.writeIntLittle(u16, hdr_data[0..2], @enumToInt(machine));
|
||||
index += 2;
|
||||
|
||||
// Number of sections (we only use .got, .text)
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 2);
|
||||
index += 2;
|
||||
// TimeDateStamp (u32), PointerToSymbolTable (u32), NumberOfSymbols (u32)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
|
||||
const default_size_of_code = 0;
|
||||
const optional_header_size = switch (options.output_mode) {
|
||||
.Exe => data_directory_count * 8 + switch (self.ptr_width) {
|
||||
.p32 => @as(u16, 96),
|
||||
@ -184,218 +155,15 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
|
||||
},
|
||||
else => 0,
|
||||
};
|
||||
|
||||
const section_table_offset = coff_file_header_offset + 20 + optional_header_size;
|
||||
const default_offset_table_size = file_alignment;
|
||||
const default_size_of_code = 0;
|
||||
|
||||
self.section_data_offset = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, file_alignment);
|
||||
const section_data_relative_virtual_address = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, section_alignment);
|
||||
self.section_data_offset = mem.alignForwardGeneric(u32, section_table_offset + section_table_size, file_alignment);
|
||||
const section_data_relative_virtual_address = mem.alignForwardGeneric(u32, section_table_offset + section_table_size, section_alignment);
|
||||
self.offset_table_virtual_address = default_image_base + section_data_relative_virtual_address;
|
||||
self.offset_table_size = default_offset_table_size;
|
||||
self.section_table_offset = section_table_offset;
|
||||
self.text_section_virtual_address = default_image_base + section_data_relative_virtual_address + section_alignment;
|
||||
self.text_section_size = default_size_of_code;
|
||||
|
||||
// Size of file when loaded in memory
|
||||
const size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - default_image_base + default_size_of_code, section_alignment);
|
||||
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], optional_header_size);
|
||||
index += 2;
|
||||
|
||||
// Characteristics
|
||||
var characteristics: std.coff.CoffHeaderFlags = .{
|
||||
.DEBUG_STRIPPED = 1, // TODO remove debug info stripped flag when necessary
|
||||
.RELOCS_STRIPPED = 1,
|
||||
};
|
||||
if (options.output_mode == .Exe) {
|
||||
characteristics.EXECUTABLE_IMAGE = 1;
|
||||
}
|
||||
switch (self.ptr_width) {
|
||||
.p32 => characteristics.@"32BIT_MACHINE" = 1,
|
||||
.p64 => characteristics.LARGE_ADDRESS_AWARE = 1,
|
||||
}
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], @bitCast(u16, characteristics));
|
||||
index += 2;
|
||||
|
||||
assert(index == 20);
|
||||
try self.base.file.?.pwriteAll(hdr_data[0..index], coff_file_header_offset);
|
||||
|
||||
if (options.output_mode == .Exe) {
|
||||
self.optional_header_offset = coff_file_header_offset + 20;
|
||||
// Optional header
|
||||
index = 0;
|
||||
mem.writeIntLittle(u16, hdr_data[0..2], switch (self.ptr_width) {
|
||||
.p32 => @as(u16, 0x10b),
|
||||
.p64 => 0x20b,
|
||||
});
|
||||
index += 2;
|
||||
|
||||
// Linker version (u8 + u8)
|
||||
mem.set(u8, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
|
||||
// SizeOfCode (UNUSED, u32), SizeOfInitializedData (u32), SizeOfUninitializedData (u32), AddressOfEntryPoint (u32), BaseOfCode (UNUSED, u32)
|
||||
mem.set(u8, hdr_data[index..][0..20], 0);
|
||||
index += 20;
|
||||
|
||||
if (self.ptr_width == .p32) {
|
||||
// Base of data relative to the image base (UNUSED)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
|
||||
// Image base address
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
// Image base address
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], default_image_base);
|
||||
index += 8;
|
||||
}
|
||||
|
||||
// Section alignment
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], section_alignment);
|
||||
index += 4;
|
||||
// File alignment
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], file_alignment);
|
||||
index += 4;
|
||||
// Required OS version, 6.0 is vista
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 6);
|
||||
index += 2;
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
// Image version
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
// Required subsystem version, same as OS version
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 6);
|
||||
index += 2;
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
// Reserved zeroes (u32)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], size_of_image);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset);
|
||||
index += 4;
|
||||
// CheckSum (u32)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
// Subsystem, TODO: Let users specify the subsystem, always CUI for now
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 3);
|
||||
index += 2;
|
||||
// DLL characteristics
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0x0);
|
||||
index += 2;
|
||||
|
||||
switch (self.ptr_width) {
|
||||
.p32 => {
|
||||
// Size of stack reserve + commit
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000_000);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000);
|
||||
index += 4;
|
||||
// Size of heap reserve + commit
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x100_000);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000);
|
||||
index += 4;
|
||||
},
|
||||
.p64 => {
|
||||
// Size of stack reserve + commit
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000_000);
|
||||
index += 8;
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000);
|
||||
index += 8;
|
||||
// Size of heap reserve + commit
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x100_000);
|
||||
index += 8;
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000);
|
||||
index += 8;
|
||||
},
|
||||
}
|
||||
|
||||
// Reserved zeroes
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
|
||||
// Number of data directories
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], data_directory_count);
|
||||
index += 4;
|
||||
// Initialize data directories to zero
|
||||
mem.set(u8, hdr_data[index..][0 .. data_directory_count * 8], 0);
|
||||
index += data_directory_count * 8;
|
||||
|
||||
assert(index == optional_header_size);
|
||||
}
|
||||
|
||||
// Write section table.
|
||||
// First, the .got section
|
||||
hdr_data[index..][0..8].* = ".got\x00\x00\x00\x00".*;
|
||||
index += 8;
|
||||
if (options.output_mode == .Exe) {
|
||||
// Virtual size (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size);
|
||||
index += 4;
|
||||
// Virtual address (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
mem.set(u8, hdr_data[index..][0..8], 0);
|
||||
index += 8;
|
||||
}
|
||||
// Size of raw data (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size);
|
||||
index += 4;
|
||||
// File pointer to the start of the section
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset);
|
||||
index += 4;
|
||||
// Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
// Section flags
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], @bitCast(u32, std.coff.SectionHeaderFlags{
|
||||
.CNT_INITIALIZED_DATA = 1,
|
||||
.MEM_READ = 1,
|
||||
}));
|
||||
index += 4;
|
||||
// Then, the .text section
|
||||
hdr_data[index..][0..8].* = ".text\x00\x00\x00".*;
|
||||
index += 8;
|
||||
if (options.output_mode == .Exe) {
|
||||
// Virtual size (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code);
|
||||
index += 4;
|
||||
// Virtual address (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
mem.set(u8, hdr_data[index..][0..8], 0);
|
||||
index += 8;
|
||||
}
|
||||
// Size of raw data (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code);
|
||||
index += 4;
|
||||
// File pointer to the start of the section
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset + default_offset_table_size);
|
||||
index += 4;
|
||||
// Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
// Section flags
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], @bitCast(u32, std.coff.SectionHeaderFlags{
|
||||
.CNT_CODE = 1,
|
||||
.MEM_EXECUTE = 1,
|
||||
.MEM_READ = 1,
|
||||
.MEM_WRITE = 1,
|
||||
}));
|
||||
index += 4;
|
||||
|
||||
assert(index == optional_header_size + section_table_size);
|
||||
try self.base.file.?.pwriteAll(hdr_data[0..index], self.optional_header_offset);
|
||||
try self.base.file.?.setEndPos(self.section_data_offset + default_offset_table_size + default_size_of_code);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -728,6 +496,12 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
|
||||
if (decl.val.tag() == .extern_fn) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
}
|
||||
if (decl.val.castTag(.variable)) |payload| {
|
||||
const variable = payload.data;
|
||||
if (variable.is_extern) {
|
||||
return; // TODO Should we do more when front-end analyzed extern decl?
|
||||
}
|
||||
}
|
||||
|
||||
// TODO COFF/PE debug information
|
||||
// TODO Implement exports
|
||||
@ -735,9 +509,10 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .none, .{
|
||||
.parent_atom_index = 0,
|
||||
});
|
||||
@ -862,15 +637,14 @@ pub fn updateDeclExports(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (mem.eql(u8, exp.options.name, "_start")) {
|
||||
if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
|
||||
self.entry_addr = decl.link.coff.getVAddr(self.*) - default_image_base;
|
||||
} else {
|
||||
try module.failed_exports.ensureUnusedCapacity(module.gpa, 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: Exports other than '_start'", .{}),
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "Unimplemented: Exports other than 'wWinMainCRTStartup'", .{}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -884,14 +658,13 @@ pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !vo
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (build_options.have_llvm and self.base.options.use_lld) {
|
||||
const use_lld = build_options.have_llvm and self.base.options.use_lld;
|
||||
if (use_lld) {
|
||||
return self.linkWithLLD(comp, prog_node);
|
||||
} else {
|
||||
switch (self.base.options.effectiveOutputMode()) {
|
||||
.Exe, .Obj => {},
|
||||
.Lib => return error.TODOImplementWritingLibFiles,
|
||||
}
|
||||
return self.flushModule(comp, prog_node);
|
||||
}
|
||||
switch (self.base.options.output_mode) {
|
||||
.Exe, .Obj => return self.flushModule(comp, prog_node),
|
||||
.Lib => return error.TODOImplementWritingLibFiles,
|
||||
}
|
||||
}
|
||||
|
||||
@ -909,6 +682,238 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
sub_prog_node.activate();
|
||||
defer sub_prog_node.end();
|
||||
|
||||
const output_mode = self.base.options.output_mode;
|
||||
log.debug("in flushModule with {}", .{output_mode});
|
||||
|
||||
var coff_file_header_offset: u32 = 0;
|
||||
if (output_mode == .Exe) {
|
||||
// Write the MS-DOS stub and the PE signature
|
||||
try self.base.file.?.pwriteAll(msdos_stub ++ "PE\x00\x00", 0);
|
||||
coff_file_header_offset = msdos_stub.len + 4;
|
||||
}
|
||||
|
||||
// COFF file header
|
||||
const data_directory_count = 0;
|
||||
var hdr_data: [112 + data_directory_count * 8 + section_table_size]u8 = undefined;
|
||||
var index: usize = 0;
|
||||
|
||||
const machine = self.base.options.target.cpu.arch.toCoffMachine();
|
||||
if (machine == .Unknown) {
|
||||
return error.UnsupportedCOFFArchitecture;
|
||||
}
|
||||
mem.writeIntLittle(u16, hdr_data[0..2], @enumToInt(machine));
|
||||
index += 2;
|
||||
|
||||
// Number of sections (we only use .got, .text)
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 2);
|
||||
index += 2;
|
||||
// TimeDateStamp (u32), PointerToSymbolTable (u32), NumberOfSymbols (u32)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
|
||||
const optional_header_size = switch (output_mode) {
|
||||
.Exe => data_directory_count * 8 + switch (self.ptr_width) {
|
||||
.p32 => @as(u16, 96),
|
||||
.p64 => 112,
|
||||
},
|
||||
else => 0,
|
||||
};
|
||||
|
||||
const default_offset_table_size = file_alignment;
|
||||
const default_size_of_code = 0;
|
||||
|
||||
// Size of file when loaded in memory
|
||||
const size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - default_image_base + default_size_of_code, section_alignment);
|
||||
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], optional_header_size);
|
||||
index += 2;
|
||||
|
||||
// Characteristics
|
||||
var characteristics: u16 = std.coff.IMAGE_FILE_DEBUG_STRIPPED | std.coff.IMAGE_FILE_RELOCS_STRIPPED; // TODO Remove debug info stripped flag when necessary
|
||||
if (output_mode == .Exe) {
|
||||
characteristics |= std.coff.IMAGE_FILE_EXECUTABLE_IMAGE;
|
||||
}
|
||||
switch (self.ptr_width) {
|
||||
.p32 => characteristics |= std.coff.IMAGE_FILE_32BIT_MACHINE,
|
||||
.p64 => characteristics |= std.coff.IMAGE_FILE_LARGE_ADDRESS_AWARE,
|
||||
}
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], characteristics);
|
||||
index += 2;
|
||||
|
||||
assert(index == 20);
|
||||
try self.base.file.?.pwriteAll(hdr_data[0..index], coff_file_header_offset);
|
||||
|
||||
if (output_mode == .Exe) {
|
||||
self.optional_header_offset = coff_file_header_offset + 20;
|
||||
// Optional header
|
||||
index = 0;
|
||||
mem.writeIntLittle(u16, hdr_data[0..2], switch (self.ptr_width) {
|
||||
.p32 => @as(u16, 0x10b),
|
||||
.p64 => 0x20b,
|
||||
});
|
||||
index += 2;
|
||||
|
||||
// Linker version (u8 + u8)
|
||||
mem.set(u8, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
|
||||
// SizeOfCode (UNUSED, u32), SizeOfInitializedData (u32), SizeOfUninitializedData (u32), AddressOfEntryPoint (u32), BaseOfCode (UNUSED, u32)
|
||||
mem.set(u8, hdr_data[index..][0..20], 0);
|
||||
index += 20;
|
||||
|
||||
if (self.ptr_width == .p32) {
|
||||
// Base of data relative to the image base (UNUSED)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
|
||||
// Image base address
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
// Image base address
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], default_image_base);
|
||||
index += 8;
|
||||
}
|
||||
|
||||
// Section alignment
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], section_alignment);
|
||||
index += 4;
|
||||
// File alignment
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], file_alignment);
|
||||
index += 4;
|
||||
// Required OS version, 6.0 is vista
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 6);
|
||||
index += 2;
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
// Image version
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
// Required subsystem version, same as OS version
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 6);
|
||||
index += 2;
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0);
|
||||
index += 2;
|
||||
// Reserved zeroes (u32)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], size_of_image);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset);
|
||||
index += 4;
|
||||
// CheckSum (u32)
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
// Subsystem, TODO: Let users specify the subsystem, always CUI for now
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 3);
|
||||
index += 2;
|
||||
// DLL characteristics
|
||||
mem.writeIntLittle(u16, hdr_data[index..][0..2], 0x0);
|
||||
index += 2;
|
||||
|
||||
switch (self.ptr_width) {
|
||||
.p32 => {
|
||||
// Size of stack reserve + commit
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000_000);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000);
|
||||
index += 4;
|
||||
// Size of heap reserve + commit
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x100_000);
|
||||
index += 4;
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000);
|
||||
index += 4;
|
||||
},
|
||||
.p64 => {
|
||||
// Size of stack reserve + commit
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000_000);
|
||||
index += 8;
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000);
|
||||
index += 8;
|
||||
// Size of heap reserve + commit
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x100_000);
|
||||
index += 8;
|
||||
mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000);
|
||||
index += 8;
|
||||
},
|
||||
}
|
||||
|
||||
// Reserved zeroes
|
||||
mem.set(u8, hdr_data[index..][0..4], 0);
|
||||
index += 4;
|
||||
|
||||
// Number of data directories
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], data_directory_count);
|
||||
index += 4;
|
||||
// Initialize data directories to zero
|
||||
mem.set(u8, hdr_data[index..][0 .. data_directory_count * 8], 0);
|
||||
index += data_directory_count * 8;
|
||||
|
||||
assert(index == optional_header_size);
|
||||
}
|
||||
|
||||
// Write section table.
|
||||
// First, the .got section
|
||||
hdr_data[index..][0..8].* = ".got\x00\x00\x00\x00".*;
|
||||
index += 8;
|
||||
if (output_mode == .Exe) {
|
||||
// Virtual size (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size);
|
||||
index += 4;
|
||||
// Virtual address (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
mem.set(u8, hdr_data[index..][0..8], 0);
|
||||
index += 8;
|
||||
}
|
||||
// Size of raw data (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size);
|
||||
index += 4;
|
||||
// File pointer to the start of the section
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset);
|
||||
index += 4;
|
||||
// Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
// Section flags
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], std.coff.IMAGE_SCN_CNT_INITIALIZED_DATA | std.coff.IMAGE_SCN_MEM_READ);
|
||||
index += 4;
|
||||
// Then, the .text section
|
||||
hdr_data[index..][0..8].* = ".text\x00\x00\x00".*;
|
||||
index += 8;
|
||||
if (output_mode == .Exe) {
|
||||
// Virtual size (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code);
|
||||
index += 4;
|
||||
// Virtual address (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - default_image_base);
|
||||
index += 4;
|
||||
} else {
|
||||
mem.set(u8, hdr_data[index..][0..8], 0);
|
||||
index += 8;
|
||||
}
|
||||
// Size of raw data (u32)
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code);
|
||||
index += 4;
|
||||
// File pointer to the start of the section
|
||||
mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset + default_offset_table_size);
|
||||
index += 4;
|
||||
// Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16)
|
||||
mem.set(u8, hdr_data[index..][0..12], 0);
|
||||
index += 12;
|
||||
// Section flags
|
||||
mem.writeIntLittle(
|
||||
u32,
|
||||
hdr_data[index..][0..4],
|
||||
std.coff.IMAGE_SCN_CNT_CODE | std.coff.IMAGE_SCN_MEM_EXECUTE | std.coff.IMAGE_SCN_MEM_READ | std.coff.IMAGE_SCN_MEM_WRITE,
|
||||
);
|
||||
index += 4;
|
||||
|
||||
assert(index == optional_header_size + section_table_size);
|
||||
try self.base.file.?.pwriteAll(hdr_data[0..index], self.optional_header_offset);
|
||||
try self.base.file.?.setEndPos(self.section_data_offset + default_offset_table_size + default_size_of_code);
|
||||
|
||||
if (self.text_section_size_dirty) {
|
||||
// Write the new raw size in the .text header
|
||||
var buf: [4]u8 = undefined;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user