mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Coff: delete
This commit is contained in:
parent
e1f3fc6ce2
commit
1fa11e0954
9 changed files with 85 additions and 3294 deletions
|
|
@ -561,7 +561,6 @@ set(ZIG_STAGE2_SOURCES
|
||||||
src/libs/libunwind.zig
|
src/libs/libunwind.zig
|
||||||
src/link.zig
|
src/link.zig
|
||||||
src/link/C.zig
|
src/link/C.zig
|
||||||
src/link/Coff.zig
|
|
||||||
src/link/Dwarf.zig
|
src/link/Dwarf.zig
|
||||||
src/link/Elf.zig
|
src/link/Elf.zig
|
||||||
src/link/Elf/Archive.zig
|
src/link/Elf/Archive.zig
|
||||||
|
|
|
||||||
|
|
@ -3226,7 +3226,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
|
||||||
.root_dir = comp.dirs.local_cache,
|
.root_dir = comp.dirs.local_cache,
|
||||||
.sub_path = try fs.path.join(arena, &.{ o_sub_path, comp.emit_bin.? }),
|
.sub_path = try fs.path.join(arena, &.{ o_sub_path, comp.emit_bin.? }),
|
||||||
};
|
};
|
||||||
const result: link.File.OpenError!void = switch (need_writable_dance) {
|
const result: (link.File.OpenError || error{HotSwapUnavailableOnHostOperatingSystem})!void = switch (need_writable_dance) {
|
||||||
.no => {},
|
.no => {},
|
||||||
.lf_only => lf.makeWritable(),
|
.lf_only => lf.makeWritable(),
|
||||||
.lf_and_debug => res: {
|
.lf_and_debug => res: {
|
||||||
|
|
|
||||||
|
|
@ -438,8 +438,6 @@ pub fn resolve(options: Options) ResolveError!Config {
|
||||||
|
|
||||||
if (options.use_new_linker) |x| break :b x;
|
if (options.use_new_linker) |x| break :b x;
|
||||||
|
|
||||||
if (target.ofmt == .coff) break :b true;
|
|
||||||
|
|
||||||
break :b options.incremental;
|
break :b options.incremental;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -978,21 +978,6 @@ pub fn genNavRef(
|
||||||
},
|
},
|
||||||
.link_once => unreachable,
|
.link_once => unreachable,
|
||||||
}
|
}
|
||||||
} else if (lf.cast(.coff)) |coff_file| {
|
|
||||||
// TODO audit this
|
|
||||||
switch (linkage) {
|
|
||||||
.internal => {
|
|
||||||
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
|
|
||||||
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
|
|
||||||
return .{ .sym_index = sym_index };
|
|
||||||
},
|
|
||||||
.strong, .weak => {
|
|
||||||
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
|
||||||
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
|
|
||||||
return .{ .sym_index = global_index };
|
|
||||||
},
|
|
||||||
.link_once => unreachable,
|
|
||||||
}
|
|
||||||
} else if (lf.cast(.coff2)) |coff| {
|
} else if (lf.cast(.coff2)) |coff| {
|
||||||
return .{ .sym_index = @intFromEnum(try coff.navSymbol(zcu, nav_index)) };
|
return .{ .sym_index = @intFromEnum(try coff.navSymbol(zcu, nav_index)) };
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,6 @@ pub fn emit(
|
||||||
else if (lf.cast(.macho)) |mf|
|
else if (lf.cast(.macho)) |mf|
|
||||||
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
|
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
|
||||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
||||||
else if (lf.cast(.coff)) |cf|
|
|
||||||
if (cf.getOrCreateAtomForLazySymbol(pt, lazy_reloc.symbol)) |atom|
|
|
||||||
cf.getAtom(atom).getSymbolIndex().?
|
|
||||||
else |err|
|
|
||||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
|
||||||
else
|
else
|
||||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||||
mir.body[lazy_reloc.reloc.label],
|
mir.body[lazy_reloc.reloc.label],
|
||||||
|
|
@ -154,8 +149,6 @@ pub fn emit(
|
||||||
try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||||
else if (lf.cast(.macho)) |mf|
|
else if (lf.cast(.macho)) |mf|
|
||||||
try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||||
else if (lf.cast(.coff)) |cf|
|
|
||||||
try cf.getGlobalSymbol(std.mem.span(global_reloc.name), "compiler_rt")
|
|
||||||
else
|
else
|
||||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||||
mir.body[global_reloc.reloc.label],
|
mir.body[global_reloc.reloc.label],
|
||||||
|
|
|
||||||
|
|
@ -170,11 +170,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||||
else if (emit.bin_file.cast(.macho)) |macho_file|
|
else if (emit.bin_file.cast(.macho)) |macho_file|
|
||||||
macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
|
macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
|
||||||
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
|
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
|
||||||
else if (emit.bin_file.cast(.coff)) |coff_file|
|
|
||||||
if (coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym)) |atom|
|
|
||||||
coff_file.getAtom(atom).getSymbolIndex().?
|
|
||||||
else |err|
|
|
||||||
return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
|
|
||||||
else if (emit.bin_file.cast(.coff2)) |elf|
|
else if (emit.bin_file.cast(.coff2)) |elf|
|
||||||
@intFromEnum(try elf.lazySymbol(lazy_sym))
|
@intFromEnum(try elf.lazySymbol(lazy_sym))
|
||||||
else
|
else
|
||||||
|
|
@ -190,8 +185,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||||
.type = .FUNC,
|
.type = .FUNC,
|
||||||
})) else if (emit.bin_file.cast(.macho)) |macho_file|
|
})) else if (emit.bin_file.cast(.macho)) |macho_file|
|
||||||
try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
|
try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
|
||||||
else if (emit.bin_file.cast(.coff)) |coff_file|
|
|
||||||
try coff_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, "compiler_rt")
|
|
||||||
else if (emit.bin_file.cast(.coff2)) |coff| @intFromEnum(try coff.globalSymbol(
|
else if (emit.bin_file.cast(.coff2)) |coff| @intFromEnum(try coff.globalSymbol(
|
||||||
extern_func.toSlice(&emit.lower.mir).?,
|
extern_func.toSlice(&emit.lower.mir).?,
|
||||||
switch (comp.compiler_rt_strat) {
|
switch (comp.compiler_rt_strat) {
|
||||||
|
|
@ -211,9 +204,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||||
switch (lowered_inst.encoding.mnemonic) {
|
switch (lowered_inst.encoding.mnemonic) {
|
||||||
.call => {
|
.call => {
|
||||||
reloc.target.type = .branch;
|
reloc.target.type = .branch;
|
||||||
if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{
|
try emit.encodeInst(lowered_inst, reloc_info);
|
||||||
.{ .mem = .initRip(.ptr, 0) },
|
|
||||||
}, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info);
|
|
||||||
continue :lowered_inst;
|
continue :lowered_inst;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|
@ -290,37 +281,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||||
}, emit.lower.target), reloc_info),
|
}, emit.lower.target), reloc_info),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
} else if (emit.bin_file.cast(.coff)) |_| {
|
|
||||||
if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
|
|
||||||
.lea => try emit.encodeInst(try .new(.none, .mov, &.{
|
|
||||||
lowered_inst.ops[0],
|
|
||||||
.{ .mem = .initRip(.ptr, 0) },
|
|
||||||
}, emit.lower.target), reloc_info),
|
|
||||||
.mov => {
|
|
||||||
const dst_reg = lowered_inst.ops[0].reg.to64();
|
|
||||||
try emit.encodeInst(try .new(.none, .mov, &.{
|
|
||||||
.{ .reg = dst_reg },
|
|
||||||
.{ .mem = .initRip(.ptr, 0) },
|
|
||||||
}, emit.lower.target), reloc_info);
|
|
||||||
try emit.encodeInst(try .new(.none, .mov, &.{
|
|
||||||
lowered_inst.ops[0],
|
|
||||||
.{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
|
|
||||||
.reg = dst_reg,
|
|
||||||
} }) },
|
|
||||||
}, emit.lower.target), &.{});
|
|
||||||
},
|
|
||||||
else => unreachable,
|
|
||||||
} else switch (lowered_inst.encoding.mnemonic) {
|
|
||||||
.lea => try emit.encodeInst(try .new(.none, .lea, &.{
|
|
||||||
lowered_inst.ops[0],
|
|
||||||
.{ .mem = .initRip(.none, 0) },
|
|
||||||
}, emit.lower.target), reloc_info),
|
|
||||||
.mov => try emit.encodeInst(try .new(.none, .mov, &.{
|
|
||||||
lowered_inst.ops[0],
|
|
||||||
.{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
|
|
||||||
}, emit.lower.target), reloc_info),
|
|
||||||
else => unreachable,
|
|
||||||
}
|
|
||||||
} else if (emit.bin_file.cast(.coff2)) |_| {
|
} else if (emit.bin_file.cast(.coff2)) |_| {
|
||||||
switch (lowered_inst.encoding.mnemonic) {
|
switch (lowered_inst.encoding.mnemonic) {
|
||||||
.lea => try emit.encodeInst(try .new(.none, .lea, &.{
|
.lea => try emit.encodeInst(try .new(.none, .lea, &.{
|
||||||
|
|
@ -820,22 +780,7 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||||
@enumFromInt(reloc.target.index),
|
@enumFromInt(reloc.target.index),
|
||||||
reloc.off,
|
reloc.off,
|
||||||
.{ .X86_64 = .@"32" },
|
.{ .X86_64 = .@"32" },
|
||||||
) else if (emit.bin_file.cast(.coff)) |coff_file| {
|
) else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
|
||||||
const atom_index = coff_file.getAtomIndexForSymbol(
|
|
||||||
.{ .sym_index = emit.atom_index, .file = null },
|
|
||||||
).?;
|
|
||||||
try coff_file.addRelocation(atom_index, .{
|
|
||||||
.type = if (reloc.target.is_extern) .got else .direct,
|
|
||||||
.target = if (reloc.target.is_extern)
|
|
||||||
coff_file.getGlobalByIndex(reloc.target.index)
|
|
||||||
else
|
|
||||||
.{ .sym_index = reloc.target.index, .file = null },
|
|
||||||
.offset = end_offset - 4,
|
|
||||||
.addend = @intCast(reloc.off),
|
|
||||||
.pcrel = true,
|
|
||||||
.length = 2,
|
|
||||||
});
|
|
||||||
} else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
|
|
||||||
@enumFromInt(emit.atom_index),
|
@enumFromInt(emit.atom_index),
|
||||||
end_offset - 4,
|
end_offset - 4,
|
||||||
@enumFromInt(reloc.target.index),
|
@enumFromInt(reloc.target.index),
|
||||||
|
|
@ -873,21 +818,6 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||||
.symbolnum = @intCast(reloc.target.index),
|
.symbolnum = @intCast(reloc.target.index),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (emit.bin_file.cast(.coff)) |coff_file| {
|
|
||||||
const atom_index = coff_file.getAtomIndexForSymbol(
|
|
||||||
.{ .sym_index = emit.atom_index, .file = null },
|
|
||||||
).?;
|
|
||||||
try coff_file.addRelocation(atom_index, .{
|
|
||||||
.type = if (reloc.target.is_extern) .import else .got,
|
|
||||||
.target = if (reloc.target.is_extern)
|
|
||||||
coff_file.getGlobalByIndex(reloc.target.index)
|
|
||||||
else
|
|
||||||
.{ .sym_index = reloc.target.index, .file = null },
|
|
||||||
.offset = end_offset - 4,
|
|
||||||
.addend = @intCast(reloc.off),
|
|
||||||
.pcrel = true,
|
|
||||||
.length = 2,
|
|
||||||
});
|
|
||||||
} else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
|
} else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
|
||||||
@enumFromInt(emit.atom_index),
|
@enumFromInt(emit.atom_index),
|
||||||
end_offset - 4,
|
end_offset - 4,
|
||||||
|
|
|
||||||
18
src/link.zig
18
src/link.zig
|
|
@ -574,16 +574,13 @@ pub const File = struct {
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
switch (base.tag) {
|
switch (base.tag) {
|
||||||
.lld => assert(base.file == null),
|
.lld => assert(base.file == null),
|
||||||
.coff, .elf, .macho, .wasm, .goff, .xcoff => {
|
.elf, .macho, .wasm, .goff, .xcoff => {
|
||||||
if (base.file != null) return;
|
if (base.file != null) return;
|
||||||
dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
||||||
const emit = base.emit;
|
const emit = base.emit;
|
||||||
if (base.child_pid) |pid| {
|
if (base.child_pid) |pid| {
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
const coff_file = base.cast(.coff).?;
|
return error.HotSwapUnavailableOnHostOperatingSystem;
|
||||||
coff_file.ptraceAttach(pid) catch |err| {
|
|
||||||
log.warn("attaching failed with error: {s}", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
// If we try to open the output file in write mode while it is running,
|
// If we try to open the output file in write mode while it is running,
|
||||||
// it will return ETXTBSY. So instead, we copy the file, atomically rename it
|
// it will return ETXTBSY. So instead, we copy the file, atomically rename it
|
||||||
|
|
@ -671,7 +668,7 @@ pub const File = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.coff, .macho, .wasm, .goff, .xcoff => if (base.file) |f| {
|
.macho, .wasm, .goff, .xcoff => if (base.file) |f| {
|
||||||
dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
||||||
f.close();
|
f.close();
|
||||||
base.file = null;
|
base.file = null;
|
||||||
|
|
@ -684,10 +681,6 @@ pub const File = struct {
|
||||||
log.warn("detaching failed with error: {s}", .{@errorName(err)});
|
log.warn("detaching failed with error: {s}", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.windows => {
|
|
||||||
const coff_file = base.cast(.coff).?;
|
|
||||||
coff_file.ptraceDetach(pid);
|
|
||||||
},
|
|
||||||
else => return error.HotSwapUnavailableOnHostOperatingSystem,
|
else => return error.HotSwapUnavailableOnHostOperatingSystem,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1157,7 +1150,6 @@ pub const File = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const Tag = enum {
|
pub const Tag = enum {
|
||||||
coff,
|
|
||||||
coff2,
|
coff2,
|
||||||
elf,
|
elf,
|
||||||
elf2,
|
elf2,
|
||||||
|
|
@ -1172,7 +1164,6 @@ pub const File = struct {
|
||||||
|
|
||||||
pub fn Type(comptime tag: Tag) type {
|
pub fn Type(comptime tag: Tag) type {
|
||||||
return switch (tag) {
|
return switch (tag) {
|
||||||
.coff => Coff,
|
|
||||||
.coff2 => Coff2,
|
.coff2 => Coff2,
|
||||||
.elf => Elf,
|
.elf => Elf,
|
||||||
.elf2 => Elf2,
|
.elf2 => Elf2,
|
||||||
|
|
@ -1189,7 +1180,7 @@ pub const File = struct {
|
||||||
|
|
||||||
fn fromObjectFormat(ofmt: std.Target.ObjectFormat, use_new_linker: bool) Tag {
|
fn fromObjectFormat(ofmt: std.Target.ObjectFormat, use_new_linker: bool) Tag {
|
||||||
return switch (ofmt) {
|
return switch (ofmt) {
|
||||||
.coff => if (use_new_linker) .coff2 else .coff,
|
.coff => .coff2,
|
||||||
.elf => if (use_new_linker) .elf2 else .elf,
|
.elf => if (use_new_linker) .elf2 else .elf,
|
||||||
.macho => .macho,
|
.macho => .macho,
|
||||||
.wasm => .wasm,
|
.wasm => .wasm,
|
||||||
|
|
@ -1274,7 +1265,6 @@ pub const File = struct {
|
||||||
|
|
||||||
pub const Lld = @import("link/Lld.zig");
|
pub const Lld = @import("link/Lld.zig");
|
||||||
pub const C = @import("link/C.zig");
|
pub const C = @import("link/C.zig");
|
||||||
pub const Coff = @import("link/Coff.zig");
|
|
||||||
pub const Coff2 = @import("link/Coff2.zig");
|
pub const Coff2 = @import("link/Coff2.zig");
|
||||||
pub const Elf = @import("link/Elf.zig");
|
pub const Elf = @import("link/Elf.zig");
|
||||||
pub const Elf2 = @import("link/Elf2.zig");
|
pub const Elf2 = @import("link/Elf2.zig");
|
||||||
|
|
|
||||||
3169
src/link/Coff.zig
3169
src/link/Coff.zig
File diff suppressed because it is too large
Load diff
|
|
@ -28,6 +28,73 @@ relocs: std.ArrayList(Reloc),
|
||||||
/// This is hiding actual bugs with global symbols! Reconsider once they are implemented correctly.
|
/// This is hiding actual bugs with global symbols! Reconsider once they are implemented correctly.
|
||||||
entry_hack: Symbol.Index,
|
entry_hack: Symbol.Index,
|
||||||
|
|
||||||
|
pub const default_file_alignment: u16 = 0x200;
|
||||||
|
pub const default_size_of_stack_reserve: u32 = 0x1000000;
|
||||||
|
pub const default_size_of_stack_commit: u32 = 0x1000;
|
||||||
|
pub const default_size_of_heap_reserve: u32 = 0x100000;
|
||||||
|
pub const default_size_of_heap_commit: u32 = 0x1000;
|
||||||
|
|
||||||
|
/// This is the start of a Portable Executable (PE) file.
|
||||||
|
/// It starts with a MS-DOS header followed by a MS-DOS stub program.
|
||||||
|
/// This data does not change so we include it as follows in all binaries.
|
||||||
|
///
|
||||||
|
/// In this context,
|
||||||
|
/// A "paragraph" is 16 bytes.
|
||||||
|
/// A "page" is 512 bytes.
|
||||||
|
/// A "long" is 4 bytes.
|
||||||
|
/// A "word" is 2 bytes.
|
||||||
|
pub const msdos_stub: [120]u8 = .{
|
||||||
|
'M', 'Z', // Magic number. Stands for Mark Zbikowski (designer of the MS-DOS executable format).
|
||||||
|
0x78, 0x00, // Number of bytes in the last page. This matches the size of this entire MS-DOS stub.
|
||||||
|
0x01, 0x00, // Number of pages.
|
||||||
|
0x00, 0x00, // Number of entries in the relocation table.
|
||||||
|
0x04, 0x00, // The number of paragraphs taken up by the header. 4 * 16 = 64, which matches the header size (all bytes before the MS-DOS stub program).
|
||||||
|
0x00, 0x00, // The number of paragraphs required by the program.
|
||||||
|
0x00, 0x00, // The number of paragraphs requested by the program.
|
||||||
|
0x00, 0x00, // Initial value for SS (relocatable segment address).
|
||||||
|
0x00, 0x00, // Initial value for SP.
|
||||||
|
0x00, 0x00, // Checksum.
|
||||||
|
0x00, 0x00, // Initial value for IP.
|
||||||
|
0x00, 0x00, // Initial value for CS (relocatable segment address).
|
||||||
|
0x40, 0x00, // Absolute offset to relocation table. 64 matches the header size (all bytes before the MS-DOS stub program).
|
||||||
|
0x00, 0x00, // Overlay number. Zero means this is the main executable.
|
||||||
|
}
|
||||||
|
// Reserved words.
|
||||||
|
++ .{ 0x00, 0x00 } ** 4
|
||||||
|
// OEM-related fields.
|
||||||
|
++ .{
|
||||||
|
0x00, 0x00, // OEM identifier.
|
||||||
|
0x00, 0x00, // OEM information.
|
||||||
|
}
|
||||||
|
// Reserved words.
|
||||||
|
++ .{ 0x00, 0x00 } ** 10
|
||||||
|
// Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub.
|
||||||
|
++ .{ 0x78, 0x00, 0x00, 0x00 }
|
||||||
|
// What follows is a 16-bit x86 MS-DOS program of 7 instructions that prints the bytes after these instructions and then exits.
|
||||||
|
++ .{
|
||||||
|
// Set the value of the data segment to the same value as the code segment.
|
||||||
|
0x0e, // push cs
|
||||||
|
0x1f, // pop ds
|
||||||
|
// Set the DX register to the address of the message.
|
||||||
|
// If you count all bytes of these 7 instructions you get 14, so that's the address of what's after these instructions.
|
||||||
|
0xba, 14, 0x00, // mov dx, 14
|
||||||
|
// Set AH to the system call code for printing a message.
|
||||||
|
0xb4, 0x09, // mov ah, 0x09
|
||||||
|
// Perform the system call to print the message.
|
||||||
|
0xcd, 0x21, // int 0x21
|
||||||
|
// Set AH to 0x4c which is the system call code for exiting, and set AL to 0x01 which is the exit code.
|
||||||
|
0xb8, 0x01, 0x4c, // mov ax, 0x4c01
|
||||||
|
// Peform the system call to exit the program with exit code 1.
|
||||||
|
0xcd, 0x21, // int 0x21
|
||||||
|
}
|
||||||
|
// Message to print.
|
||||||
|
++ "This program cannot be run in DOS mode.".*
|
||||||
|
// Message terminators.
|
||||||
|
++ .{
|
||||||
|
'$', // We do not pass a length to the print system call; the string is terminated by this character.
|
||||||
|
0x00, 0x00, // Terminating zero bytes.
|
||||||
|
};
|
||||||
|
|
||||||
pub const Node = union(enum) {
|
pub const Node = union(enum) {
|
||||||
file,
|
file,
|
||||||
header,
|
header,
|
||||||
|
|
@ -613,8 +680,7 @@ fn initHeaders(
|
||||||
) !void {
|
) !void {
|
||||||
const comp = coff.base.comp;
|
const comp = coff.base.comp;
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
const file_align: std.mem.Alignment =
|
const file_align: std.mem.Alignment = comptime .fromByteUnits(default_file_alignment);
|
||||||
comptime .fromByteUnits(link.File.Coff.default_file_alignment);
|
|
||||||
const target_endian = coff.targetEndian();
|
const target_endian = coff.targetEndian();
|
||||||
|
|
||||||
const optional_header_size: u16 = if (is_image) switch (magic) {
|
const optional_header_size: u16 = if (is_image) switch (magic) {
|
||||||
|
|
@ -639,15 +705,14 @@ fn initHeaders(
|
||||||
|
|
||||||
const signature_ni = Node.known.signature;
|
const signature_ni = Node.known.signature;
|
||||||
assert(signature_ni == try coff.mf.addOnlyChildNode(gpa, header_ni, .{
|
assert(signature_ni == try coff.mf.addOnlyChildNode(gpa, header_ni, .{
|
||||||
.size = (if (is_image) link.File.Coff.msdos_stub.len else 0) + "PE\x00\x00".len,
|
.size = (if (is_image) msdos_stub.len else 0) + "PE\x00\x00".len,
|
||||||
.alignment = .@"4",
|
.alignment = .@"4",
|
||||||
.fixed = true,
|
.fixed = true,
|
||||||
}));
|
}));
|
||||||
coff.nodes.appendAssumeCapacity(.signature);
|
coff.nodes.appendAssumeCapacity(.signature);
|
||||||
{
|
{
|
||||||
const signature_slice = signature_ni.slice(&coff.mf);
|
const signature_slice = signature_ni.slice(&coff.mf);
|
||||||
if (is_image)
|
if (is_image) @memcpy(signature_slice[0..msdos_stub.len], &msdos_stub);
|
||||||
@memcpy(signature_slice[0..link.File.Coff.msdos_stub.len], &link.File.Coff.msdos_stub);
|
|
||||||
@memcpy(signature_slice[signature_slice.len - 4 ..], "PE\x00\x00");
|
@memcpy(signature_slice[signature_slice.len - 4 ..], "PE\x00\x00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,10 +795,10 @@ fn initHeaders(
|
||||||
.TERMINAL_SERVER_AWARE = true,
|
.TERMINAL_SERVER_AWARE = true,
|
||||||
.NX_COMPAT = true,
|
.NX_COMPAT = true,
|
||||||
},
|
},
|
||||||
.size_of_stack_reserve = link.File.Coff.default_size_of_stack_reserve,
|
.size_of_stack_reserve = default_size_of_stack_reserve,
|
||||||
.size_of_stack_commit = link.File.Coff.default_size_of_stack_commit,
|
.size_of_stack_commit = default_size_of_stack_commit,
|
||||||
.size_of_heap_reserve = link.File.Coff.default_size_of_heap_reserve,
|
.size_of_heap_reserve = default_size_of_heap_reserve,
|
||||||
.size_of_heap_commit = link.File.Coff.default_size_of_heap_commit,
|
.size_of_heap_commit = default_size_of_heap_commit,
|
||||||
.loader_flags = 0,
|
.loader_flags = 0,
|
||||||
.number_of_rva_and_sizes = data_directories_len,
|
.number_of_rva_and_sizes = data_directories_len,
|
||||||
};
|
};
|
||||||
|
|
@ -781,10 +846,10 @@ fn initHeaders(
|
||||||
.TERMINAL_SERVER_AWARE = true,
|
.TERMINAL_SERVER_AWARE = true,
|
||||||
.NX_COMPAT = true,
|
.NX_COMPAT = true,
|
||||||
},
|
},
|
||||||
.size_of_stack_reserve = link.File.Coff.default_size_of_stack_reserve,
|
.size_of_stack_reserve = default_size_of_stack_reserve,
|
||||||
.size_of_stack_commit = link.File.Coff.default_size_of_stack_commit,
|
.size_of_stack_commit = default_size_of_stack_commit,
|
||||||
.size_of_heap_reserve = link.File.Coff.default_size_of_heap_reserve,
|
.size_of_heap_reserve = default_size_of_heap_reserve,
|
||||||
.size_of_heap_commit = link.File.Coff.default_size_of_heap_commit,
|
.size_of_heap_commit = default_size_of_heap_commit,
|
||||||
.loader_flags = 0,
|
.loader_flags = 0,
|
||||||
.number_of_rva_and_sizes = data_directories_len,
|
.number_of_rva_and_sizes = data_directories_len,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue