coff: re-enable default entrypoint for Windows

This commit is contained in:
Jakub Konka 2022-08-31 19:55:39 +02:00
parent 11d14a23a3
commit a35f156cf6
7 changed files with 56 additions and 10 deletions

View File

@ -36,6 +36,10 @@ comptime {
if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {
@export(main2, .{ .name = "main" });
}
} else if (builtin.os.tag == .windows) {
if (!@hasDecl(root, "wWinMainCRTStartup") and !@hasDecl(root, "mainCRTStartup")) {
@export(wWinMainCRTStartup2, .{ .name = "wWinMainCRTStartup" });
}
} else if (builtin.os.tag == .wasi and @hasDecl(root, "main")) {
@export(wasiMain2, .{ .name = "_start" });
} else {

View File

@ -3999,7 +3999,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
.data = undefined,
});
}
} else if (self.bin_file.cast(link.File.Coff)) |_| {
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
if (self.air.value(callee)) |func_value| {
if (func_value.castTag(.function)) |func_payload| {
const func = func_payload.data;
@ -4015,8 +4015,26 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
}),
.data = undefined,
});
} else if (func_value.castTag(.extern_fn)) |_| {
return self.fail("TODO implement calling extern functions", .{});
} else if (func_value.castTag(.extern_fn)) |func_payload| {
const extern_fn = func_payload.data;
const decl_name = mod.declPtr(extern_fn.owner_decl).name;
if (extern_fn.lib_name) |lib_name| {
log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
decl_name,
lib_name,
});
}
const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
_ = try self.addInst(.{
.tag = .call_extern,
.ops = undefined,
.data = .{
.relocation = .{
.atom_index = mod.declPtr(self.mod_fn.owner_decl).link.coff.sym_index,
.sym_index = sym_index,
},
},
});
} else {
return self.fail("TODO implement calling bitcasted functions", .{});
}

View File

@ -473,7 +473,7 @@ pub const File = struct {
log.debug("getGlobalSymbol '{s}'", .{name});
switch (base.tag) {
// zig fmt: off
.coff => unreachable,
.coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name),
.elf => unreachable,
.macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name),
.plan9 => unreachable,

View File

@ -596,7 +596,7 @@ fn allocateSymbol(self: *Coff) !u32 {
self.locals.items[index] = .{
.name = [_]u8{0} ** 8,
.value = 0,
.section_number = @intToEnum(coff.SectionNumber, 0),
.section_number = .UNDEFINED,
.@"type" = .{ .base_type = .NULL, .complex_type = .NULL },
.storage_class = .NULL,
.number_of_aux_symbols = 0,
@ -1027,7 +1027,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index });
}
self.locals.items[sym_index].section_number = @intToEnum(coff.SectionNumber, 0);
self.locals.items[sym_index].section_number = .UNDEFINED;
_ = self.atom_by_index_table.remove(sym_index);
decl.link.coff.sym_index = 0;
}
@ -1268,6 +1268,30 @@ pub fn getDeclVAddr(
@panic("TODO getDeclVAddr");
}
pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {
const gpa = self.base.allocator;
const sym_name = try gpa.dupe(u8, name);
const global_index = @intCast(u32, self.globals.values().len);
_ = global_index;
const gop = try self.globals.getOrPut(gpa, sym_name);
defer if (gop.found_existing) gpa.free(sym_name);
if (gop.found_existing) {
// TODO audit this: can we ever reference anything from outside the Zig module?
assert(gop.value_ptr.file == null);
return gop.value_ptr.sym_index;
}
const sym_index = try self.allocateSymbol();
const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
const sym = self.getSymbolPtr(sym_loc);
try self.setSymbolName(sym, sym_name);
sym.storage_class = .EXTERNAL;
gop.value_ptr.* = sym_loc;
return sym_index;
}
pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !void {
_ = self;
_ = module;
@ -1614,7 +1638,7 @@ inline fn getSizeOfImage(self: Coff) u32 {
/// Returns symbol location corresponding to the set entrypoint (if any).
pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
const entry_name = self.base.options.entry orelse "_start"; // TODO this is incomplete
const entry_name = self.base.options.entry orelse "wWinMainCRTStartup"; // TODO this is incomplete
return self.globals.get(entry_name);
}

View File

@ -2,5 +2,5 @@
// output_mode=Exe
// target=aarch64-macos
//
// :105:9: error: struct 'tmp.tmp' has no member named 'main'
// :107:9: error: struct 'tmp.tmp' has no member named 'main'
// :7:1: note: struct declared here

View File

@ -2,5 +2,5 @@
// output_mode=Exe
// target=x86_64-linux
//
// :105:9: error: struct 'tmp.tmp' has no member named 'main'
// :107:9: error: struct 'tmp.tmp' has no member named 'main'
// :7:1: note: struct declared here

View File

@ -2,5 +2,5 @@
// output_mode=Exe
// target=x86_64-macos
//
// :105:9: error: struct 'tmp.tmp' has no member named 'main'
// :107:9: error: struct 'tmp.tmp' has no member named 'main'
// :7:1: note: struct declared here