authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-14 11:46:50+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-14 13:08:56+02:00
log00ebbe6df2249ba8201c0e5472d95022bf73e782
tree8a71469cc3f1e2ec94360a9317ebcce576924c9a
parent8eea5eddf773a8d1f9f883e71d00409e454ee0bd

macho: require _main as global export in self-hosted

Clean up type and description flags generation for exports in self-hosted MachO backend.

2 files changed, 32 insertions(+), 15 deletions(-)

src/link/MachO.zig+25-8
...@@ -1369,15 +1369,32 @@ pub fn updateDeclExports(...@@ -1369,15 +1369,32 @@ pub fn updateDeclExports(
1369 continue;1369 continue;
1370 }1370 }
1371 }1371 }
1372 const n_desc = switch (exp.options.linkage) {1372
1373 .Internal => macho.REFERENCE_FLAG_PRIVATE_DEFINED,1373 var n_type: u8 = macho.N_SECT | macho.N_EXT;
1374 .Strong => blk: {1374 var n_desc: u16 = 0;
1375 if (mem.eql(u8, exp.options.name, "_start")) {1375
1376 switch (exp.options.linkage) {
1377 .Internal => {
1378 // Symbol should be hidden, or in MachO lingo, private extern.
1379 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
1380 // TODO work out when to add N_WEAK_REF.
1381 n_type |= macho.N_PEXT;
1382 n_desc |= macho.N_WEAK_DEF;
1383 },
1384 .Strong => {
1385 // Check if the export is _main, and note if os.
1386 // Otherwise, don't do anything since we already have all the flags
1387 // set that we need for global (strong) linkage.
1388 // n_type == N_SECT | N_EXT
1389 if (mem.eql(u8, exp.options.name, "_main")) {
1376 self.entry_addr = decl_sym.n_value;1390 self.entry_addr = decl_sym.n_value;
1377 }1391 }
1378 break :blk macho.REFERENCE_FLAG_DEFINED;
1379 },1392 },
1380 .Weak => macho.N_WEAK_REF,1393 .Weak => {
1394 // Weak linkage is specified as part of n_desc field.
1395 // Symbol's n_type is like for a symbol with strong linkage.
1396 n_desc |= macho.N_WEAK_DEF;
1397 },
1381 .LinkOnce => {1398 .LinkOnce => {
1382 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);1399 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
1383 module.failed_exports.putAssumeCapacityNoClobber(1400 module.failed_exports.putAssumeCapacityNoClobber(
...@@ -1386,8 +1403,8 @@ pub fn updateDeclExports(...@@ -1386,8 +1403,8 @@ pub fn updateDeclExports(
1386 );1403 );
1387 continue;1404 continue;
1388 },1405 },
1389 };1406 }
1390 const n_type = decl_sym.n_type | macho.N_EXT;1407
1391 if (exp.link.macho.sym_index) |i| {1408 if (exp.link.macho.sym_index) |i| {
1392 const sym = &self.globals.items[i];1409 const sym = &self.globals.items[i];
1393 sym.* = .{1410 sym.* = .{
test/stage2/darwin.zig+7-7
...@@ -17,7 +17,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -17,7 +17,7 @@ pub fn addCases(ctx: *TestContext) !void {
1717
18 // Incorrect return type18 // Incorrect return type
19 case.addError(19 case.addError(
20 \\export fn _start() noreturn {20 \\export fn _main() noreturn {
21 \\}21 \\}
22 , &[_][]const u8{":2:1: error: expected noreturn, found void"});22 , &[_][]const u8{":2:1: error: expected noreturn, found void"});
2323
...@@ -26,7 +26,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -26,7 +26,7 @@ pub fn addCases(ctx: *TestContext) !void {
26 \\extern "c" fn write(usize, usize, usize) usize;26 \\extern "c" fn write(usize, usize, usize) usize;
27 \\extern "c" fn exit(usize) noreturn;27 \\extern "c" fn exit(usize) noreturn;
28 \\28 \\
29 \\export fn _start() noreturn {29 \\export fn _main() noreturn {
30 \\ print();30 \\ print();
31 \\31 \\
32 \\ exit(0);32 \\ exit(0);
...@@ -46,7 +46,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -46,7 +46,7 @@ pub fn addCases(ctx: *TestContext) !void {
46 \\extern "c" fn write(usize, usize, usize) usize;46 \\extern "c" fn write(usize, usize, usize) usize;
47 \\extern "c" fn exit(usize) noreturn;47 \\extern "c" fn exit(usize) noreturn;
48 \\48 \\
49 \\export fn _start() noreturn {49 \\export fn _main() noreturn {
50 \\ print();50 \\ print();
51 \\ print();51 \\ print();
52 \\ print();52 \\ print();
...@@ -73,7 +73,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -73,7 +73,7 @@ pub fn addCases(ctx: *TestContext) !void {
73 \\extern "c" fn write(usize, usize, usize) usize;73 \\extern "c" fn write(usize, usize, usize) usize;
74 \\extern "c" fn exit(usize) noreturn;74 \\extern "c" fn exit(usize) noreturn;
75 \\75 \\
76 \\export fn _start() noreturn {76 \\export fn _main() noreturn {
77 \\ print();77 \\ print();
78 \\78 \\
79 \\ exit(0);79 \\ exit(0);
...@@ -93,7 +93,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -93,7 +93,7 @@ pub fn addCases(ctx: *TestContext) !void {
93 \\extern "c" fn write(usize, usize, usize) usize;93 \\extern "c" fn write(usize, usize, usize) usize;
94 \\extern "c" fn exit(usize) noreturn;94 \\extern "c" fn exit(usize) noreturn;
95 \\95 \\
96 \\export fn _start() noreturn {96 \\export fn _main() noreturn {
97 \\ print();97 \\ print();
98 \\ print();98 \\ print();
99 \\99 \\
...@@ -119,7 +119,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -119,7 +119,7 @@ pub fn addCases(ctx: *TestContext) !void {
119 case.addCompareOutput(119 case.addCompareOutput(
120 \\extern "c" fn exit(usize) noreturn;120 \\extern "c" fn exit(usize) noreturn;
121 \\121 \\
122 \\export fn _start() noreturn {122 \\export fn _main() noreturn {
123 \\ exit(0);123 \\ exit(0);
124 \\}124 \\}
125 ,125 ,
...@@ -130,7 +130,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -130,7 +130,7 @@ pub fn addCases(ctx: *TestContext) !void {
130 \\extern "c" fn exit(usize) noreturn;130 \\extern "c" fn exit(usize) noreturn;
131 \\extern "c" fn write(usize, usize, usize) usize;131 \\extern "c" fn write(usize, usize, usize) usize;
132 \\132 \\
133 \\export fn _start() noreturn {133 \\export fn _main() noreturn {
134 \\ _ = write(1, @ptrToInt("Hey!\n"), 5);134 \\ _ = write(1, @ptrToInt("Hey!\n"), 5);
135 \\ exit(0);135 \\ exit(0);
136 \\}136 \\}