mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Coff: delete
This commit is contained in:
parent
e1f3fc6ce2
commit
1fa11e0954
@ -561,7 +561,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/libs/libunwind.zig
|
||||
src/link.zig
|
||||
src/link/C.zig
|
||||
src/link/Coff.zig
|
||||
src/link/Dwarf.zig
|
||||
src/link/Elf.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,
|
||||
.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 => {},
|
||||
.lf_only => lf.makeWritable(),
|
||||
.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 (target.ofmt == .coff) break :b true;
|
||||
|
||||
break :b options.incremental;
|
||||
};
|
||||
|
||||
|
||||
@ -978,21 +978,6 @@ pub fn genNavRef(
|
||||
},
|
||||
.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| {
|
||||
return .{ .sym_index = @intFromEnum(try coff.navSymbol(zcu, nav_index)) };
|
||||
} else {
|
||||
|
||||
@ -135,11 +135,6 @@ pub fn emit(
|
||||
else if (lf.cast(.macho)) |mf|
|
||||
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |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
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
mir.body[lazy_reloc.reloc.label],
|
||||
@ -154,8 +149,6 @@ pub fn emit(
|
||||
try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||
else if (lf.cast(.macho)) |mf|
|
||||
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
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
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|
|
||||
macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |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|
|
||||
@intFromEnum(try elf.lazySymbol(lazy_sym))
|
||||
else
|
||||
@ -190,8 +185,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.type = .FUNC,
|
||||
})) else if (emit.bin_file.cast(.macho)) |macho_file|
|
||||
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(
|
||||
extern_func.toSlice(&emit.lower.mir).?,
|
||||
switch (comp.compiler_rt_strat) {
|
||||
@ -211,9 +204,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
switch (lowered_inst.encoding.mnemonic) {
|
||||
.call => {
|
||||
reloc.target.type = .branch;
|
||||
if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{
|
||||
.{ .mem = .initRip(.ptr, 0) },
|
||||
}, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info);
|
||||
try emit.encodeInst(lowered_inst, reloc_info);
|
||||
continue :lowered_inst;
|
||||
},
|
||||
else => {},
|
||||
@ -290,37 +281,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
}, emit.lower.target), reloc_info),
|
||||
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)) |_| {
|
||||
switch (lowered_inst.encoding.mnemonic) {
|
||||
.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),
|
||||
reloc.off,
|
||||
.{ .X86_64 = .@"32" },
|
||||
) 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) .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(
|
||||
) else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
|
||||
@enumFromInt(emit.atom_index),
|
||||
end_offset - 4,
|
||||
@enumFromInt(reloc.target.index),
|
||||
@ -873,21 +818,6 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||
.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(
|
||||
@enumFromInt(emit.atom_index),
|
||||
end_offset - 4,
|
||||
|
||||
18
src/link.zig
18
src/link.zig
@ -574,16 +574,13 @@ pub const File = struct {
|
||||
const gpa = comp.gpa;
|
||||
switch (base.tag) {
|
||||
.lld => assert(base.file == null),
|
||||
.coff, .elf, .macho, .wasm, .goff, .xcoff => {
|
||||
.elf, .macho, .wasm, .goff, .xcoff => {
|
||||
if (base.file != null) return;
|
||||
dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
||||
const emit = base.emit;
|
||||
if (base.child_pid) |pid| {
|
||||
if (builtin.os.tag == .windows) {
|
||||
const coff_file = base.cast(.coff).?;
|
||||
coff_file.ptraceAttach(pid) catch |err| {
|
||||
log.warn("attaching failed with error: {s}", .{@errorName(err)});
|
||||
};
|
||||
return error.HotSwapUnavailableOnHostOperatingSystem;
|
||||
} else {
|
||||
// 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
|
||||
@ -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 });
|
||||
f.close();
|
||||
base.file = null;
|
||||
@ -684,10 +681,6 @@ pub const File = struct {
|
||||
log.warn("detaching failed with error: {s}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.windows => {
|
||||
const coff_file = base.cast(.coff).?;
|
||||
coff_file.ptraceDetach(pid);
|
||||
},
|
||||
else => return error.HotSwapUnavailableOnHostOperatingSystem,
|
||||
}
|
||||
}
|
||||
@ -1157,7 +1150,6 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub const Tag = enum {
|
||||
coff,
|
||||
coff2,
|
||||
elf,
|
||||
elf2,
|
||||
@ -1172,7 +1164,6 @@ pub const File = struct {
|
||||
|
||||
pub fn Type(comptime tag: Tag) type {
|
||||
return switch (tag) {
|
||||
.coff => Coff,
|
||||
.coff2 => Coff2,
|
||||
.elf => Elf,
|
||||
.elf2 => Elf2,
|
||||
@ -1189,7 +1180,7 @@ pub const File = struct {
|
||||
|
||||
fn fromObjectFormat(ofmt: std.Target.ObjectFormat, use_new_linker: bool) Tag {
|
||||
return switch (ofmt) {
|
||||
.coff => if (use_new_linker) .coff2 else .coff,
|
||||
.coff => .coff2,
|
||||
.elf => if (use_new_linker) .elf2 else .elf,
|
||||
.macho => .macho,
|
||||
.wasm => .wasm,
|
||||
@ -1274,7 +1265,6 @@ pub const File = struct {
|
||||
|
||||
pub const Lld = @import("link/Lld.zig");
|
||||
pub const C = @import("link/C.zig");
|
||||
pub const Coff = @import("link/Coff.zig");
|
||||
pub const Coff2 = @import("link/Coff2.zig");
|
||||
pub const Elf = @import("link/Elf.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.
|
||||
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) {
|
||||
file,
|
||||
header,
|
||||
@ -613,8 +680,7 @@ fn initHeaders(
|
||||
) !void {
|
||||
const comp = coff.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const file_align: std.mem.Alignment =
|
||||
comptime .fromByteUnits(link.File.Coff.default_file_alignment);
|
||||
const file_align: std.mem.Alignment = comptime .fromByteUnits(default_file_alignment);
|
||||
const target_endian = coff.targetEndian();
|
||||
|
||||
const optional_header_size: u16 = if (is_image) switch (magic) {
|
||||
@ -639,15 +705,14 @@ fn initHeaders(
|
||||
|
||||
const signature_ni = Node.known.signature;
|
||||
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",
|
||||
.fixed = true,
|
||||
}));
|
||||
coff.nodes.appendAssumeCapacity(.signature);
|
||||
{
|
||||
const signature_slice = signature_ni.slice(&coff.mf);
|
||||
if (is_image)
|
||||
@memcpy(signature_slice[0..link.File.Coff.msdos_stub.len], &link.File.Coff.msdos_stub);
|
||||
if (is_image) @memcpy(signature_slice[0..msdos_stub.len], &msdos_stub);
|
||||
@memcpy(signature_slice[signature_slice.len - 4 ..], "PE\x00\x00");
|
||||
}
|
||||
|
||||
@ -730,10 +795,10 @@ fn initHeaders(
|
||||
.TERMINAL_SERVER_AWARE = true,
|
||||
.NX_COMPAT = true,
|
||||
},
|
||||
.size_of_stack_reserve = link.File.Coff.default_size_of_stack_reserve,
|
||||
.size_of_stack_commit = link.File.Coff.default_size_of_stack_commit,
|
||||
.size_of_heap_reserve = link.File.Coff.default_size_of_heap_reserve,
|
||||
.size_of_heap_commit = link.File.Coff.default_size_of_heap_commit,
|
||||
.size_of_stack_reserve = default_size_of_stack_reserve,
|
||||
.size_of_stack_commit = default_size_of_stack_commit,
|
||||
.size_of_heap_reserve = default_size_of_heap_reserve,
|
||||
.size_of_heap_commit = default_size_of_heap_commit,
|
||||
.loader_flags = 0,
|
||||
.number_of_rva_and_sizes = data_directories_len,
|
||||
};
|
||||
@ -781,10 +846,10 @@ fn initHeaders(
|
||||
.TERMINAL_SERVER_AWARE = true,
|
||||
.NX_COMPAT = true,
|
||||
},
|
||||
.size_of_stack_reserve = link.File.Coff.default_size_of_stack_reserve,
|
||||
.size_of_stack_commit = link.File.Coff.default_size_of_stack_commit,
|
||||
.size_of_heap_reserve = link.File.Coff.default_size_of_heap_reserve,
|
||||
.size_of_heap_commit = link.File.Coff.default_size_of_heap_commit,
|
||||
.size_of_stack_reserve = default_size_of_stack_reserve,
|
||||
.size_of_stack_commit = default_size_of_stack_commit,
|
||||
.size_of_heap_reserve = default_size_of_heap_reserve,
|
||||
.size_of_heap_commit = default_size_of_heap_commit,
|
||||
.loader_flags = 0,
|
||||
.number_of_rva_and_sizes = data_directories_len,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user