link-tests: move macho tests to subfolder

Handle `-e` option in MachO linker allowing the user to set a custom
entrypoint address.
This commit is contained in:
Jakub Konka 2022-06-21 23:01:06 +02:00
parent 937464f398
commit 3bb4d65b2f
22 changed files with 90 additions and 12 deletions

View File

@ -156,6 +156,14 @@ fn dumpLoadCommand(lc: macho.LoadCommand, index: u16, writer: anytype) !void {
});
},
.MAIN => {
try writer.writeByte('\n');
try writer.print(
\\entryoff {x}
\\stacksize {x}
, .{ lc.main.entryoff, lc.main.stacksize });
},
.RPATH => {
try writer.writeByte('\n');
try writer.print(

View File

@ -934,6 +934,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size}));
}
if (self.base.options.entry) |entry| {
try argv.append("-e");
try argv.append(entry);
}
try argv.appendSlice(positionals.items);
try argv.append("-o");
@ -3371,13 +3376,12 @@ fn addCodeSignatureLC(self: *MachO) !void {
fn setEntryPoint(self: *MachO) !void {
if (self.base.options.output_mode != .Exe) return;
// TODO we should respect the -entry flag passed in by the user to set a custom
// entrypoint. For now, assume default of `_main`.
const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment;
const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{
const entry_name = self.base.options.entry orelse "_main";
const n_strx = self.strtab_dir.getKeyAdapted(entry_name, StringIndexAdapter{
.bytes = &self.strtab,
}) orelse {
log.err("'_main' export not found", .{});
log.err("entrypoint '{s}' not found", .{entry_name});
return error.MissingMainEntrypoint;
};
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;

View File

@ -28,29 +28,37 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
});
if (builtin.os.tag == .macos) {
cases.addBuildFile("test/link/pagezero/build.zig", .{
.build_modes = false,
});
cases.addBuildFile("test/link/dylib/build.zig", .{
cases.addBuildFile("test/link/entry/build.zig", .{
.build_modes = true,
});
cases.addBuildFile("test/link/frameworks/build.zig", .{
cases.addBuildFile("test/link/macho/pagezero/build.zig", .{
.build_modes = false,
});
cases.addBuildFile("test/link/macho/dylib/build.zig", .{
.build_modes = true,
});
cases.addBuildFile("test/link/macho/frameworks/build.zig", .{
.build_modes = true,
.requires_macos_sdk = true,
});
// Try to build and run an Objective-C executable.
cases.addBuildFile("test/link/objc/build.zig", .{
cases.addBuildFile("test/link/macho/objc/build.zig", .{
.build_modes = true,
.requires_macos_sdk = true,
});
// Try to build and run an Objective-C++ executable.
cases.addBuildFile("test/link/objcpp/build.zig", .{
cases.addBuildFile("test/link/macho/objcpp/build.zig", .{
.build_modes = true,
.requires_macos_sdk = true,
});
cases.addBuildFile("test/link/macho/stack_size/build.zig", .{
.build_modes = true,
});
}
}

View File

@ -0,0 +1,25 @@
const std = @import("std");
const Builder = std.build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const test_step = b.step("test", "Test");
test_step.dependOn(b.getInstallStep());
const exe = b.addExecutable("main", null);
exe.setBuildMode(mode);
exe.addCSourceFile("main.c", &.{});
exe.linkLibC();
exe.entry_symbol_name = "_non_main";
const check_exe = exe.checkMachO();
check_exe.check("cmd MAIN");
check_exe.checkNext("entryoff {x}");
test_step.dependOn(&check_exe.step);
const run = exe.run();
run.expectStdOutEqual("42");
test_step.dependOn(&run.step);
}

View File

@ -0,0 +1,6 @@
#include <stdio.h>
int non_main() {
printf("%d", 42);
return 0;
}

View File

@ -0,0 +1,24 @@
const std = @import("std");
const Builder = std.build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const test_step = b.step("test", "Test");
test_step.dependOn(b.getInstallStep());
const exe = b.addExecutable("main", null);
exe.setBuildMode(mode);
exe.addCSourceFile("main.c", &.{});
exe.linkLibC();
exe.stack_size = 0x100000000;
const check_exe = exe.checkMachO();
check_exe.check("cmd MAIN");
check_exe.checkNext("stacksize 100000000");
test_step.dependOn(&check_exe.step);
const run = exe.run();
test_step.dependOn(&run.step);
}

View File

@ -0,0 +1,3 @@
int main(int argc, char* argv[]) {
return 0;
}