mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Fix after rebase and enable stage2 tests for macOS
Also, rewrites codegen section to store symbol address in a register to then later invoke `callq` on the register.
This commit is contained in:
parent
5a7105401c
commit
f8dd48bcd2
@ -1532,12 +1532,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
|
||||
const func = func_val.func;
|
||||
const got = &macho_file.sections.items[macho_file.got_section_index.?];
|
||||
const ptr_bytes = 8;
|
||||
const got_addr = @intCast(u32, got.addr + func.owner_decl.link.macho.offset_table_index.? * ptr_bytes);
|
||||
// ff 14 25 xx xx xx xx call [addr]
|
||||
try self.code.ensureCapacity(self.code.items.len + 7);
|
||||
self.code.appendSliceAssumeCapacity(&[3]u8{ 0xff, 0x14, 0x25 });
|
||||
mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), got_addr);
|
||||
const got_addr = got.addr + func.owner_decl.link.macho.offset_table_index.? * @sizeOf(u64);
|
||||
// Here, we store the got address in %rax, and then call %rax
|
||||
// movabsq [addr], %rax
|
||||
try self.genSetReg(inst.base.src, .rax, .{ .memory = got_addr });
|
||||
// callq *%rax
|
||||
self.code.appendSliceAssumeCapacity(&[2]u8{ 0xff, 0xd0 });
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
|
||||
}
|
||||
|
||||
@ -262,11 +262,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
||||
dysymtab.iundefsym = nlocals + nglobals;
|
||||
dysymtab.nundefsym = nundefs;
|
||||
}
|
||||
{
|
||||
if (self.entry_addr) |addr| {
|
||||
// update LC_MAIN with entry offset
|
||||
const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
|
||||
const main_cmd = &self.load_commands.items[self.main_cmd_index.?].EntryPoint;
|
||||
main_cmd.entryoff = self.entry_addr.? - text_segment.vmaddr;
|
||||
main_cmd.entryoff = addr - text_segment.vmaddr;
|
||||
}
|
||||
{
|
||||
var last_cmd_offset: usize = @sizeOf(macho.mach_header_64);
|
||||
@ -709,6 +709,7 @@ fn darwinArchString(arch: std.Target.Cpu.Arch) []const u8 {
|
||||
pub fn deinit(self: *MachO) void {
|
||||
self.offset_table.deinit(self.base.allocator);
|
||||
self.string_table.deinit(self.base.allocator);
|
||||
self.undef_symbols.deinit(self.base.allocator);
|
||||
self.global_symbols.deinit(self.base.allocator);
|
||||
self.local_symbols.deinit(self.base.allocator);
|
||||
self.sections.deinit(self.base.allocator);
|
||||
@ -813,7 +814,7 @@ pub fn updateDeclExports(
|
||||
try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: ExportOptions.section", .{}),
|
||||
try Compilation.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: ExportOptions.section", .{}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -831,7 +832,7 @@ pub fn updateDeclExports(
|
||||
try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}),
|
||||
try Compilation.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}),
|
||||
);
|
||||
continue;
|
||||
},
|
||||
@ -1405,6 +1406,8 @@ fn writeAllUndefSymbols(self: *MachO) !void {
|
||||
}
|
||||
|
||||
fn writeExportTrie(self: *MachO) !void {
|
||||
if (self.entry_addr == null) return;
|
||||
|
||||
// TODO implement mechanism for generating a prefix tree of the exported symbols
|
||||
// single branch export trie
|
||||
var buf = [_]u8{0} ** 24;
|
||||
|
||||
@ -151,6 +151,45 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
{
|
||||
var case = ctx.exe("hello world", macosx_x64);
|
||||
case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
|
||||
|
||||
// Incorrect return type
|
||||
case.addError(
|
||||
\\export fn _start() noreturn {
|
||||
\\}
|
||||
, &[_][]const u8{":2:1: error: expected noreturn, found void"});
|
||||
|
||||
// Regular old hello world
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ print();
|
||||
\\
|
||||
\\ exit();
|
||||
\\}
|
||||
\\
|
||||
\\fn print() void {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (0x2000004),
|
||||
\\ [arg1] "{rdi}" (1),
|
||||
\\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
|
||||
\\ [arg3] "{rdx}" (14)
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
\\
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (0x2000001),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"Hello, World!\n",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user