authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-01 03:08:55-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-02 04:49:53-04:00
log677427bc3ac839629654175f0a2aaaec9fd6fb6c
treedeb37ed3275cfef97f9d49d7e8a1eeea5a3c64db
parentccefa9dbf5369e0fadc75b9e705e74ec96a02859

x86_64: implement error name


11 files changed, 529 insertions(+), 42 deletions(-)

src/arch/x86_64/CodeGen.zig+102-25
...@@ -1923,7 +1923,7 @@ fn genSetStackTruncatedOverflowCompare(...@@ -1923,7 +1923,7 @@ fn genSetStackTruncatedOverflowCompare(
1923 );1923 );
19241924
1925 try self.genSetStack(ty, stack_offset, .{ .register = scratch_reg }, .{});1925 try self.genSetStack(ty, stack_offset, .{ .register = scratch_reg }, .{});
1926 try self.genSetStack(Type.initTag(.u1), stack_offset - overflow_bit_offset, .{1926 try self.genSetStack(Type.u1, stack_offset - overflow_bit_offset, .{
1927 .register = overflow_reg.to8(),1927 .register = overflow_reg.to8(),
1928 }, .{});1928 }, .{});
1929}1929}
...@@ -5280,8 +5280,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5280,8 +5280,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
52805280
5281 if (self.bin_file.cast(link.File.Elf)) |elf_file| {5281 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
5282 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);5282 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
5283 const atom = elf_file.getAtom(atom_index);5283 const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file);
5284 const got_addr = atom.getOffsetTableAddress(elf_file);
5285 try self.asmMemory(.call, Memory.sib(.qword, .{5284 try self.asmMemory(.call, Memory.sib(.qword, .{
5286 .base = .ds,5285 .base = .ds,
5287 .disp = @intCast(i32, got_addr),5286 .disp = @intCast(i32, got_addr),
...@@ -5289,22 +5288,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5289,22 +5288,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5289 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {5288 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5290 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);5289 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
5291 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;5290 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5292 try self.genSetReg(Type.initTag(.usize), .rax, .{5291 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5293 .linker_load = .{5292 .type = .got,
5294 .type = .got,5293 .sym_index = sym_index,
5295 .sym_index = sym_index,5294 } });
5296 },
5297 });
5298 try self.asmRegister(.call, .rax);5295 try self.asmRegister(.call, .rax);
5299 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {5296 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
5300 const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);5297 const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
5301 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;5298 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5302 try self.genSetReg(Type.initTag(.usize), .rax, .{5299 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5303 .linker_load = .{5300 .type = .got,
5304 .type = .got,5301 .sym_index = sym_index,
5305 .sym_index = sym_index,5302 } });
5306 },
5307 });
5308 try self.asmRegister(.call, .rax);5303 try self.asmRegister(.call, .rax);
5309 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {5304 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
5310 const decl_block_index = try p9.seeDecl(func.owner_decl);5305 const decl_block_index = try p9.seeDecl(func.owner_decl);
...@@ -5325,7 +5320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5325,7 +5320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5325 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);5320 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
5326 if (self.bin_file.cast(link.File.Coff)) |coff_file| {5321 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5327 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);5322 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
5328 try self.genSetReg(Type.initTag(.usize), .rax, .{5323 try self.genSetReg(Type.usize, .rax, .{
5329 .linker_load = .{5324 .linker_load = .{
5330 .type = .import,5325 .type = .import,
5331 .sym_index = sym_index,5326 .sym_index = sym_index,
...@@ -5353,7 +5348,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5353,7 +5348,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5353 } else {5348 } else {
5354 assert(ty.zigTypeTag() == .Pointer);5349 assert(ty.zigTypeTag() == .Pointer);
5355 const mcv = try self.resolveInst(callee);5350 const mcv = try self.resolveInst(callee);
5356 try self.genSetReg(Type.initTag(.usize), .rax, mcv);5351 try self.genSetReg(Type.usize, .rax, mcv);
5357 try self.asmRegister(.call, .rax);5352 try self.asmRegister(.call, .rax);
5358 }5353 }
53595354
...@@ -7299,7 +7294,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -7299,7 +7294,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
7299 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {7294 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
7300 const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16));7295 const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16));
7301 try self.genSetStack(ptr_ty, stack_offset, ptr, .{});7296 try self.genSetStack(ptr_ty, stack_offset, ptr, .{});
7302 try self.genSetStack(Type.initTag(.u64), stack_offset - 8, .{ .immediate = array_len }, .{});7297 try self.genSetStack(Type.u64, stack_offset - 8, .{ .immediate = array_len }, .{});
7303 break :blk .{ .stack_offset = stack_offset };7298 break :blk .{ .stack_offset = stack_offset };
7304 };7299 };
7305 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });7300 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -7809,10 +7804,92 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -7809,10 +7804,92 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
78097804
7810fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {7805fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
7811 const un_op = self.air.instructions.items(.data)[inst].un_op;7806 const un_op = self.air.instructions.items(.data)[inst].un_op;
7812 const operand = try self.resolveInst(un_op);7807 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
7813 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {7808 const err_ty = self.air.typeOf(un_op);
7814 _ = operand;7809 const err_mcv = try self.resolveInst(un_op);
7815 return self.fail("TODO implement airErrorName for x86_64", .{});7810 const err_reg = try self.copyToTmpRegister(err_ty, err_mcv);
7811 const err_lock = self.register_manager.lockRegAssumeUnused(err_reg);
7812 defer self.register_manager.unlockReg(err_lock);
7813
7814 const addr_reg = try self.register_manager.allocReg(null, gp);
7815 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
7816 defer self.register_manager.unlockReg(addr_lock);
7817
7818 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
7819 const atom_index = try elf_file.getOrCreateAtomForLazySymbol(
7820 .{ .kind = .const_data, .ty = Type.anyerror },
7821 4, // dword alignment
7822 );
7823 const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file);
7824 try self.asmRegisterMemory(.mov, addr_reg.to64(), Memory.sib(.qword, .{
7825 .base = .ds,
7826 .disp = @intCast(i32, got_addr),
7827 }));
7828 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
7829 const atom_index = try coff_file.getOrCreateAtomForLazySymbol(
7830 .{ .kind = .const_data, .ty = Type.anyerror },
7831 4, // dword alignment
7832 );
7833 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
7834 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
7835 .type = .got,
7836 .sym_index = sym_index,
7837 } });
7838 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
7839 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
7840 .{ .kind = .const_data, .ty = Type.anyerror },
7841 4, // dword alignment
7842 );
7843 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
7844 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
7845 .type = .got,
7846 .sym_index = sym_index,
7847 } });
7848 } else {
7849 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
7850 }
7851
7852 const start_reg = try self.register_manager.allocReg(null, gp);
7853 const start_lock = self.register_manager.lockRegAssumeUnused(start_reg);
7854 defer self.register_manager.unlockReg(start_lock);
7855
7856 const end_reg = try self.register_manager.allocReg(null, gp);
7857 const end_lock = self.register_manager.lockRegAssumeUnused(end_reg);
7858 defer self.register_manager.unlockReg(end_lock);
7859
7860 try self.truncateRegister(err_ty, err_reg.to32());
7861
7862 try self.asmRegisterMemory(.mov, start_reg.to32(), Memory.sib(.dword, .{
7863 .base = addr_reg.to64(),
7864 .scale_index = .{ .scale = 4, .index = err_reg.to64() },
7865 .disp = 0,
7866 }));
7867 try self.asmRegisterMemory(.mov, end_reg.to32(), Memory.sib(.dword, .{
7868 .base = addr_reg.to64(),
7869 .scale_index = .{ .scale = 4, .index = err_reg.to64() },
7870 .disp = 4,
7871 }));
7872 try self.asmRegisterRegister(.sub, end_reg.to32(), start_reg.to32());
7873 try self.asmRegisterMemory(.lea, start_reg.to64(), Memory.sib(.byte, .{
7874 .base = addr_reg.to64(),
7875 .scale_index = .{ .scale = 1, .index = start_reg.to64() },
7876 .disp = 0,
7877 }));
7878 try self.asmRegisterMemory(.lea, end_reg.to32(), Memory.sib(.byte, .{
7879 .base = end_reg.to64(),
7880 .disp = -1,
7881 }));
7882
7883 const dst_mcv = try self.allocRegOrMem(inst, false);
7884 try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{
7885 .base = .rbp,
7886 .disp = 0 - dst_mcv.stack_offset,
7887 }), start_reg.to64());
7888 try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{
7889 .base = .rbp,
7890 .disp = 8 - dst_mcv.stack_offset,
7891 }), end_reg.to64());
7892 break :result dst_mcv;
7816 };7893 };
7817 return self.finishAir(inst, result, .{ un_op, .none, .none });7894 return self.finishAir(inst, result, .{ un_op, .none, .none });
7818}7895}
...@@ -8046,7 +8123,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV...@@ -8046,7 +8123,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
8046 // This immediate is unsigned.8123 // This immediate is unsigned.
8047 const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed));8124 const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed));
8048 if (imm >= math.maxInt(U)) {8125 if (imm >= math.maxInt(U)) {
8049 return MCValue{ .register = try self.copyToTmpRegister(Type.initTag(.usize), mcv) };8126 return MCValue{ .register = try self.copyToTmpRegister(Type.usize, mcv) };
8050 }8127 }
8051 },8128 },
8052 else => {},8129 else => {},
...@@ -8321,8 +8398,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -8321,8 +8398,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
8321 .unsigned => {8398 .unsigned => {
8322 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);8399 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);
8323 const mask = (~@as(u64, 0)) >> shift;8400 const mask = (~@as(u64, 0)) >> shift;
8324 if (int_info.bits < 32) {8401 if (int_info.bits <= 32) {
8325 try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask });8402 try self.genBinOpMir(.@"and", Type.u32, .{ .register = reg }, .{ .immediate = mask });
8326 } else {8403 } else {
8327 const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });8404 const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });
8328 try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .register = tmp_reg });8405 try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .register = tmp_reg });
src/codegen.zig+44-7
...@@ -99,6 +99,47 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian...@@ -99,6 +99,47 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian
99 mem.writeInt(Int, code[0..@sizeOf(Int)], int, endian);99 mem.writeInt(Int, code[0..@sizeOf(Int)], int, endian);
100}100}
101101
102pub fn generateLazySymbol(
103 bin_file: *link.File,
104 src_loc: Module.SrcLoc,
105 lazy_sym: link.File.LazySymbol,
106 code: *std.ArrayList(u8),
107 debug_output: DebugInfoOutput,
108 reloc_info: RelocInfo,
109) CodeGenError!Result {
110 _ = debug_output;
111 _ = reloc_info;
112
113 const tracy = trace(@src());
114 defer tracy.end();
115
116 const target = bin_file.options.target;
117 const endian = target.cpu.arch.endian();
118
119 const mod = bin_file.options.module.?;
120 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
121 @tagName(lazy_sym.kind),
122 lazy_sym.ty.fmt(mod),
123 });
124
125 if (lazy_sym.kind == .const_data and lazy_sym.ty.isAnyError()) {
126 const err_names = mod.error_name_list.items;
127 try code.resize(err_names.len * 4);
128 for (err_names, 0..) |err_name, index| {
129 mem.writeInt(u32, code.items[index * 4 ..][0..4], @intCast(u32, code.items.len), endian);
130 try code.ensureUnusedCapacity(err_name.len + 1);
131 code.appendSliceAssumeCapacity(err_name);
132 code.appendAssumeCapacity(0);
133 }
134 return Result.ok;
135 } else return .{ .fail = try ErrorMsg.create(
136 bin_file.allocator,
137 src_loc,
138 "TODO implement generateLazySymbol for {s} {}",
139 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) },
140 ) };
141}
142
102pub fn generateSymbol(143pub fn generateSymbol(
103 bin_file: *link.File,144 bin_file: *link.File,
104 src_loc: Module.SrcLoc,145 src_loc: Module.SrcLoc,
...@@ -118,9 +159,10 @@ pub fn generateSymbol(...@@ -118,9 +159,10 @@ pub fn generateSymbol(
118 const target = bin_file.options.target;159 const target = bin_file.options.target;
119 const endian = target.cpu.arch.endian();160 const endian = target.cpu.arch.endian();
120161
162 const mod = bin_file.options.module.?;
121 log.debug("generateSymbol: ty = {}, val = {}", .{163 log.debug("generateSymbol: ty = {}, val = {}", .{
122 typed_value.ty.fmtDebug(),164 typed_value.ty.fmt(mod),
123 typed_value.val.fmtDebug(),165 typed_value.val.fmtValue(typed_value.ty, mod),
124 });166 });
125167
126 if (typed_value.val.isUndefDeep()) {168 if (typed_value.val.isUndefDeep()) {
...@@ -170,7 +212,6 @@ pub fn generateSymbol(...@@ -170,7 +212,6 @@ pub fn generateSymbol(
170 },212 },
171 .str_lit => {213 .str_lit => {
172 const str_lit = typed_value.val.castTag(.str_lit).?.data;214 const str_lit = typed_value.val.castTag(.str_lit).?.data;
173 const mod = bin_file.options.module.?;
174 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];215 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
175 try code.ensureUnusedCapacity(bytes.len + 1);216 try code.ensureUnusedCapacity(bytes.len + 1);
176 code.appendSliceAssumeCapacity(bytes);217 code.appendSliceAssumeCapacity(bytes);
...@@ -300,7 +341,6 @@ pub fn generateSymbol(...@@ -300,7 +341,6 @@ pub fn generateSymbol(
300 switch (container_ptr.tag()) {341 switch (container_ptr.tag()) {
301 .decl_ref => {342 .decl_ref => {
302 const decl_index = container_ptr.castTag(.decl_ref).?.data;343 const decl_index = container_ptr.castTag(.decl_ref).?.data;
303 const mod = bin_file.options.module.?;
304 const decl = mod.declPtr(decl_index);344 const decl = mod.declPtr(decl_index);
305 const addend = blk: {345 const addend = blk: {
306 switch (decl.ty.zigTypeTag()) {346 switch (decl.ty.zigTypeTag()) {
...@@ -493,7 +533,6 @@ pub fn generateSymbol(...@@ -493,7 +533,6 @@ pub fn generateSymbol(
493 const field_vals = typed_value.val.castTag(.aggregate).?.data;533 const field_vals = typed_value.val.castTag(.aggregate).?.data;
494 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;534 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
495 const current_pos = code.items.len;535 const current_pos = code.items.len;
496 const mod = bin_file.options.module.?;
497 try code.resize(current_pos + abi_size);536 try code.resize(current_pos + abi_size);
498 var bits: u16 = 0;537 var bits: u16 = 0;
499538
...@@ -570,7 +609,6 @@ pub fn generateSymbol(...@@ -570,7 +609,6 @@ pub fn generateSymbol(
570 }609 }
571610
572 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;611 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;
573 const mod = bin_file.options.module.?;
574 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;612 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;
575 assert(union_ty.haveFieldTypes());613 assert(union_ty.haveFieldTypes());
576 const field_ty = union_ty.fields.values()[field_index].ty;614 const field_ty = union_ty.fields.values()[field_index].ty;
...@@ -776,7 +814,6 @@ pub fn generateSymbol(...@@ -776,7 +814,6 @@ pub fn generateSymbol(
776 },814 },
777 .str_lit => {815 .str_lit => {
778 const str_lit = typed_value.val.castTag(.str_lit).?.data;816 const str_lit = typed_value.val.castTag(.str_lit).?.data;
779 const mod = bin_file.options.module.?;
780 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];817 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
781 try code.ensureUnusedCapacity(str_lit.len);818 try code.ensureUnusedCapacity(str_lit.len);
782 code.appendSliceAssumeCapacity(bytes);819 code.appendSliceAssumeCapacity(bytes);
src/link.zig+21
...@@ -687,6 +687,7 @@ pub const File = struct {...@@ -687,6 +687,7 @@ pub const File = struct {
687 FrameworkNotFound,687 FrameworkNotFound,
688 FunctionSignatureMismatch,688 FunctionSignatureMismatch,
689 GlobalTypeMismatch,689 GlobalTypeMismatch,
690 HotSwapUnavailableOnHostOperatingSystem,
690 InvalidCharacter,691 InvalidCharacter,
691 InvalidEntryKind,692 InvalidEntryKind,
692 InvalidFeatureSet,693 InvalidFeatureSet,
...@@ -1104,6 +1105,26 @@ pub const File = struct {...@@ -1104,6 +1105,26 @@ pub const File = struct {
1104 missing_libc: bool = false,1105 missing_libc: bool = false,
1105 };1106 };
11061107
1108 pub const LazySymbol = struct {
1109 kind: enum { code, const_data },
1110 ty: Type,
1111
1112 pub const Context = struct {
1113 mod: *Module,
1114
1115 pub fn hash(ctx: @This(), sym: LazySymbol) u32 {
1116 var hasher = std.hash.Wyhash.init(0);
1117 std.hash.autoHash(&hasher, sym.kind);
1118 sym.ty.hashWithHasher(&hasher, ctx.mod);
1119 return @truncate(u32, hasher.final());
1120 }
1121
1122 pub fn eql(ctx: @This(), lhs: LazySymbol, rhs: LazySymbol, _: usize) bool {
1123 return lhs.kind == rhs.kind and lhs.ty.eql(rhs.ty, ctx.mod);
1124 }
1125 };
1126 };
1127
1107 pub const C = @import("link/C.zig");1128 pub const C = @import("link/C.zig");
1108 pub const Coff = @import("link/Coff.zig");1129 pub const Coff = @import("link/Coff.zig");
1109 pub const Plan9 = @import("link/Plan9.zig");1130 pub const Plan9 = @import("link/Plan9.zig");
src/link/Coff.zig+122
...@@ -49,6 +49,9 @@ imports_count_dirty: bool = true,...@@ -49,6 +49,9 @@ imports_count_dirty: bool = true,
49/// Virtual address of the entry point procedure relative to image base.49/// Virtual address of the entry point procedure relative to image base.
50entry_addr: ?u32 = null,50entry_addr: ?u32 = null,
5151
52/// Table of tracked LazySymbols.
53lazy_syms: LazySymbolTable = .{},
54
52/// Table of tracked Decls.55/// Table of tracked Decls.
53decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},56decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
5457
...@@ -142,6 +145,18 @@ const Section = struct {...@@ -142,6 +145,18 @@ const Section = struct {
142 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},145 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
143};146};
144147
148const LazySymbolTable = std.ArrayHashMapUnmanaged(
149 link.File.LazySymbol,
150 LazySymbolMetadata,
151 link.File.LazySymbol.Context,
152 true,
153);
154
155const LazySymbolMetadata = struct {
156 atom: Atom.Index,
157 section: u16,
158};
159
145const DeclMetadata = struct {160const DeclMetadata = struct {
146 atom: Atom.Index,161 atom: Atom.Index,
147 section: u16,162 section: u16,
...@@ -1168,6 +1183,100 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !...@@ -1168,6 +1183,100 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
1168 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));1183 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
1169}1184}
11701185
1186fn updateLazySymbol(
1187 self: *Coff,
1188 lazy_sym: link.File.LazySymbol,
1189 lazy_metadata: LazySymbolMetadata,
1190) !void {
1191 const gpa = self.base.allocator;
1192 const mod = self.base.options.module.?;
1193
1194 var code_buffer = std.ArrayList(u8).init(gpa);
1195 defer code_buffer.deinit();
1196
1197 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1198 @tagName(lazy_sym.kind),
1199 lazy_sym.ty.fmt(mod),
1200 });
1201 defer gpa.free(name);
1202
1203 const atom_index = lazy_metadata.atom;
1204 const atom = self.getAtomPtr(atom_index);
1205 const local_sym_index = atom.getSymbolIndex().?;
1206
1207 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|
1208 mod.declPtr(owner_decl).srcLoc()
1209 else
1210 Module.SrcLoc{
1211 .file_scope = undefined,
1212 .parent_decl_node = undefined,
1213 .lazy = .unneeded,
1214 };
1215 const res = try codegen.generateLazySymbol(
1216 &self.base,
1217 src,
1218 lazy_sym,
1219 &code_buffer,
1220 .none,
1221 .{ .parent_atom_index = local_sym_index },
1222 );
1223 const code = switch (res) {
1224 .ok => code_buffer.items,
1225 .fail => |em| {
1226 log.err("{s}", .{em.msg});
1227 return error.CodegenFail;
1228 },
1229 };
1230
1231 const required_alignment = atom.alignment;
1232 const code_len = @intCast(u32, code.len);
1233 const symbol = atom.getSymbolPtr(self);
1234 try self.setSymbolName(symbol, name);
1235 symbol.section_number = @intToEnum(coff.SectionNumber, lazy_metadata.section + 1);
1236 symbol.type = .{ .complex_type = .NULL, .base_type = .NULL };
1237
1238 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
1239 errdefer self.freeAtom(atom_index);
1240
1241 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
1242 log.debug(" (required alignment 0x{x})", .{required_alignment});
1243
1244 atom.size = code_len;
1245 symbol.value = vaddr;
1246
1247 const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null };
1248 const got_index = try self.allocateGotEntry(got_target);
1249 const got_atom_index = try self.createGotAtom(got_target);
1250 const got_atom = self.getAtom(got_atom_index);
1251 self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
1252 try self.writePtrWidthAtom(got_atom_index);
1253
1254 self.markRelocsDirtyByTarget(atom.getSymbolWithLoc());
1255 try self.writeAtom(atom_index, code);
1256}
1257
1258pub fn getOrCreateAtomForLazySymbol(
1259 self: *Coff,
1260 lazy_sym: link.File.LazySymbol,
1261 alignment: u32,
1262) !Atom.Index {
1263 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{
1264 .mod = self.base.options.module.?,
1265 });
1266 errdefer _ = self.lazy_syms.pop();
1267 if (!gop.found_existing) {
1268 gop.value_ptr.* = .{
1269 .atom = try self.createAtom(),
1270 .section = switch (lazy_sym.kind) {
1271 .code => self.text_section_index.?,
1272 .const_data => self.rdata_section_index.?,
1273 },
1274 };
1275 self.getAtomPtr(gop.value_ptr.atom).alignment = alignment;
1276 }
1277 return gop.value_ptr.atom;
1278}
1279
1171pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {1280pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {
1172 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);1281 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
1173 if (!gop.found_existing) {1282 if (!gop.found_existing) {
...@@ -1498,6 +1607,19 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1498,6 +1607,19 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1498 sub_prog_node.activate();1607 sub_prog_node.activate();
1499 defer sub_prog_node.end();1608 defer sub_prog_node.end();
15001609
1610 {
1611 var lazy_it = self.lazy_syms.iterator();
1612 while (lazy_it.next()) |lazy_entry| {
1613 self.updateLazySymbol(
1614 lazy_entry.key_ptr.*,
1615 lazy_entry.value_ptr.*,
1616 ) catch |err| switch (err) {
1617 error.CodegenFail => return error.FlushFailure,
1618 else => |e| return e,
1619 };
1620 }
1621 }
1622
1501 const gpa = self.base.allocator;1623 const gpa = self.base.allocator;
15021624
1503 while (self.unresolved.popOrNull()) |entry| {1625 while (self.unresolved.popOrNull()) |entry| {
src/link/Elf.zig+114
...@@ -63,6 +63,12 @@ const Section = struct {...@@ -63,6 +63,12 @@ const Section = struct {
63 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},63 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
64};64};
6565
66const LazySymbolMetadata = struct {
67 atom: Atom.Index,
68 shdr: u16,
69 alignment: u32,
70};
71
66const DeclMetadata = struct {72const DeclMetadata = struct {
67 atom: Atom.Index,73 atom: Atom.Index,
68 shdr: u16,74 shdr: u16,
...@@ -157,6 +163,9 @@ debug_line_header_dirty: bool = false,...@@ -157,6 +163,9 @@ debug_line_header_dirty: bool = false,
157163
158error_flags: File.ErrorFlags = File.ErrorFlags{},164error_flags: File.ErrorFlags = File.ErrorFlags{},
159165
166/// Table of tracked LazySymbols.
167lazy_syms: LazySymbolTable = .{},
168
160/// Table of tracked Decls.169/// Table of tracked Decls.
161decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},170decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
162171
...@@ -194,6 +203,7 @@ relocs: RelocTable = .{},...@@ -194,6 +203,7 @@ relocs: RelocTable = .{},
194203
195const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc));204const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc));
196const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));205const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
206const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true);
197207
198/// When allocating, the ideal_capacity is calculated by208/// When allocating, the ideal_capacity is calculated by
199/// actual_capacity + (actual_capacity / ideal_factor)209/// actual_capacity + (actual_capacity / ideal_factor)
...@@ -1011,6 +1021,19 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1011,6 +1021,19 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1011 sub_prog_node.activate();1021 sub_prog_node.activate();
1012 defer sub_prog_node.end();1022 defer sub_prog_node.end();
10131023
1024 {
1025 var lazy_it = self.lazy_syms.iterator();
1026 while (lazy_it.next()) |lazy_entry| {
1027 self.updateLazySymbol(
1028 lazy_entry.key_ptr.*,
1029 lazy_entry.value_ptr.*,
1030 ) catch |err| switch (err) {
1031 error.CodegenFail => return error.FlushFailure,
1032 else => |e| return e,
1033 };
1034 }
1035 }
1036
1014 // TODO This linker code currently assumes there is only 1 compilation unit and it1037 // TODO This linker code currently assumes there is only 1 compilation unit and it
1015 // corresponds to the Zig source code.1038 // corresponds to the Zig source code.
1016 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;1039 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
...@@ -2344,6 +2367,24 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {...@@ -2344,6 +2367,24 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
2344 }2367 }
2345}2368}
23462369
2370pub fn getOrCreateAtomForLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, alignment: u32) !Atom.Index {
2371 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{
2372 .mod = self.base.options.module.?,
2373 });
2374 errdefer _ = self.lazy_syms.pop();
2375 if (!gop.found_existing) {
2376 gop.value_ptr.* = .{
2377 .atom = try self.createAtom(),
2378 .shdr = switch (lazy_sym.kind) {
2379 .code => self.text_section_index.?,
2380 .const_data => self.rodata_section_index.?,
2381 },
2382 .alignment = alignment,
2383 };
2384 }
2385 return gop.value_ptr.atom;
2386}
2387
2347pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {2388pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {
2348 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);2389 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
2349 if (!gop.found_existing) {2390 if (!gop.found_existing) {
...@@ -2610,6 +2651,79 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v...@@ -2610,6 +2651,79 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
2610 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));2651 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
2611}2652}
26122653
2654fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void {
2655 const gpa = self.base.allocator;
2656 const mod = self.base.options.module.?;
2657
2658 var code_buffer = std.ArrayList(u8).init(gpa);
2659 defer code_buffer.deinit();
2660
2661 const name_str_index = blk: {
2662 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
2663 @tagName(lazy_sym.kind),
2664 lazy_sym.ty.fmt(mod),
2665 });
2666 defer gpa.free(name);
2667 break :blk try self.shstrtab.insert(gpa, name);
2668 };
2669 const name = self.shstrtab.get(name_str_index).?;
2670
2671 const atom_index = lazy_metadata.atom;
2672 const atom = self.getAtom(atom_index);
2673 const local_sym_index = atom.getSymbolIndex().?;
2674
2675 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|
2676 mod.declPtr(owner_decl).srcLoc()
2677 else
2678 Module.SrcLoc{
2679 .file_scope = undefined,
2680 .parent_decl_node = undefined,
2681 .lazy = .unneeded,
2682 };
2683 const res = try codegen.generateLazySymbol(
2684 &self.base,
2685 src,
2686 lazy_sym,
2687 &code_buffer,
2688 .none,
2689 .{ .parent_atom_index = local_sym_index },
2690 );
2691 const code = switch (res) {
2692 .ok => code_buffer.items,
2693 .fail => |em| {
2694 log.err("{s}", .{em.msg});
2695 return error.CodegenFail;
2696 },
2697 };
2698
2699 const shdr_index = lazy_metadata.shdr;
2700 const phdr_index = self.sections.items(.phdr_index)[shdr_index];
2701 const local_sym = atom.getSymbolPtr(self);
2702 local_sym.* = .{
2703 .st_name = name_str_index,
2704 .st_info = (elf.STB_LOCAL << 4) | elf.STT_OBJECT,
2705 .st_other = 0,
2706 .st_shndx = shdr_index,
2707 .st_value = 0,
2708 .st_size = 0,
2709 };
2710 const required_alignment = lazy_metadata.alignment;
2711 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
2712 errdefer self.freeAtom(atom_index);
2713 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });
2714
2715 self.offset_table.items[atom.offset_table_index] = vaddr;
2716 local_sym.st_value = vaddr;
2717 local_sym.st_size = code.len;
2718
2719 try self.writeSymbol(local_sym_index);
2720 try self.writeOffsetTableEntry(atom.offset_table_index);
2721
2722 const section_offset = vaddr - self.program_headers.items[phdr_index].p_vaddr;
2723 const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
2724 try self.base.file.?.pwriteAll(code, file_offset);
2725}
2726
2613pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 {2727pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 {
2614 const gpa = self.base.allocator;2728 const gpa = self.base.allocator;
26152729
src/link/MachO.zig+126-4
...@@ -218,6 +218,9 @@ bindings: BindingTable = .{},...@@ -218,6 +218,9 @@ bindings: BindingTable = .{},
218/// this will be a table indexed by index into the list of Atoms.218/// this will be a table indexed by index into the list of Atoms.
219lazy_bindings: BindingTable = .{},219lazy_bindings: BindingTable = .{},
220220
221/// Table of tracked LazySymbols.
222lazy_syms: LazySymbolTable = .{},
223
221/// Table of tracked Decls.224/// Table of tracked Decls.
222decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},225decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
223226
...@@ -229,6 +232,18 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {...@@ -229,6 +232,18 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {
229 else => false,232 else => false,
230};233};
231234
235const LazySymbolTable = std.ArrayHashMapUnmanaged(
236 link.File.LazySymbol,
237 LazySymbolMetadata,
238 link.File.LazySymbol.Context,
239 true,
240);
241
242const LazySymbolMetadata = struct {
243 atom: Atom.Index,
244 section: u8,
245};
246
232const DeclMetadata = struct {247const DeclMetadata = struct {
233 atom: Atom.Index,248 atom: Atom.Index,
234 section: u8,249 section: u8,
...@@ -497,6 +512,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -497,6 +512,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
497 sub_prog_node.activate();512 sub_prog_node.activate();
498 defer sub_prog_node.end();513 defer sub_prog_node.end();
499514
515 {
516 var lazy_it = self.lazy_syms.iterator();
517 while (lazy_it.next()) |lazy_entry| {
518 self.updateLazySymbol(
519 lazy_entry.key_ptr.*,
520 lazy_entry.value_ptr.*,
521 ) catch |err| switch (err) {
522 error.CodegenFail => return error.FlushFailure,
523 else => |e| return e,
524 };
525 }
526 }
527
500 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;528 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
501529
502 if (self.d_sym) |*d_sym| {530 if (self.d_sym) |*d_sym| {
...@@ -2163,13 +2191,13 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu...@@ -2163,13 +2191,13 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
21632191
2164 const name_str_index = blk: {2192 const name_str_index = blk: {
2165 const index = unnamed_consts.items.len;2193 const index = unnamed_consts.items.len;
2166 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });2194 const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index });
2167 defer gpa.free(name);2195 defer gpa.free(name);
2168 break :blk try self.strtab.insert(gpa, name);2196 break :blk try self.strtab.insert(gpa, name);
2169 };2197 };
2170 const name = self.strtab.get(name_str_index);2198 const name = self.strtab.get(name_str_index).?;
21712199
2172 log.debug("allocating symbol indexes for {?s}", .{name});2200 log.debug("allocating symbol indexes for {s}", .{name});
21732201
2174 const atom_index = try self.createAtom();2202 const atom_index = try self.createAtom();
21752203
...@@ -2202,7 +2230,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu...@@ -2202,7 +2230,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
22022230
2203 try unnamed_consts.append(gpa, atom_index);2231 try unnamed_consts.append(gpa, atom_index);
22042232
2205 log.debug("allocated atom for {?s} at 0x{x}", .{ name, symbol.n_value });2233 log.debug("allocated atom for {s} at 0x{x}", .{ name, symbol.n_value });
2206 log.debug(" (required alignment 0x{x})", .{required_alignment});2234 log.debug(" (required alignment 0x{x})", .{required_alignment});
22072235
2208 try self.writeAtom(atom_index, code);2236 try self.writeAtom(atom_index, code);
...@@ -2282,6 +2310,100 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)...@@ -2282,6 +2310,100 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
2282 try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));2310 try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
2283}2311}
22842312
2313fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void {
2314 const gpa = self.base.allocator;
2315 const mod = self.base.options.module.?;
2316
2317 var code_buffer = std.ArrayList(u8).init(gpa);
2318 defer code_buffer.deinit();
2319
2320 const name_str_index = blk: {
2321 const name = try std.fmt.allocPrint(gpa, "___lazy_{s}_{}", .{
2322 @tagName(lazy_sym.kind),
2323 lazy_sym.ty.fmt(mod),
2324 });
2325 defer gpa.free(name);
2326 break :blk try self.strtab.insert(gpa, name);
2327 };
2328 const name = self.strtab.get(name_str_index).?;
2329
2330 const atom_index = lazy_metadata.atom;
2331 const atom = self.getAtomPtr(atom_index);
2332 const local_sym_index = atom.getSymbolIndex().?;
2333
2334 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|
2335 mod.declPtr(owner_decl).srcLoc()
2336 else
2337 Module.SrcLoc{
2338 .file_scope = undefined,
2339 .parent_decl_node = undefined,
2340 .lazy = .unneeded,
2341 };
2342 const res = try codegen.generateLazySymbol(
2343 &self.base,
2344 src,
2345 lazy_sym,
2346 &code_buffer,
2347 .none,
2348 .{ .parent_atom_index = local_sym_index },
2349 );
2350 const code = switch (res) {
2351 .ok => code_buffer.items,
2352 .fail => |em| {
2353 log.err("{s}", .{em.msg});
2354 return error.CodegenFail;
2355 },
2356 };
2357
2358 const required_alignment = atom.alignment;
2359 const symbol = atom.getSymbolPtr(self);
2360 symbol.n_strx = name_str_index;
2361 symbol.n_type = macho.N_SECT;
2362 symbol.n_sect = lazy_metadata.section + 1;
2363 symbol.n_desc = 0;
2364
2365 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
2366 errdefer self.freeAtom(atom_index);
2367
2368 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
2369 log.debug(" (required alignment 0x{x}", .{required_alignment});
2370
2371 atom.size = code.len;
2372 symbol.n_value = vaddr;
2373
2374 const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null };
2375 const got_index = try self.allocateGotEntry(got_target);
2376 const got_atom_index = try self.createGotAtom(got_target);
2377 const got_atom = self.getAtom(got_atom_index);
2378 self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
2379 try self.writePtrWidthAtom(got_atom_index);
2380
2381 self.markRelocsDirtyByTarget(atom.getSymbolWithLoc());
2382 try self.writeAtom(atom_index, code);
2383}
2384
2385pub fn getOrCreateAtomForLazySymbol(
2386 self: *MachO,
2387 lazy_sym: File.LazySymbol,
2388 alignment: u32,
2389) !Atom.Index {
2390 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{
2391 .mod = self.base.options.module.?,
2392 });
2393 errdefer _ = self.lazy_syms.pop();
2394 if (!gop.found_existing) {
2395 gop.value_ptr.* = .{
2396 .atom = try self.createAtom(),
2397 .section = switch (lazy_sym.kind) {
2398 .code => self.text_section_index.?,
2399 .const_data => self.data_const_section_index.?,
2400 },
2401 };
2402 self.getAtomPtr(gop.value_ptr.atom).alignment = alignment;
2403 }
2404 return gop.value_ptr.atom;
2405}
2406
2285pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {2407pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {
2286 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);2408 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
2287 if (!gop.found_existing) {2409 if (!gop.found_existing) {
test/behavior/bugs/6047.zig-1
...@@ -11,7 +11,6 @@ fn getError2() !void {...@@ -11,7 +11,6 @@ fn getError2() !void {
1111
12test "`try`ing an if/else expression" {12test "`try`ing an if/else expression" {
13 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/defer.zig-1
...@@ -110,7 +110,6 @@ test "mixing normal and error defers" {...@@ -110,7 +110,6 @@ test "mixing normal and error defers" {
110}110}
111111
112test "errdefer with payload" {112test "errdefer with payload" {
113 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
115 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/error.zig-2
...@@ -575,7 +575,6 @@ fn gimmeItBroke() anyerror {...@@ -575,7 +575,6 @@ fn gimmeItBroke() anyerror {
575}575}
576576
577test "@errorName sentinel length matches slice length" {577test "@errorName sentinel length matches slice length" {
578 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
579 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;578 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
580 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;579 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
581 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO580 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -851,7 +850,6 @@ test "catch within a function that calls no errorable functions" {...@@ -851,7 +850,6 @@ test "catch within a function that calls no errorable functions" {
851test "error from comptime string" {850test "error from comptime string" {
852 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO851 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
853 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO852 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
854 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
855 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO853 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
856854
857 const name = "Weird error name!";855 const name = "Weird error name!";
test/behavior/optional.zig-1
...@@ -468,7 +468,6 @@ test "peer type resolution in nested if expressions" {...@@ -468,7 +468,6 @@ test "peer type resolution in nested if expressions" {
468test "cast slice to const slice nested in error union and optional" {468test "cast slice to const slice nested in error union and optional" {
469 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;469 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
471 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
472471
473 const S = struct {472 const S = struct {
474 fn inner() !?[]u8 {473 fn inner() !?[]u8 {
test/behavior/switch.zig-1
...@@ -419,7 +419,6 @@ test "switch on integer with else capturing expr" {...@@ -419,7 +419,6 @@ test "switch on integer with else capturing expr" {
419}419}
420420
421test "else prong of switch on error set excludes other cases" {421test "else prong of switch on error set excludes other cases" {
422 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
423 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO422 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
424 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO423 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
425 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO424 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO