authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-05-01 13:41:42+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 19:22:52-04:00
log565f8979cc38d46b8b905f3a8b7db03238779ffc
tree2edf8690b21953f2c9c90854ffea0b2a1f38b821
parent7064d7dbf0157aed9b497e1158243e472082633f

link: fix accessing source atom's symbol index in codegen

Since the owner can either be a `Decl` or a `LazySymbol` we need to preserve this information at the codegen generate function level so that we can then correctly work out the corresponding `Atom` in the linker.

2 files changed, 62 insertions(+), 39 deletions(-)

src/arch/x86_64/CodeGen.zig+60-34
...@@ -56,10 +56,7 @@ liveness: Liveness,...@@ -56,10 +56,7 @@ liveness: Liveness,
56bin_file: *link.File,56bin_file: *link.File,
57debug_output: DebugInfoOutput,57debug_output: DebugInfoOutput,
58target: *const std.Target,58target: *const std.Target,
59owner: union(enum) {59owner: Owner,
60 mod_fn: *const Module.Fn,
61 decl: Module.Decl.Index,
62},
63err_msg: ?*ErrorMsg,60err_msg: ?*ErrorMsg,
64args: []MCValue,61args: []MCValue,
65ret_mcv: InstTracking,62ret_mcv: InstTracking,
...@@ -111,6 +108,44 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged...@@ -111,6 +108,44 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged
111const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };108const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
112const RegisterOffset = struct { reg: Register, off: i32 = 0 };109const RegisterOffset = struct { reg: Register, off: i32 = 0 };
113110
111const Owner = union(enum) {
112 mod_fn: *const Module.Fn,
113 lazy_sym: link.File.LazySymbol,
114
115 fn getOwnerDecl(owner: Owner) Module.Decl.Index {
116 return switch (owner) {
117 .mod_fn => |mod_fn| mod_fn.owner_decl,
118 .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(),
119 };
120 }
121
122 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
123 switch (owner) {
124 .mod_fn => |mod_fn| {
125 const decl_index = mod_fn.owner_decl;
126 if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
127 const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
128 return macho_file.getAtom(atom).getSymbolIndex().?;
129 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
130 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
131 return coff_file.getAtom(atom).getSymbolIndex().?;
132 } else unreachable;
133 },
134 .lazy_sym => |lazy_sym| {
135 if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
136 const atom = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
137 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
138 return macho_file.getAtom(atom).getSymbolIndex().?;
139 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
140 const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
141 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
142 return coff_file.getAtom(atom).getSymbolIndex().?;
143 } else unreachable;
144 },
145 }
146 }
147};
148
114pub const MCValue = union(enum) {149pub const MCValue = union(enum) {
115 /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc.150 /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc.
116 /// TODO Look into deleting this tag and using `dead` instead, since every use151 /// TODO Look into deleting this tag and using `dead` instead, since every use
...@@ -763,7 +798,7 @@ pub fn generateLazy(...@@ -763,7 +798,7 @@ pub fn generateLazy(
763 .target = &bin_file.options.target,798 .target = &bin_file.options.target,
764 .bin_file = bin_file,799 .bin_file = bin_file,
765 .debug_output = debug_output,800 .debug_output = debug_output,
766 .owner = .{ .decl = lazy_sym.ty.getOwnerDecl() },801 .owner = .{ .lazy_sym = lazy_sym },
767 .err_msg = null,802 .err_msg = null,
768 .args = undefined,803 .args = undefined,
769 .ret_mcv = undefined,804 .ret_mcv = undefined,
...@@ -1724,13 +1759,6 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1724,13 +1759,6 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
1724 }1759 }
1725}1760}
17261761
1727fn getOwnerDecl(self: *const Self) Module.Decl.Index {
1728 return switch (self.owner) {
1729 .mod_fn => |mod_fn| mod_fn.owner_decl,
1730 .decl => |index| index,
1731 };
1732}
1733
1734fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void {1762fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void {
1735 const reg = value.getReg() orelse return;1763 const reg = value.getReg() orelse return;
1736 if (self.register_manager.isRegFree(reg)) {1764 if (self.register_manager.isRegFree(reg)) {
...@@ -6230,7 +6258,10 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {...@@ -6230,7 +6258,10 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
6230 //},6258 //},
6231 else => unreachable, // not a valid function parameter6259 else => unreachable, // not a valid function parameter
6232 };6260 };
6233 try dw.genArgDbgInfo(name, ty, self.getOwnerDecl(), loc);6261 // TODO: this might need adjusting like the linkers do.
6262 // Instead of flattening the owner and passing Decl.Index here we may
6263 // want to special case LazySymbol in DWARF linker too.
6264 try dw.genArgDbgInfo(name, ty, self.owner.getOwnerDecl(), loc);
6234 },6265 },
6235 .plan9 => {},6266 .plan9 => {},
6236 .none => {},6267 .none => {},
...@@ -6271,7 +6302,10 @@ fn genVarDbgInfo(...@@ -6271,7 +6302,10 @@ fn genVarDbgInfo(
6271 break :blk .nop;6302 break :blk .nop;
6272 },6303 },
6273 };6304 };
6274 try dw.genVarDbgInfo(name, ty, self.getOwnerDecl(), is_ptr, loc);6305 // TODO: this might need adjusting like the linkers do.
6306 // Instead of flattening the owner and passing Decl.Index here we may
6307 // want to special case LazySymbol in DWARF linker too.
6308 try dw.genVarDbgInfo(name, ty, self.owner.getOwnerDecl(), is_ptr, loc);
6275 },6309 },
6276 .plan9 => {},6310 .plan9 => {},
6277 .none => {},6311 .none => {},
...@@ -6403,12 +6437,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -6403,12 +6437,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
6403 .base = .{ .reg = .ds },6437 .base = .{ .reg = .ds },
6404 .disp = @intCast(i32, got_addr),6438 .disp = @intCast(i32, got_addr),
6405 }));6439 }));
6406 } else if (self.bin_file.cast(link.File.Coff)) |_| {6440 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6407 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);6441 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
6442 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
6408 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });6443 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
6409 try self.asmRegister(.call, .rax);6444 try self.asmRegister(.call, .rax);
6410 } else if (self.bin_file.cast(link.File.MachO)) |_| {6445 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
6411 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);6446 const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
6447 const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
6412 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });6448 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
6413 try self.asmRegister(.call, .rax);6449 try self.asmRegister(.call, .rax);
6414 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {6450 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
...@@ -6429,7 +6465,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -6429,7 +6465,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
6429 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);6465 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);
6430 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);6466 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
6431 if (self.bin_file.cast(link.File.Coff)) |coff_file| {6467 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6432 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());6468 const atom_index = try self.owner.getSymbolIndex(self);
6433 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);6469 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
6434 _ = try self.addInst(.{6470 _ = try self.addInst(.{
6435 .tag = .mov_linker,6471 .tag = .mov_linker,
...@@ -6442,8 +6478,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -6442,8 +6478,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
6442 });6478 });
6443 try self.asmRegister(.call, .rax);6479 try self.asmRegister(.call, .rax);
6444 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {6480 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
6481 const atom_index = try self.owner.getSymbolIndex(self);
6445 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);6482 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
6446 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
6447 _ = try self.addInst(.{6483 _ = try self.addInst(.{
6448 .tag = .call_extern,6484 .tag = .call_extern,
6449 .ops = undefined,6485 .ops = undefined,
...@@ -7719,7 +7755,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7719,7 +7755,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7719 }),7755 }),
7720 ),7756 ),
7721 .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) {7757 .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) {
7722 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());7758 const atom_index = try self.owner.getSymbolIndex(self);
7723 _ = try self.addInst(.{7759 _ = try self.addInst(.{
7724 .tag = .mov_linker,7760 .tag = .mov_linker,
7725 .ops = .direct_reloc,7761 .ops = .direct_reloc,
...@@ -7746,7 +7782,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7746,7 +7782,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7746 );7782 );
7747 },7783 },
7748 .lea_direct, .lea_got => |sym_index| {7784 .lea_direct, .lea_got => |sym_index| {
7749 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());7785 const atom_index = try self.owner.getSymbolIndex(self);
7750 _ = try self.addInst(.{7786 _ = try self.addInst(.{
7751 .tag = switch (src_mcv) {7787 .tag = switch (src_mcv) {
7752 .lea_direct => .lea_linker,7788 .lea_direct => .lea_linker,
...@@ -7766,7 +7802,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7766,7 +7802,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7766 });7802 });
7767 },7803 },
7768 .lea_tlv => |sym_index| {7804 .lea_tlv => |sym_index| {
7769 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());7805 const atom_index = try self.owner.getSymbolIndex(self);
7770 if (self.bin_file.cast(link.File.MachO)) |_| {7806 if (self.bin_file.cast(link.File.MachO)) |_| {
7771 _ = try self.addInst(.{7807 _ = try self.addInst(.{
7772 .tag = .lea_linker,7808 .tag = .lea_linker,
...@@ -9079,7 +9115,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV...@@ -9079,7 +9115,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
9079}9115}
90809116
9081fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {9117fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
9082 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.getOwnerDecl())) {9118 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getOwnerDecl())) {
9083 .mcv => |mcv| switch (mcv) {9119 .mcv => |mcv| switch (mcv) {
9084 .none => .none,9120 .none => .none,
9085 .undef => .undef,9121 .undef => .undef,
...@@ -9390,13 +9426,3 @@ fn regBitSize(self: *Self, ty: Type) u64 {...@@ -9390,13 +9426,3 @@ fn regBitSize(self: *Self, ty: Type) u64 {
9390fn regExtraBits(self: *Self, ty: Type) u64 {9426fn regExtraBits(self: *Self, ty: Type) u64 {
9391 return self.regBitSize(ty) - ty.bitSize(self.target.*);9427 return self.regBitSize(ty) - ty.bitSize(self.target.*);
9392}9428}
9393
9394fn getSymbolIndexForDecl(self: *Self, decl_index: Module.Decl.Index) !u32 {
9395 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
9396 const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
9397 return macho_file.getAtom(atom).getSymbolIndex().?;
9398 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
9399 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
9400 return coff_file.getAtom(atom).getSymbolIndex().?;
9401 } else unreachable;
9402}
src/link/MachO.zig+2-5
...@@ -2112,7 +2112,7 @@ fn updateLazySymbolAtom(...@@ -2112,7 +2112,7 @@ fn updateLazySymbolAtom(
2112 errdefer self.freeAtom(atom_index);2112 errdefer self.freeAtom(atom_index);
21132113
2114 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });2114 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
2115 log.debug(" (required alignment 0x{x}", .{required_alignment});2115 log.debug(" (required alignment 0x{x})", .{required_alignment});
21162116
2117 atom.size = code.len;2117 atom.size = code.len;
2118 symbol.n_value = vaddr;2118 symbol.n_value = vaddr;
...@@ -4157,9 +4157,6 @@ pub fn logSymtab(self: *MachO) void {...@@ -4157,9 +4157,6 @@ pub fn logSymtab(self: *MachO) void {
41574157
4158 log.debug("stubs entries:", .{});4158 log.debug("stubs entries:", .{});
4159 log.debug("{}", .{self.stub_table});4159 log.debug("{}", .{self.stub_table});
4160
4161 // log.debug("threadlocal entries:", .{});
4162 // log.debug("{}", .{self.tlv_table});
4163}4160}
41644161
4165pub fn logAtoms(self: *MachO) void {4162pub fn logAtoms(self: *MachO) void {
...@@ -4199,6 +4196,6 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void {...@@ -4199,6 +4196,6 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void {
4199 sym.n_value,4196 sym.n_value,
4200 atom.size,4197 atom.size,
4201 atom.file,4198 atom.file,
4202 sym.n_sect,4199 sym.n_sect + 1,
4203 });4200 });
4204}4201}