Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 40 additions & 51 deletions lib/std/coff.zig
Original file line number Diff line number Diff line change
Expand Up @@ -249,55 +249,6 @@ pub const OptionalHeader = extern struct {

pub const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;

pub const DirectoryEntry = enum(u16) {
/// Export Directory
EXPORT = 0,

/// Import Directory
IMPORT = 1,

/// Resource Directory
RESOURCE = 2,

/// Exception Directory
EXCEPTION = 3,

/// Security Directory
SECURITY = 4,

/// Base Relocation Table
BASERELOC = 5,

/// Debug Directory
DEBUG = 6,

/// Architecture Specific Data
ARCHITECTURE = 7,

/// RVA of GP
GLOBALPTR = 8,

/// TLS Directory
TLS = 9,

/// Load Configuration Directory
LOAD_CONFIG = 10,

/// Bound Import Directory in headers
BOUND_IMPORT = 11,

/// Import Address Table
IAT = 12,

/// Delay Load Import Descriptors
DELAY_IMPORT = 13,

/// COM Runtime descriptor
COM_DESCRIPTOR = 14,

_,
};

pub const ImageDataDirectory = extern struct {
virtual_address: u32,
size: u32,
Expand Down Expand Up @@ -1054,9 +1005,9 @@ pub const Coff = struct {
assert(self.is_image);

const data_dirs = self.getDataDirectories();
if (@intFromEnum(DirectoryEntry.DEBUG) >= data_dirs.len) return null;
if (@intFromEnum(IMAGE.DIRECTORY_ENTRY.DEBUG) >= data_dirs.len) return null;

const debug_dir = data_dirs[@intFromEnum(DirectoryEntry.DEBUG)];
const debug_dir = data_dirs[@intFromEnum(IMAGE.DIRECTORY_ENTRY.DEBUG)];
var reader: std.Io.Reader = .fixed(self.data);

if (self.is_loaded) {
Expand Down Expand Up @@ -1400,6 +1351,44 @@ pub const Relocation = extern struct {
};

pub const IMAGE = struct {
pub const DIRECTORY_ENTRY = enum(u32) {
/// Export Directory
EXPORT = 0,
/// Import Directory
IMPORT = 1,
/// Resource Directory
RESOURCE = 2,
/// Exception Directory
EXCEPTION = 3,
/// Security Directory
SECURITY = 4,
/// Base Relocation Table
BASERELOC = 5,
/// Debug Directory
DEBUG = 6,
/// Architecture Specific Data
ARCHITECTURE = 7,
/// RVA of GP
GLOBALPTR = 8,
/// TLS Directory
TLS = 9,
/// Load Configuration Directory
LOAD_CONFIG = 10,
/// Bound Import Directory in headers
BOUND_IMPORT = 11,
/// Import Address Table
IAT = 12,
/// Delay Load Import Descriptors
DELAY_IMPORT = 13,
/// COM Runtime descriptor
COM_DESCRIPTOR = 14,
/// must be zero
RESERVED = 15,
_,

pub const len = @typeInfo(IMAGE.DIRECTORY_ENTRY).@"enum".fields.len;
};

pub const FILE = struct {
/// Machine Types
/// The Machine field has one of the following values, which specify the CPU type.
Expand Down
20 changes: 0 additions & 20 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,6 @@ const use_trap_panic = switch (builtin.zig_backend) {
.stage2_wasm,
.stage2_x86,
=> true,
.stage2_x86_64 => switch (builtin.target.ofmt) {
.elf, .macho => false,
else => true,
},
else => false,
};

Expand All @@ -481,22 +477,6 @@ pub fn defaultPanic(

if (use_trap_panic) @trap();

switch (builtin.zig_backend) {
.stage2_aarch64,
.stage2_arm,
.stage2_powerpc,
.stage2_riscv64,
.stage2_spirv,
.stage2_wasm,
.stage2_x86,
=> @trap(),
.stage2_x86_64 => switch (builtin.target.ofmt) {
.elf, .macho => {},
else => @trap(),
},
else => {},
}

switch (builtin.os.tag) {
.freestanding, .other => {
@trap();
Expand Down
2 changes: 2 additions & 0 deletions lib/std/math/isnan.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ test isNan {
}

test isSignalNan {
if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;

inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
// TODO: Signalling NaN values get converted to quiet NaN values in
// some cases where they shouldn't such that this can fail.
Expand Down
35 changes: 15 additions & 20 deletions lib/ubsan_rt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,6 @@ const Value = extern struct {
}

pub fn format(value: Value, writer: *std.Io.Writer) std.Io.Writer.Error!void {
// Work around x86_64 backend limitation.
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) {
try writer.writeAll("(unknown)");
return;
}

switch (value.td.kind) {
.integer => {
if (value.td.isSigned()) {
Expand Down Expand Up @@ -624,27 +618,28 @@ fn exportHandler(
handler: anytype,
comptime sym_name: []const u8,
) void {
// Work around x86_64 backend limitation.
const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
const N = "__ubsan_handle_" ++ sym_name;
@export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
@export(handler, .{
.name = "__ubsan_handle_" ++ sym_name,
.linkage = .weak,
.visibility = .hidden,
});
}

fn exportHandlerWithAbort(
handler: anytype,
abort_handler: anytype,
comptime sym_name: []const u8,
) void {
// Work around x86_64 backend limitation.
const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
{
const N = "__ubsan_handle_" ++ sym_name;
@export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
}
{
const N = "__ubsan_handle_" ++ sym_name ++ "_abort";
@export(abort_handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
}
@export(handler, .{
.name = "__ubsan_handle_" ++ sym_name,
.linkage = .weak,
.visibility = .hidden,
});
@export(abort_handler, .{
.name = "__ubsan_handle_" ++ sym_name ++ "_abort",
.linkage = .weak,
.visibility = .hidden,
});
}

const can_build_ubsan = switch (builtin.zig_backend) {
Expand Down
2 changes: 1 addition & 1 deletion src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1985,7 +1985,7 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options
switch (target_util.zigBackend(target, use_llvm)) {
else => {},
.stage2_aarch64, .stage2_x86_64 => if (target.ofmt == .coff) {
break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
break :s if (is_exe_or_dyn_lib and build_options.have_llvm) .dyn_lib else .zcu;
},
}
if (options.config.use_new_linker) break :s .zcu;
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/x86_64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -173685,7 +173685,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const ty_nav = air_datas[@intFromEnum(inst)].ty_nav;
const nav = ip.getNav(ty_nav.nav);
const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.isThreadlocal(ip);
if (is_threadlocal) if (cg.mod.pic) {
if (is_threadlocal) if (cg.target.ofmt == .coff or cg.mod.pic) {
try cg.spillRegisters(&.{ .rdi, .rax });
} else {
try cg.spillRegisters(&.{.rax});
Expand Down
84 changes: 83 additions & 1 deletion src/codegen/x86_64/Emit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,82 @@ pub fn emitMir(emit: *Emit) Error!void {
}, emit.lower.target), &.{});
},
else => unreachable,
} else if (emit.bin_file.cast(.coff2)) |coff| {
switch (emit.lower.target.cpu.arch) {
else => unreachable,
.x86 => {
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .eax },
.{ .mem = .initSib(.qword, .{
.base = .{ .reg = .fs },
.disp = 4 * 11,
}) },
}, emit.lower.target), &.{});
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .edi },
.{ .mem = .initSib(.dword, .{}) },
}, emit.lower.target), &.{.{
.op_index = 1,
.target = .{
.index = @intFromEnum(
try coff.globalSymbol("__tls_index", null),
),
.is_extern = false,
.type = .symbol,
},
}});
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .eax },
.{ .mem = .initSib(.dword, .{
.base = .{ .reg = .eax },
.scale_index = .{ .index = .edi, .scale = 4 },
}) },
}, emit.lower.target), &.{});
try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{
lowered_inst.ops[0],
.{ .mem = .initSib(lowered_inst.ops[1].mem.sib.ptr_size, .{
.base = .{ .reg = .eax },
.disp = std.math.minInt(i32),
}) },
}, emit.lower.target), reloc_info);
},
.x86_64 => {
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .rax },
.{ .mem = .initSib(.qword, .{
.base = .{ .reg = .gs },
.disp = 8 * 11,
}) },
}, emit.lower.target), &.{});
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .edi },
.{ .mem = .initRip(.dword, 0) },
}, emit.lower.target), &.{.{
.op_index = 1,
.target = .{
.index = @intFromEnum(
try coff.globalSymbol("_tls_index", null),
),
.is_extern = false,
.type = .symbol,
},
}});
try emit.encodeInst(try .new(.none, .mov, &.{
.{ .reg = .rax },
.{ .mem = .initSib(.qword, .{
.base = .{ .reg = .rax },
.scale_index = .{ .index = .rdi, .scale = 8 },
}) },
}, emit.lower.target), &.{});
try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{
lowered_inst.ops[0],
.{ .mem = .initSib(lowered_inst.ops[1].mem.sib.ptr_size, .{
.base = .{ .reg = .rax },
.disp = std.math.minInt(i32),
}) },
}, emit.lower.target), reloc_info);
},
}
} else return emit.fail("TODO implement relocs for {s}", .{
@tagName(emit.bin_file.tag),
});
Expand Down Expand Up @@ -870,7 +946,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
.symbolnum = @intCast(reloc.target.index),
},
});
} else return emit.fail("TODO implement {s} reloc for {s}", .{
} else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc(
@enumFromInt(emit.atom_index),
end_offset - 4,
@enumFromInt(reloc.target.index),
reloc.off,
.{ .AMD64 = .SECREL },
) else return emit.fail("TODO implement {s} reloc for {s}", .{
@tagName(reloc.target.type), @tagName(emit.bin_file.tag),
}),
};
Expand Down
Loading