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
28 changes: 21 additions & 7 deletions lib/std/coff.zig
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,11 @@ pub const SectionHeader = extern struct {

/// Applicable only to section headers in COFF objects.
pub fn getAlignment(self: SectionHeader) ?u16 {
if (self.flags.ALIGN == 0) return null;
return std.math.powi(u16, 2, self.flags.ALIGN - 1) catch unreachable;
return self.flags.ALIGN.toByteUnits();
}

pub fn setAlignment(self: *SectionHeader, new_alignment: u16) void {
assert(new_alignment > 0 and new_alignment <= 8192);
self.flags.ALIGN = @intCast(std.math.log2(new_alignment));
self.flags.ALIGN = .fromByteUnits(new_alignment);
}

pub fn isCode(self: SectionHeader) bool {
Expand Down Expand Up @@ -651,6 +649,16 @@ pub const SectionHeader = extern struct {
@"4096BYTES" = 13,
@"8192BYTES" = 14,
_,

pub fn toByteUnits(a: Align) ?u16 {
if (a == .NONE) return null;
return @as(u16, 1) << (@intFromEnum(a) - 1);
}

pub fn fromByteUnits(n: u16) Align {
std.debug.assert(std.math.isPowerOfTwo(n));
return @enumFromInt(@ctz(n) + 1);
}
};
};
};
Expand Down Expand Up @@ -925,6 +933,10 @@ pub const WeakExternalDefinition = struct {
flag: WeakExternalFlag,

unused: [10]u8,

pub fn sizeOf() usize {
return 18;
}
};

// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/km/ntimage.h
Expand Down Expand Up @@ -1338,14 +1350,16 @@ pub const Strtab = struct {
};

pub const ImportHeader = extern struct {
sig1: IMAGE.FILE.MACHINE,
sig2: u16,
/// Must be IMAGE_FILE_MACHINE_UNKNOWN
sig1: IMAGE.FILE.MACHINE = .UNKNOWN,
/// Must be 0xFFFF
sig2: u16 = 0xFFFF,
version: u16,
machine: IMAGE.FILE.MACHINE,
time_date_stamp: u32,
size_of_data: u32,
hint: u16,
types: packed struct(u32) {
types: packed struct(u16) {
type: ImportType,
name_type: ImportNameType,
reserved: u11,
Expand Down
8 changes: 0 additions & 8 deletions src/codegen/llvm/bindings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,6 @@ extern fn ZigLLVMWriteArchive(
pub const ParseCommandLineOptions = ZigLLVMParseCommandLineOptions;
extern fn ZigLLVMParseCommandLineOptions(argc: usize, argv: [*]const [*:0]const u8) void;

pub const WriteImportLibrary = ZigLLVMWriteImportLibrary;
extern fn ZigLLVMWriteImportLibrary(
def_path: [*:0]const u8,
coff_machine: c_uint,
output_lib_path: [*:0]const u8,
kill_at: bool,
) bool;
Comment on lines -341 to -347
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳


pub const GetHostCPUName = LLVMGetHostCPUName;
extern fn LLVMGetHostCPUName() ?[*:0]u8;

Expand Down
71 changes: 43 additions & 28 deletions src/libs/mingw.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ const Compilation = @import("../Compilation.zig");
const build_options = @import("build_options");
const Cache = std.Build.Cache;
const dev = @import("../dev.zig");
const def = @import("mingw/def.zig");
const implib = @import("mingw/implib.zig");

test {
_ = def;
_ = implib;
}

pub const CrtFile = enum {
crt2_o,
Expand Down Expand Up @@ -290,11 +297,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{});
defer o_dir.close();

const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name});
const def_final_path = try comp.dirs.global_cache.join(arena, &[_][]const u8{
"o", &digest, final_def_basename,
});

const aro = @import("aro");
var diagnostics: aro.Diagnostics = .{
.output = .{ .to_list = .{ .arena = .init(gpa) } },
Expand All @@ -312,7 +314,6 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
defer std.debug.unlockStderrWriter();
nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
nosuspend stderr.print("output path: {s}\n", .{def_final_path}) catch break :print;
}

try aro_comp.include_dirs.append(gpa, include_dir);
Expand All @@ -339,32 +340,46 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
}
}

{
// new scope to ensure definition file is written before passing the path to WriteImportLibrary
const def_final_file = try o_dir.createFile(final_def_basename, .{ .truncate = true });
defer def_final_file.close();
var buffer: [1024]u8 = undefined;
var file_writer = def_final_file.writer(&buffer);
try pp.prettyPrintTokens(&file_writer.interface, .result_only);
try file_writer.interface.flush();
}
const members = members: {
var aw: std.Io.Writer.Allocating = .init(gpa);
errdefer aw.deinit();
try pp.prettyPrintTokens(&aw.writer, .result_only);

const input = try aw.toOwnedSliceSentinel(0);
defer gpa.free(input);

const machine_type = target.toCoffMachine();
var def_diagnostics: def.Diagnostics = undefined;
var module_def = def.parse(gpa, input, machine_type, .mingw, &def_diagnostics) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
error.ParseError => {
var buffer: [64]u8 = undefined;
const w = std.debug.lockStderrWriter(&buffer);
defer std.debug.unlockStderrWriter();
try w.writeAll("error: ");
try def_diagnostics.writeMsg(w, input);
try w.writeByte('\n');
return error.WritingImportLibFailed;
},
};
defer module_def.deinit();

module_def.fixupForImportLibraryGeneration(machine_type);

break :members try implib.getMembers(gpa, module_def, machine_type);
};
defer members.deinit();

const lib_final_path = try std.fs.path.join(gpa, &.{ "o", &digest, final_lib_basename });
errdefer gpa.free(lib_final_path);

if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
const llvm_bindings = @import("../codegen/llvm/bindings.zig");
const def_final_path_z = try arena.dupeZ(u8, def_final_path);
const lib_final_path_z = try comp.dirs.global_cache.joinZ(arena, &.{lib_final_path});
if (llvm_bindings.WriteImportLibrary(
def_final_path_z.ptr,
@intFromEnum(target.toCoffMachine()),
lib_final_path_z.ptr,
true,
)) {
// TODO surface a proper error here
log.err("unable to turn {s}.def into {s}.lib", .{ lib_name, lib_name });
return error.WritingImportLibFailed;
{
const lib_final_file = try o_dir.createFile(final_lib_basename, .{ .truncate = true });
defer lib_final_file.close();
var buffer: [1024]u8 = undefined;
var file_writer = lib_final_file.writer(&buffer);
try implib.writeCoffArchive(gpa, &file_writer.interface, members);
try file_writer.interface.flush();
}

man.writeManifest() catch |err| {
Expand Down
Loading