aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJacob G-W <jacoblevgw@gmail.com>2021-06-13 21:29:32 -0400
committerAndrew Kelley <andrew@ziglang.org>2021-07-08 14:12:07 -0700
commitdb2d5b49c693b8a38743232b83a6ee1eab8e6468 (patch)
tree5d52790c19c1bd35bb7a85699f9777c267aeea46 /src/codegen.zig
parent166dffb08811cb4ad7ea8ca65ef99b49d2986b94 (diff)
downloadzig-db2d5b49c693b8a38743232b83a6ee1eab8e6468.tar.gz
zig-db2d5b49c693b8a38743232b83a6ee1eab8e6468.zip
plan9 linker: use a global offset table
this simplifies stuff and makes us not have to use relocations
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index b70c06c7d6..87f287b674 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2593,14 +2593,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
}
if (inst.func.value()) |func_value| {
if (func_value.castTag(.function)) |func_payload| {
- try self.genSetReg(inst.base.src, Type.initTag(.u64), .rax, .{ .immediate = 0xdeadbeefdeadbeef });
- try p9.addCallReloc(self.code, .{
- .caller = p9.cur_decl,
- .callee = func_payload.data.owner_decl,
- .offset_in_caller = self.code.items.len,
- });
- // call rax
- try self.code.appendSlice(&.{ 0xff, 0xd0 });
+ const ptr_bits = self.target.cpu.arch.ptrBitWidth();
+ const ptr_bytes: u64 = @divExact(ptr_bits, 8);
+ const got_addr = p9.bases.data;
+ const got_index = func_payload.data.owner_decl.link.plan9.got_index.?;
+ // 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 });
+ const fn_got_addr = got_addr + got_index * ptr_bytes;
+ mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), @intCast(u32, fn_got_addr));
} else return self.fail(inst.base.src, "TODO implement calling extern fn on plan9", .{});
} else {
return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
@@ -4273,6 +4274,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
const decl = payload.data;
const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
return MCValue{ .memory = got_addr };
+ } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
+ const decl = payload.data;
+ const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
+ return MCValue{ .memory = got_addr };
} else {
return self.fail(src, "TODO codegen non-ELF const Decl pointer", .{});
}