| author | |
| committer | |
| log | 677427bc3ac839629654175f0a2aaaec9fd6fb6c |
| tree | deb37ed3275cfef97f9d49d7e8a1eeea5a3c64db |
| parent | ccefa9dbf5369e0fadc75b9e705e74ec96a02859 |
11 files changed, 529 insertions(+), 42 deletions(-)
src/arch/x86_64/CodeGen.zig+102-25| ... | ... | @@ -1923,7 +1923,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1923 | 1923 | ); |
| 1924 | 1924 | |
| 1925 | 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 | 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 | 5280 | |
| 5281 | 5281 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 5282 | 5282 | const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); |
| 5283 | const atom = elf_file.getAtom(atom_index); | |
| 5284 | const got_addr = atom.getOffsetTableAddress(elf_file); | |
| 5283 | const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file); | |
| 5285 | 5284 | try self.asmMemory(.call, Memory.sib(.qword, .{ |
| 5286 | 5285 | .base = .ds, |
| 5287 | 5286 | .disp = @intCast(i32, got_addr), |
| ... | ... | @@ -5289,22 +5288,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5289 | 5288 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 5290 | 5289 | const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| 5291 | 5290 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 5292 | try self.genSetReg(Type.initTag(.usize), .rax, .{ | |
| 5293 | .linker_load = .{ | |
| 5294 | .type = .got, | |
| 5295 | .sym_index = sym_index, | |
| 5296 | }, | |
| 5297 | }); | |
| 5291 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | |
| 5292 | .type = .got, | |
| 5293 | .sym_index = sym_index, | |
| 5294 | } }); | |
| 5298 | 5295 | try self.asmRegister(.call, .rax); |
| 5299 | 5296 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5300 | 5297 | const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); |
| 5301 | 5298 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 5302 | try self.genSetReg(Type.initTag(.usize), .rax, .{ | |
| 5303 | .linker_load = .{ | |
| 5304 | .type = .got, | |
| 5305 | .sym_index = sym_index, | |
| 5306 | }, | |
| 5307 | }); | |
| 5299 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | |
| 5300 | .type = .got, | |
| 5301 | .sym_index = sym_index, | |
| 5302 | } }); | |
| 5308 | 5303 | try self.asmRegister(.call, .rax); |
| 5309 | 5304 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 5310 | 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 | 5320 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 5326 | 5321 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 5327 | 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 | 5324 | .linker_load = .{ |
| 5330 | 5325 | .type = .import, |
| 5331 | 5326 | .sym_index = sym_index, |
| ... | ... | @@ -5353,7 +5348,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5353 | 5348 | } else { |
| 5354 | 5349 | assert(ty.zigTypeTag() == .Pointer); |
| 5355 | 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 | 5352 | try self.asmRegister(.call, .rax); |
| 5358 | 5353 | } |
| 5359 | 5354 | |
| ... | ... | @@ -7299,7 +7294,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 7299 | 7294 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: { |
| 7300 | 7295 | const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); |
| 7301 | 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 | 7298 | break :blk .{ .stack_offset = stack_offset }; |
| 7304 | 7299 | }; |
| 7305 | 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 | 7804 | |
| 7810 | 7805 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 7811 | 7806 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 7812 | const operand = try self.resolveInst(un_op); | |
| 7813 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else { | |
| 7814 | _ = operand; | |
| 7815 | return self.fail("TODO implement airErrorName for x86_64", .{}); | |
| 7807 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | |
| 7808 | const err_ty = self.air.typeOf(un_op); | |
| 7809 | const err_mcv = try self.resolveInst(un_op); | |
| 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 | 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 | 8123 | // This immediate is unsigned. |
| 8047 | 8124 | const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed)); |
| 8048 | 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 | 8129 | else => {}, |
| ... | ... | @@ -8321,8 +8398,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 8321 | 8398 | .unsigned => { |
| 8322 | 8399 | const shift = @intCast(u6, max_reg_bit_width - int_info.bits); |
| 8323 | 8400 | const mask = (~@as(u64, 0)) >> shift; |
| 8324 | if (int_info.bits < 32) { | |
| 8325 | try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask }); | |
| 8401 | if (int_info.bits <= 32) { | |
| 8402 | try self.genBinOpMir(.@"and", Type.u32, .{ .register = reg }, .{ .immediate = mask }); | |
| 8326 | 8403 | } else { |
| 8327 | 8404 | const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); |
| 8328 | 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 | 99 | mem.writeInt(Int, code[0..@sizeOf(Int)], int, endian); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | pub 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 | ||
| 102 | 143 | pub fn generateSymbol( |
| 103 | 144 | bin_file: *link.File, |
| 104 | 145 | src_loc: Module.SrcLoc, |
| ... | ... | @@ -118,9 +159,10 @@ pub fn generateSymbol( |
| 118 | 159 | const target = bin_file.options.target; |
| 119 | 160 | const endian = target.cpu.arch.endian(); |
| 120 | 161 | |
| 162 | const mod = bin_file.options.module.?; | |
| 121 | 163 | log.debug("generateSymbol: ty = {}, val = {}", .{ |
| 122 | typed_value.ty.fmtDebug(), | |
| 123 | typed_value.val.fmtDebug(), | |
| 164 | typed_value.ty.fmt(mod), | |
| 165 | typed_value.val.fmtValue(typed_value.ty, mod), | |
| 124 | 166 | }); |
| 125 | 167 | |
| 126 | 168 | if (typed_value.val.isUndefDeep()) { |
| ... | ... | @@ -170,7 +212,6 @@ pub fn generateSymbol( |
| 170 | 212 | }, |
| 171 | 213 | .str_lit => { |
| 172 | 214 | const str_lit = typed_value.val.castTag(.str_lit).?.data; |
| 173 | const mod = bin_file.options.module.?; | |
| 174 | 215 | const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; |
| 175 | 216 | try code.ensureUnusedCapacity(bytes.len + 1); |
| 176 | 217 | code.appendSliceAssumeCapacity(bytes); |
| ... | ... | @@ -300,7 +341,6 @@ pub fn generateSymbol( |
| 300 | 341 | switch (container_ptr.tag()) { |
| 301 | 342 | .decl_ref => { |
| 302 | 343 | const decl_index = container_ptr.castTag(.decl_ref).?.data; |
| 303 | const mod = bin_file.options.module.?; | |
| 304 | 344 | const decl = mod.declPtr(decl_index); |
| 305 | 345 | const addend = blk: { |
| 306 | 346 | switch (decl.ty.zigTypeTag()) { |
| ... | ... | @@ -493,7 +533,6 @@ pub fn generateSymbol( |
| 493 | 533 | const field_vals = typed_value.val.castTag(.aggregate).?.data; |
| 494 | 534 | const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow; |
| 495 | 535 | const current_pos = code.items.len; |
| 496 | const mod = bin_file.options.module.?; | |
| 497 | 536 | try code.resize(current_pos + abi_size); |
| 498 | 537 | var bits: u16 = 0; |
| 499 | 538 | |
| ... | ... | @@ -570,7 +609,6 @@ pub fn generateSymbol( |
| 570 | 609 | } |
| 571 | 610 | |
| 572 | 611 | const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data; |
| 573 | const mod = bin_file.options.module.?; | |
| 574 | 612 | const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?; |
| 575 | 613 | assert(union_ty.haveFieldTypes()); |
| 576 | 614 | const field_ty = union_ty.fields.values()[field_index].ty; |
| ... | ... | @@ -776,7 +814,6 @@ pub fn generateSymbol( |
| 776 | 814 | }, |
| 777 | 815 | .str_lit => { |
| 778 | 816 | const str_lit = typed_value.val.castTag(.str_lit).?.data; |
| 779 | const mod = bin_file.options.module.?; | |
| 780 | 817 | const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; |
| 781 | 818 | try code.ensureUnusedCapacity(str_lit.len); |
| 782 | 819 | code.appendSliceAssumeCapacity(bytes); |
src/link.zig+21| ... | ... | @@ -687,6 +687,7 @@ pub const File = struct { |
| 687 | 687 | FrameworkNotFound, |
| 688 | 688 | FunctionSignatureMismatch, |
| 689 | 689 | GlobalTypeMismatch, |
| 690 | HotSwapUnavailableOnHostOperatingSystem, | |
| 690 | 691 | InvalidCharacter, |
| 691 | 692 | InvalidEntryKind, |
| 692 | 693 | InvalidFeatureSet, |
| ... | ... | @@ -1104,6 +1105,26 @@ pub const File = struct { |
| 1104 | 1105 | missing_libc: bool = false, |
| 1105 | 1106 | }; |
| 1106 | 1107 | |
| 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 | 1128 | pub const C = @import("link/C.zig"); |
| 1108 | 1129 | pub const Coff = @import("link/Coff.zig"); |
| 1109 | 1130 | pub const Plan9 = @import("link/Plan9.zig"); |
src/link/Coff.zig+122| ... | ... | @@ -49,6 +49,9 @@ imports_count_dirty: bool = true, |
| 49 | 49 | /// Virtual address of the entry point procedure relative to image base. |
| 50 | 50 | entry_addr: ?u32 = null, |
| 51 | 51 | |
| 52 | /// Table of tracked LazySymbols. | |
| 53 | lazy_syms: LazySymbolTable = .{}, | |
| 54 | ||
| 52 | 55 | /// Table of tracked Decls. |
| 53 | 56 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 54 | 57 | |
| ... | ... | @@ -142,6 +145,18 @@ const Section = struct { |
| 142 | 145 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 143 | 146 | }; |
| 144 | 147 | |
| 148 | const LazySymbolTable = std.ArrayHashMapUnmanaged( | |
| 149 | link.File.LazySymbol, | |
| 150 | LazySymbolMetadata, | |
| 151 | link.File.LazySymbol.Context, | |
| 152 | true, | |
| 153 | ); | |
| 154 | ||
| 155 | const LazySymbolMetadata = struct { | |
| 156 | atom: Atom.Index, | |
| 157 | section: u16, | |
| 158 | }; | |
| 159 | ||
| 145 | 160 | const DeclMetadata = struct { |
| 146 | 161 | atom: Atom.Index, |
| 147 | 162 | section: u16, |
| ... | ... | @@ -1168,6 +1183,100 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1168 | 1183 | return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 1169 | 1184 | } |
| 1170 | 1185 | |
| 1186 | fn 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 | ||
| 1258 | pub 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 | ||
| 1171 | 1280 | pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index { |
| 1172 | 1281 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 1173 | 1282 | if (!gop.found_existing) { |
| ... | ... | @@ -1498,6 +1607,19 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1498 | 1607 | sub_prog_node.activate(); |
| 1499 | 1608 | defer sub_prog_node.end(); |
| 1500 | 1609 | |
| 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 | 1623 | const gpa = self.base.allocator; |
| 1502 | 1624 | |
| 1503 | 1625 | while (self.unresolved.popOrNull()) |entry| { |
src/link/Elf.zig+114| ... | ... | @@ -63,6 +63,12 @@ const Section = struct { |
| 63 | 63 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 64 | 64 | }; |
| 65 | 65 | |
| 66 | const LazySymbolMetadata = struct { | |
| 67 | atom: Atom.Index, | |
| 68 | shdr: u16, | |
| 69 | alignment: u32, | |
| 70 | }; | |
| 71 | ||
| 66 | 72 | const DeclMetadata = struct { |
| 67 | 73 | atom: Atom.Index, |
| 68 | 74 | shdr: u16, |
| ... | ... | @@ -157,6 +163,9 @@ debug_line_header_dirty: bool = false, |
| 157 | 163 | |
| 158 | 164 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 159 | 165 | |
| 166 | /// Table of tracked LazySymbols. | |
| 167 | lazy_syms: LazySymbolTable = .{}, | |
| 168 | ||
| 160 | 169 | /// Table of tracked Decls. |
| 161 | 170 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 162 | 171 | |
| ... | ... | @@ -194,6 +203,7 @@ relocs: RelocTable = .{}, |
| 194 | 203 | |
| 195 | 204 | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc)); |
| 196 | 205 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 206 | const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true); | |
| 197 | 207 | |
| 198 | 208 | /// When allocating, the ideal_capacity is calculated by |
| 199 | 209 | /// actual_capacity + (actual_capacity / ideal_factor) |
| ... | ... | @@ -1011,6 +1021,19 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1011 | 1021 | sub_prog_node.activate(); |
| 1012 | 1022 | defer sub_prog_node.end(); |
| 1013 | 1023 | |
| 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 | 1037 | // TODO This linker code currently assumes there is only 1 compilation unit and it |
| 1015 | 1038 | // corresponds to the Zig source code. |
| 1016 | 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 | 2367 | } |
| 2345 | 2368 | } |
| 2346 | 2369 | |
| 2370 | pub 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 | ||
| 2347 | 2388 | pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index { |
| 2348 | 2389 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 2349 | 2390 | if (!gop.found_existing) { |
| ... | ... | @@ -2610,6 +2651,79 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v |
| 2610 | 2651 | return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 2611 | 2652 | } |
| 2612 | 2653 | |
| 2654 | fn 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 | ||
| 2613 | 2727 | pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 { |
| 2614 | 2728 | const gpa = self.base.allocator; |
| 2615 | 2729 |
src/link/MachO.zig+126-4| ... | ... | @@ -218,6 +218,9 @@ bindings: BindingTable = .{}, |
| 218 | 218 | /// this will be a table indexed by index into the list of Atoms. |
| 219 | 219 | lazy_bindings: BindingTable = .{}, |
| 220 | 220 | |
| 221 | /// Table of tracked LazySymbols. | |
| 222 | lazy_syms: LazySymbolTable = .{}, | |
| 223 | ||
| 221 | 224 | /// Table of tracked Decls. |
| 222 | 225 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 223 | 226 | |
| ... | ... | @@ -229,6 +232,18 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) { |
| 229 | 232 | else => false, |
| 230 | 233 | }; |
| 231 | 234 | |
| 235 | const LazySymbolTable = std.ArrayHashMapUnmanaged( | |
| 236 | link.File.LazySymbol, | |
| 237 | LazySymbolMetadata, | |
| 238 | link.File.LazySymbol.Context, | |
| 239 | true, | |
| 240 | ); | |
| 241 | ||
| 242 | const LazySymbolMetadata = struct { | |
| 243 | atom: Atom.Index, | |
| 244 | section: u8, | |
| 245 | }; | |
| 246 | ||
| 232 | 247 | const DeclMetadata = struct { |
| 233 | 248 | atom: Atom.Index, |
| 234 | 249 | section: u8, |
| ... | ... | @@ -497,6 +512,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 497 | 512 | sub_prog_node.activate(); |
| 498 | 513 | defer sub_prog_node.end(); |
| 499 | 514 | |
| 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 | 528 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 501 | 529 | |
| 502 | 530 | if (self.d_sym) |*d_sym| { |
| ... | ... | @@ -2163,13 +2191,13 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2163 | 2191 | |
| 2164 | 2192 | const name_str_index = blk: { |
| 2165 | 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 | 2195 | defer gpa.free(name); |
| 2168 | 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).?; | |
| 2171 | 2199 | |
| 2172 | log.debug("allocating symbol indexes for {?s}", .{name}); | |
| 2200 | log.debug("allocating symbol indexes for {s}", .{name}); | |
| 2173 | 2201 | |
| 2174 | 2202 | const atom_index = try self.createAtom(); |
| 2175 | 2203 | |
| ... | ... | @@ -2202,7 +2230,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2202 | 2230 | |
| 2203 | 2231 | try unnamed_consts.append(gpa, atom_index); |
| 2204 | 2232 | |
| 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 | 2234 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2207 | 2235 | |
| 2208 | 2236 | try self.writeAtom(atom_index, code); |
| ... | ... | @@ -2282,6 +2310,100 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) |
| 2282 | 2310 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 2283 | 2311 | } |
| 2284 | 2312 | |
| 2313 | fn 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 | ||
| 2385 | pub 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 | ||
| 2285 | 2407 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { |
| 2286 | 2408 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 2287 | 2409 | if (!gop.found_existing) { |
test/behavior/bugs/6047.zig-1| ... | ... | @@ -11,7 +11,6 @@ fn getError2() !void { |
| 11 | 11 | |
| 12 | 12 | test "`try`ing an if/else expression" { |
| 13 | 13 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 15 | 14 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO |
| 16 | 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 17 | 16 | 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 | 110 | } |
| 111 | 111 | |
| 112 | 112 | test "errdefer with payload" { |
| 113 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 114 | 113 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 115 | 114 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 116 | 115 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/error.zig-2| ... | ... | @@ -575,7 +575,6 @@ fn gimmeItBroke() anyerror { |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | 577 | test "@errorName sentinel length matches slice length" { |
| 578 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 579 | 578 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 580 | 579 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 581 | 580 | 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 | 850 | test "error from comptime string" { |
| 852 | 851 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 853 | 852 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 854 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 855 | 853 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 856 | 854 | |
| 857 | 855 | const name = "Weird error name!"; |
test/behavior/optional.zig-1| ... | ... | @@ -468,7 +468,6 @@ test "peer type resolution in nested if expressions" { |
| 468 | 468 | test "cast slice to const slice nested in error union and optional" { |
| 469 | 469 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 470 | 470 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 471 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 472 | 471 | |
| 473 | 472 | const S = struct { |
| 474 | 473 | fn inner() !?[]u8 { |
test/behavior/switch.zig-1| ... | ... | @@ -419,7 +419,6 @@ test "switch on integer with else capturing expr" { |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | test "else prong of switch on error set excludes other cases" { |
| 422 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 423 | 422 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 424 | 423 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 425 | 424 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |