authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-08-31 19:55:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:55+02:00
loga35f156cf60ed3d8095c15c4ab26aee267761a56
treee1a3c92285e60c0b3940a6d4b0a67a53abf9a1c4
parent11d14a23a3984fa8a72555a6d7e17a06965ad1a0

coff: re-enable default entrypoint for Windows


7 files changed, 56 insertions(+), 10 deletions(-)

lib/std/start.zig+4
......@@ -36,6 +36,10 @@ comptime {
3636 if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {
3737 @export(main2, .{ .name = "main" });
3838 }
39 } else if (builtin.os.tag == .windows) {
40 if (!@hasDecl(root, "wWinMainCRTStartup") and !@hasDecl(root, "mainCRTStartup")) {
41 @export(wWinMainCRTStartup2, .{ .name = "wWinMainCRTStartup" });
42 }
3943 } else if (builtin.os.tag == .wasi and @hasDecl(root, "main")) {
4044 @export(wasiMain2, .{ .name = "_start" });
4145 } else {
src/arch/x86_64/CodeGen.zig+21-3
......@@ -3999,7 +3999,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
39993999 .data = undefined,
40004000 });
40014001 }
4002 } else if (self.bin_file.cast(link.File.Coff)) |_| {
4002 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
40034003 if (self.air.value(callee)) |func_value| {
40044004 if (func_value.castTag(.function)) |func_payload| {
40054005 const func = func_payload.data;
......@@ -4015,8 +4015,26 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
40154015 }),
40164016 .data = undefined,
40174017 });
4018 } else if (func_value.castTag(.extern_fn)) |_| {
4019 return self.fail("TODO implement calling extern functions", .{});
4018 } else if (func_value.castTag(.extern_fn)) |func_payload| {
4019 const extern_fn = func_payload.data;
4020 const decl_name = mod.declPtr(extern_fn.owner_decl).name;
4021 if (extern_fn.lib_name) |lib_name| {
4022 log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
4023 decl_name,
4024 lib_name,
4025 });
4026 }
4027 const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
4028 _ = try self.addInst(.{
4029 .tag = .call_extern,
4030 .ops = undefined,
4031 .data = .{
4032 .relocation = .{
4033 .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.coff.sym_index,
4034 .sym_index = sym_index,
4035 },
4036 },
4037 });
40204038 } else {
40214039 return self.fail("TODO implement calling bitcasted functions", .{});
40224040 }
src/link.zig+1-1
......@@ -473,7 +473,7 @@ pub const File = struct {
473473 log.debug("getGlobalSymbol '{s}'", .{name});
474474 switch (base.tag) {
475475 // zig fmt: off
476 .coff => unreachable,
476 .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name),
477477 .elf => unreachable,
478478 .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name),
479479 .plan9 => unreachable,
src/link/Coff.zig+27-3
......@@ -596,7 +596,7 @@ fn allocateSymbol(self: *Coff) !u32 {
596596 self.locals.items[index] = .{
597597 .name = [_]u8{0} ** 8,
598598 .value = 0,
599 .section_number = @intToEnum(coff.SectionNumber, 0),
599 .section_number = .UNDEFINED,
600600 .@"type" = .{ .base_type = .NULL, .complex_type = .NULL },
601601 .storage_class = .NULL,
602602 .number_of_aux_symbols = 0,
......@@ -1027,7 +1027,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
10271027 log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index });
10281028 }
10291029
1030 self.locals.items[sym_index].section_number = @intToEnum(coff.SectionNumber, 0);
1030 self.locals.items[sym_index].section_number = .UNDEFINED;
10311031 _ = self.atom_by_index_table.remove(sym_index);
10321032 decl.link.coff.sym_index = 0;
10331033 }
......@@ -1268,6 +1268,30 @@ pub fn getDeclVAddr(
12681268 @panic("TODO getDeclVAddr");
12691269}
12701270
1271pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {
1272 const gpa = self.base.allocator;
1273 const sym_name = try gpa.dupe(u8, name);
1274 const global_index = @intCast(u32, self.globals.values().len);
1275 _ = global_index;
1276 const gop = try self.globals.getOrPut(gpa, sym_name);
1277 defer if (gop.found_existing) gpa.free(sym_name);
1278
1279 if (gop.found_existing) {
1280 // TODO audit this: can we ever reference anything from outside the Zig module?
1281 assert(gop.value_ptr.file == null);
1282 return gop.value_ptr.sym_index;
1283 }
1284
1285 const sym_index = try self.allocateSymbol();
1286 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
1287 const sym = self.getSymbolPtr(sym_loc);
1288 try self.setSymbolName(sym, sym_name);
1289 sym.storage_class = .EXTERNAL;
1290 gop.value_ptr.* = sym_loc;
1291
1292 return sym_index;
1293}
1294
12711295pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !void {
12721296 _ = self;
12731297 _ = module;
......@@ -1614,7 +1638,7 @@ inline fn getSizeOfImage(self: Coff) u32 {
16141638
16151639/// Returns symbol location corresponding to the set entrypoint (if any).
16161640pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
1617 const entry_name = self.base.options.entry orelse "_start"; // TODO this is incomplete
1641 const entry_name = self.base.options.entry orelse "wWinMainCRTStartup"; // TODO this is incomplete
16181642 return self.globals.get(entry_name);
16191643}
16201644
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1
......@@ -2,5 +2,5 @@
22// output_mode=Exe
33// target=aarch64-macos
44//
5// :105:9: error: struct 'tmp.tmp' has no member named 'main'
5// :107:9: error: struct 'tmp.tmp' has no member named 'main'
66// :7:1: note: struct declared here
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1
......@@ -2,5 +2,5 @@
22// output_mode=Exe
33// target=x86_64-linux
44//
5// :105:9: error: struct 'tmp.tmp' has no member named 'main'
5// :107:9: error: struct 'tmp.tmp' has no member named 'main'
66// :7:1: note: struct declared here
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1
......@@ -2,5 +2,5 @@
22// output_mode=Exe
33// target=x86_64-macos
44//
5// :105:9: error: struct 'tmp.tmp' has no member named 'main'
5// :107:9: error: struct 'tmp.tmp' has no member named 'main'
66// :7:1: note: struct declared here