diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-06-16 21:57:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-16 21:57:33 -0700 |
| commit | 78c8cb4225c3c3d429764151ad703a4bfa67d75a (patch) | |
| tree | 8352b61ff54c133f78e4b8d1e05714561ee105bb /src/arch/x86_64/CodeGen.zig | |
| parent | 0f5aff34414bcb024443540fe905039f3783803a (diff) | |
| parent | 5343a2f566a5c235055f4aebb4ab9c10773e57f0 (diff) | |
| download | zig-78c8cb4225c3c3d429764151ad703a4bfa67d75a.tar.gz zig-78c8cb4225c3c3d429764151ad703a4bfa67d75a.zip | |
Merge pull request #16003 from g-w1/plan9-lazy-syms
Plan9: lots of fixes
Diffstat (limited to 'src/arch/x86_64/CodeGen.zig')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 6d98ecce4f..6e13a55008 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -130,6 +130,8 @@ const Owner = union(enum) { } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { const atom = try coff_file.getOrCreateAtomForDecl(decl_index); return coff_file.getAtom(atom).getSymbolIndex().?; + } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| { + return p9_file.seeDecl(decl_index); } else unreachable; }, .lazy_sym => |lazy_sym| { @@ -141,6 +143,9 @@ const Owner = union(enum) { const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); return coff_file.getAtom(atom).getSymbolIndex().?; + } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| { + return p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| + return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); } else unreachable; }, } @@ -8115,16 +8120,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); try self.asmRegister(.{ ._, .call }, .rax); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - const decl_block_index = try p9.seeDecl(owner_decl); - const decl_block = p9.getDeclBlock(decl_block_index); - const ptr_bits = self.target.ptrBitWidth(); - const ptr_bytes: u64 = @divExact(ptr_bits, 8); - const got_addr = p9.bases.data; - const got_index = decl_block.got_index.?; - const fn_got_addr = got_addr + got_index * ptr_bytes; + const atom_index = try p9.seeDecl(owner_decl); + const atom = p9.getAtom(atom_index); try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ .base = .{ .reg = .ds }, - .disp = @intCast(i32, fn_got_addr), + .disp = @intCast(i32, atom.getOffsetTableAddress(p9)), })); } else unreachable; } else if (func_value.getExternFunc(mod)) |extern_func| { @@ -10092,6 +10092,28 @@ fn genLazySymbolRef( ), else => unreachable, } + } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { + const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| + return self.fail("{s} creating lazy symbol", .{@errorName(err)}); + var atom = p9_file.getAtom(atom_index); + _ = atom.getOrCreateOffsetTableEntry(p9_file); + const got_addr = atom.getOffsetTableAddress(p9_file); + const got_mem = + Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }); + switch (tag) { + .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem), + .call => try self.asmMemory(.{ ._, .call }, got_mem), + else => unreachable, + } + switch (tag) { + .lea, .call => {}, + .mov => try self.asmRegisterMemory( + .{ ._, tag }, + reg.to64(), + Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), + ), + else => unreachable, + } } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
