authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 00:39:31-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 19:22:52-04:00
log0bdfb288ccc58807355221d3e86451c33e390d01
tree6a381faa569dd9f824cedaa1973404c199298b46
parent47a34d038dd114533c3fcb130e03249ad846fe9c

x86_64: workaround tagName linker issues

Pass extra pointer param with a linker ref when calling the lazy tagName function to workaround not being able to lower linker refs during codegen of a lazy func.

1 files changed, 34 insertions(+), 45 deletions(-)

src/arch/x86_64/CodeGen.zig+34-45
...@@ -1641,48 +1641,16 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1641,48 +1641,16 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
1641 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)});1641 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)});
16421642
1643 const param_regs = abi.getCAbiIntParamRegs(self.target.*);1643 const param_regs = abi.getCAbiIntParamRegs(self.target.*);
1644 const param_locks = self.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*);1644 const param_locks = self.register_manager.lockRegsAssumeUnused(3, param_regs[0..3].*);
1645 defer for (param_locks) |lock| self.register_manager.unlockReg(lock);1645 defer for (param_locks) |lock| self.register_manager.unlockReg(lock);
16461646
1647 const ret_reg = param_regs[0];1647 const ret_reg = param_regs[0];
1648 const enum_mcv = MCValue{ .register = param_regs[1] };1648 const enum_mcv = MCValue{ .register = param_regs[1] };
1649 const data_mcv = MCValue{ .register = param_regs[2] };
16491650
1650 var exitlude_jump_relocs = try self.gpa.alloc(u32, enum_ty.enumFieldCount());1651 var exitlude_jump_relocs = try self.gpa.alloc(u32, enum_ty.enumFieldCount());
1651 defer self.gpa.free(exitlude_jump_relocs);1652 defer self.gpa.free(exitlude_jump_relocs);
16521653
1653 const data_reg = try self.register_manager.allocReg(null, gp);
1654 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);
1655 defer self.register_manager.unlockReg(data_lock);
1656
1657 const data_lazy_sym = link.File.LazySymbol{ .kind = .const_data, .ty = enum_ty };
1658 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1659 const atom_index = elf_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1660 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1661 const atom = elf_file.getAtom(atom_index);
1662 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
1663 const got_addr = atom.getOffsetTableAddress(elf_file);
1664 try self.asmRegisterMemory(
1665 .mov,
1666 data_reg.to64(),
1667 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
1668 );
1669 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
1670 const atom_index = coff_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1671 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1672 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
1673 try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index });
1674 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
1675 const atom_index = macho_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1676 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1677 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
1678 try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index });
1679 } else {
1680 return self.fail("TODO implement {s} for {}", .{
1681 @tagName(lazy_sym.kind),
1682 lazy_sym.ty.fmt(self.bin_file.options.module.?),
1683 });
1684 }
1685
1686 var data_off: i32 = 0;1654 var data_off: i32 = 0;
1687 for (1655 for (
1688 exitlude_jump_relocs,1656 exitlude_jump_relocs,
...@@ -1698,12 +1666,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1698,12 +1666,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
1698 try self.genBinOpMir(.cmp, enum_ty, enum_mcv, tag_mcv);1666 try self.genBinOpMir(.cmp, enum_ty, enum_mcv, tag_mcv);
1699 const skip_reloc = try self.asmJccReloc(undefined, .ne);1667 const skip_reloc = try self.asmJccReloc(undefined, .ne);
17001668
1701 try self.genSetMem(1669 try self.genSetMem(.{ .reg = ret_reg }, 0, Type.usize, data_mcv.offset(data_off));
1702 .{ .reg = ret_reg },
1703 0,
1704 Type.usize,
1705 .{ .register_offset = .{ .reg = data_reg, .off = data_off } },
1706 );
1707 try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len });1670 try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len });
17081671
1709 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);1672 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
...@@ -8663,6 +8626,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -8663,6 +8626,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
8663}8626}
86648627
8665fn airTagName(self: *Self, inst: Air.Inst.Index) !void {8628fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
8629 const mod = self.bin_file.options.module.?;
8666 const un_op = self.air.instructions.items(.data)[inst].un_op;8630 const un_op = self.air.instructions.items(.data)[inst].un_op;
8667 const inst_ty = self.air.typeOfIndex(inst);8631 const inst_ty = self.air.typeOfIndex(inst);
8668 const enum_ty = self.air.typeOf(un_op);8632 const enum_ty = self.air.typeOf(un_op);
...@@ -8693,10 +8657,35 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -8693,10 +8657,35 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
8693 const operand = try self.resolveInst(un_op);8657 const operand = try self.resolveInst(un_op);
8694 try self.genSetReg(param_regs[1], enum_ty, operand);8658 try self.genSetReg(param_regs[1], enum_ty, operand);
86958659
8696 const mod = self.bin_file.options.module.?;8660 const data_lazy_sym = link.File.LazySymbol.initDecl(.const_data, enum_ty.getOwnerDecl(), mod);
8697 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod);
8698 if (self.bin_file.cast(link.File.Elf)) |elf_file| {8661 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8699 const atom_index = elf_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|8662 const atom_index = elf_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
8663 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8664 const atom = elf_file.getAtom(atom_index);
8665 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
8666 const got_addr = atom.getOffsetTableAddress(elf_file);
8667 try self.asmRegisterMemory(
8668 .mov,
8669 param_regs[2],
8670 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
8671 );
8672 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8673 const atom_index = coff_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
8674 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8675 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8676 try self.genSetReg(param_regs[2], Type.usize, .{ .lea_got = sym_index });
8677 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8678 const atom_index = macho_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
8679 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8680 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8681 try self.genSetReg(param_regs[2], Type.usize, .{ .lea_got = sym_index });
8682 } else {
8683 return self.fail("TODO implement airTagName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
8684 }
8685
8686 const code_lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod);
8687 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8688 const atom_index = elf_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err|
8700 return self.fail("{s} creating lazy symbol", .{@errorName(err)});8689 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8701 const atom = elf_file.getAtom(atom_index);8690 const atom = elf_file.getAtom(atom_index);
8702 _ = try atom.getOrCreateOffsetTableEntry(elf_file);8691 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
...@@ -8706,13 +8695,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -8706,13 +8695,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
8706 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),8695 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
8707 );8696 );
8708 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {8697 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8709 const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|8698 const atom_index = coff_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err|
8710 return self.fail("{s} creating lazy symbol", .{@errorName(err)});8699 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8711 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;8700 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8712 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });8701 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8713 try self.asmRegister(.call, .rax);8702 try self.asmRegister(.call, .rax);
8714 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {8703 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8715 const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|8704 const atom_index = macho_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err|
8716 return self.fail("{s} creating lazy symbol", .{@errorName(err)});8705 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8717 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;8706 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8718 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });8707 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });