| author | |
| committer | |
| log | a35f156cf60ed3d8095c15c4ab26aee267761a56 |
| tree | e1a3c92285e60c0b3940a6d4b0a67a53abf9a1c4 |
| parent | 11d14a23a3984fa8a72555a6d7e17a06965ad1a0 |
7 files changed, 56 insertions(+), 10 deletions(-)
lib/std/start.zig+4| ... | ... | @@ -36,6 +36,10 @@ comptime { |
| 36 | 36 | if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) { |
| 37 | 37 | @export(main2, .{ .name = "main" }); |
| 38 | 38 | } |
| 39 | } else if (builtin.os.tag == .windows) { | |
| 40 | if (!@hasDecl(root, "wWinMainCRTStartup") and !@hasDecl(root, "mainCRTStartup")) { | |
| 41 | @export(wWinMainCRTStartup2, .{ .name = "wWinMainCRTStartup" }); | |
| 42 | } | |
| 39 | 43 | } else if (builtin.os.tag == .wasi and @hasDecl(root, "main")) { |
| 40 | 44 | @export(wasiMain2, .{ .name = "_start" }); |
| 41 | 45 | } 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. |
| 3999 | 3999 | .data = undefined, |
| 4000 | 4000 | }); |
| 4001 | 4001 | } |
| 4002 | } else if (self.bin_file.cast(link.File.Coff)) |_| { | |
| 4002 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | |
| 4003 | 4003 | if (self.air.value(callee)) |func_value| { |
| 4004 | 4004 | if (func_value.castTag(.function)) |func_payload| { |
| 4005 | 4005 | const func = func_payload.data; |
| ... | ... | @@ -4015,8 +4015,26 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 4015 | 4015 | }), |
| 4016 | 4016 | .data = undefined, |
| 4017 | 4017 | }); |
| 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 | }); | |
| 4020 | 4038 | } else { |
| 4021 | 4039 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 4022 | 4040 | } |
src/link.zig+1-1| ... | ... | @@ -473,7 +473,7 @@ pub const File = struct { |
| 473 | 473 | log.debug("getGlobalSymbol '{s}'", .{name}); |
| 474 | 474 | switch (base.tag) { |
| 475 | 475 | // zig fmt: off |
| 476 | .coff => unreachable, | |
| 476 | .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name), | |
| 477 | 477 | .elf => unreachable, |
| 478 | 478 | .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name), |
| 479 | 479 | .plan9 => unreachable, |
src/link/Coff.zig+27-3| ... | ... | @@ -596,7 +596,7 @@ fn allocateSymbol(self: *Coff) !u32 { |
| 596 | 596 | self.locals.items[index] = .{ |
| 597 | 597 | .name = [_]u8{0} ** 8, |
| 598 | 598 | .value = 0, |
| 599 | .section_number = @intToEnum(coff.SectionNumber, 0), | |
| 599 | .section_number = .UNDEFINED, | |
| 600 | 600 | .@"type" = .{ .base_type = .NULL, .complex_type = .NULL }, |
| 601 | 601 | .storage_class = .NULL, |
| 602 | 602 | .number_of_aux_symbols = 0, |
| ... | ... | @@ -1027,7 +1027,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1027 | 1027 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index }); |
| 1028 | 1028 | } |
| 1029 | 1029 | |
| 1030 | self.locals.items[sym_index].section_number = @intToEnum(coff.SectionNumber, 0); | |
| 1030 | self.locals.items[sym_index].section_number = .UNDEFINED; | |
| 1031 | 1031 | _ = self.atom_by_index_table.remove(sym_index); |
| 1032 | 1032 | decl.link.coff.sym_index = 0; |
| 1033 | 1033 | } |
| ... | ... | @@ -1268,6 +1268,30 @@ pub fn getDeclVAddr( |
| 1268 | 1268 | @panic("TODO getDeclVAddr"); |
| 1269 | 1269 | } |
| 1270 | 1270 | |
| 1271 | pub 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 | ||
| 1271 | 1295 | pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 1272 | 1296 | _ = self; |
| 1273 | 1297 | _ = module; |
| ... | ... | @@ -1614,7 +1638,7 @@ inline fn getSizeOfImage(self: Coff) u32 { |
| 1614 | 1638 | |
| 1615 | 1639 | /// Returns symbol location corresponding to the set entrypoint (if any). |
| 1616 | 1640 | pub 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 | |
| 1618 | 1642 | return self.globals.get(entry_name); |
| 1619 | 1643 | } |
| 1620 | 1644 |
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,5 +2,5 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=aarch64-macos |
| 4 | 4 | // |
| 5 | // :105:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 6 | 6 | // :7:1: note: struct declared here |
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,5 +2,5 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=x86_64-linux |
| 4 | 4 | // |
| 5 | // :105:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 6 | 6 | // :7:1: note: struct declared here |
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,5 +2,5 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=x86_64-macos |
| 4 | 4 | // |
| 5 | // :105:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 6 | 6 | // :7:1: note: struct declared here |