From 00ebbe6df2249ba8201c0e5472d95022bf73e782 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 14 May 2021 11:46:50 +0200 Subject: [PATCH] macho: require _main as global export in self-hosted Clean up type and description flags generation for exports in self-hosted MachO backend. --- src/link/MachO.zig | 33 +++++++++++++++++++++++++-------- test/stage2/darwin.zig | 14 +++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index d8518c4894..5a0deb67bc 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1369,15 +1369,32 @@ pub fn updateDeclExports( continue; } } - const n_desc = switch (exp.options.linkage) { - .Internal => macho.REFERENCE_FLAG_PRIVATE_DEFINED, - .Strong => blk: { - if (mem.eql(u8, exp.options.name, "_start")) { + + var n_type: u8 = macho.N_SECT | macho.N_EXT; + var n_desc: u16 = 0; + + switch (exp.options.linkage) { + .Internal => { + // Symbol should be hidden, or in MachO lingo, private extern. + // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF. + // TODO work out when to add N_WEAK_REF. + n_type |= macho.N_PEXT; + n_desc |= macho.N_WEAK_DEF; + }, + .Strong => { + // Check if the export is _main, and note if os. + // Otherwise, don't do anything since we already have all the flags + // set that we need for global (strong) linkage. + // n_type == N_SECT | N_EXT + if (mem.eql(u8, exp.options.name, "_main")) { self.entry_addr = decl_sym.n_value; } - break :blk macho.REFERENCE_FLAG_DEFINED; }, - .Weak => macho.N_WEAK_REF, + .Weak => { + // Weak linkage is specified as part of n_desc field. + // Symbol's n_type is like for a symbol with strong linkage. + n_desc |= macho.N_WEAK_DEF; + }, .LinkOnce => { try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); module.failed_exports.putAssumeCapacityNoClobber( @@ -1386,8 +1403,8 @@ pub fn updateDeclExports( ); continue; }, - }; - const n_type = decl_sym.n_type | macho.N_EXT; + } + if (exp.link.macho.sym_index) |i| { const sym = &self.globals.items[i]; sym.* = .{ diff --git a/test/stage2/darwin.zig b/test/stage2/darwin.zig index f8d82391cc..4f708729a2 100644 --- a/test/stage2/darwin.zig +++ b/test/stage2/darwin.zig @@ -17,7 +17,7 @@ pub fn addCases(ctx: *TestContext) !void { // Incorrect return type case.addError( - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\} , &[_][]const u8{":2:1: error: expected noreturn, found void"}); @@ -26,7 +26,7 @@ pub fn addCases(ctx: *TestContext) !void { \\extern "c" fn write(usize, usize, usize) usize; \\extern "c" fn exit(usize) noreturn; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ print(); \\ \\ exit(0); @@ -46,7 +46,7 @@ pub fn addCases(ctx: *TestContext) !void { \\extern "c" fn write(usize, usize, usize) usize; \\extern "c" fn exit(usize) noreturn; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ print(); \\ print(); \\ print(); @@ -73,7 +73,7 @@ pub fn addCases(ctx: *TestContext) !void { \\extern "c" fn write(usize, usize, usize) usize; \\extern "c" fn exit(usize) noreturn; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ print(); \\ \\ exit(0); @@ -93,7 +93,7 @@ pub fn addCases(ctx: *TestContext) !void { \\extern "c" fn write(usize, usize, usize) usize; \\extern "c" fn exit(usize) noreturn; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ print(); \\ print(); \\ @@ -119,7 +119,7 @@ pub fn addCases(ctx: *TestContext) !void { case.addCompareOutput( \\extern "c" fn exit(usize) noreturn; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ exit(0); \\} , @@ -130,7 +130,7 @@ pub fn addCases(ctx: *TestContext) !void { \\extern "c" fn exit(usize) noreturn; \\extern "c" fn write(usize, usize, usize) usize; \\ - \\export fn _start() noreturn { + \\export fn _main() noreturn { \\ _ = write(1, @ptrToInt("Hey!\n"), 5); \\ exit(0); \\}