From e8eb9778cccd2f2d23027d9e0d73d7053bf92efe Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 1 Mar 2022 22:03:18 +0100 Subject: codegen: lower field_ptr to memory across linking backends This requires generating an addend for the target relocation as the field pointer might point at a field inner to the container. --- src/arch/x86_64/CodeGen.zig | 3 +- src/codegen.zig | 122 ++++++++++++++++++++++++++++++-------------- src/link.zig | 16 ++++-- src/link/Coff.zig | 11 ++-- src/link/Elf.zig | 18 ++++--- src/link/MachO.zig | 25 +++++---- src/link/Plan9.zig | 11 ++-- test/behavior/bugs/3046.zig | 1 - 8 files changed, 138 insertions(+), 69 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index c1d1c6863e..c511a26eac 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2565,7 +2565,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type const payload = try self.addExtra(Mir.ImmPair{ .dest_off = 0, - .operand = @intCast(u32, imm), + // TODO check if this logic is correct + .operand = @truncate(u32, imm), }); const flags: u2 = switch (abi_size) { 1 => 0b00, diff --git a/src/codegen.zig b/src/codegen.zig index db3684155e..fbc8bd9b3a 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -142,11 +142,11 @@ pub fn generateFunction( pub fn generateSymbol( bin_file: *link.File, - parent_atom_index: u32, src_loc: Module.SrcLoc, typed_value: TypedValue, code: *std.ArrayList(u8), debug_output: DebugInfoOutput, + reloc_info: RelocInfo, ) GenerateSymbolError!Result { const tracy = trace(@src()); defer tracy.end(); @@ -178,10 +178,10 @@ pub fn generateSymbol( if (typed_value.ty.sentinel()) |sentinel| { try code.ensureUnusedCapacity(payload.data.len + 1); code.appendSliceAssumeCapacity(payload.data); - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = typed_value.ty.elemType(), .val = sentinel, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => return Result{ .appended = {} }, .externally_managed => |slice| { code.appendSliceAssumeCapacity(slice); @@ -198,10 +198,10 @@ pub fn generateSymbol( const elem_vals = typed_value.val.castTag(.array).?.data; const elem_ty = typed_value.ty.elemType(); for (elem_vals) |elem_val| { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, .val = elem_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |slice| { code.appendSliceAssumeCapacity(slice); @@ -219,10 +219,10 @@ pub fn generateSymbol( var index: u64 = 0; while (index < len) : (index += 1) { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, .val = array, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |slice| { code.appendSliceAssumeCapacity(slice); @@ -232,10 +232,10 @@ pub fn generateSymbol( } if (sentinel) |sentinel_val| { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, .val = sentinel_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |slice| { code.appendSliceAssumeCapacity(slice); @@ -249,10 +249,10 @@ pub fn generateSymbol( .empty_array_sentinel => { const elem_ty = typed_value.ty.childType(); const sentinel_val = typed_value.ty.sentinel().?; - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, .val = sentinel_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |slice| { code.appendSliceAssumeCapacity(slice); @@ -273,11 +273,11 @@ pub fn generateSymbol( .Pointer => switch (typed_value.val.tag()) { .variable => { const decl = typed_value.val.castTag(.variable).?.data.owner_decl; - return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output); + return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, reloc_info); }, .decl_ref => { const decl = typed_value.val.castTag(.decl_ref).?.data; - return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output); + return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, reloc_info); }, .slice => { const slice = typed_value.val.castTag(.slice).?.data; @@ -285,10 +285,10 @@ pub fn generateSymbol( // generate ptr var buf: Type.SlicePtrFieldTypeBuffer = undefined; const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf); - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = slice_ptr_field_type, .val = slice.ptr, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -297,10 +297,10 @@ pub fn generateSymbol( } // generate length - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = Type.initTag(.usize), .val = slice.len, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -310,6 +310,45 @@ pub fn generateSymbol( return Result{ .appended = {} }; }, + .field_ptr => { + const target = bin_file.options.target; + const field_ptr = typed_value.val.castTag(.field_ptr).?.data; + const container_ptr = field_ptr.container_ptr; + + switch (container_ptr.tag()) { + .decl_ref => { + const decl = container_ptr.castTag(.decl_ref).?.data; + const addend = blk: { + switch (decl.ty.tag()) { + .@"struct" => { + const addend = decl.ty.structFieldOffset(field_ptr.field_index, target); + break :blk @intCast(u32, addend); + }, + else => return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for pointer type value: '{s}'", + .{@tagName(typed_value.val.tag())}, + ), + }, + } + }; + return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{ + .parent_atom_index = reloc_info.parent_atom_index, + .addend = (reloc_info.addend orelse 0) + addend, + }); + }, + else => return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for pointer type value: '{s}'", + .{@tagName(typed_value.val.tag())}, + ), + }, + } + }, else => return Result{ .fail = try ErrorMsg.create( bin_file.allocator, @@ -441,10 +480,10 @@ pub fn generateSymbol( const field_ty = typed_value.ty.structFieldType(index); if (!field_ty.hasRuntimeBits()) continue; - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = field_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -472,10 +511,10 @@ pub fn generateSymbol( const layout = typed_value.ty.unionGetLayout(target); if (layout.payload_size == 0) { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = typed_value.ty.unionTagType().?, .val = union_obj.tag, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -486,10 +525,10 @@ pub fn generateSymbol( // Check if we should store the tag first. if (layout.tag_align >= layout.payload_align) { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = typed_value.ty.unionTagType().?, .val = union_obj.tag, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -505,10 +544,10 @@ pub fn generateSymbol( if (!field_ty.hasRuntimeBits()) { try code.writer().writeByteNTimes(0xaa, try math.cast(usize, layout.payload_size)); } else { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = union_obj.val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -523,10 +562,10 @@ pub fn generateSymbol( } if (layout.tag_size > 0) { - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = union_ty.tag_ty, .val = union_obj.tag, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -555,10 +594,10 @@ pub fn generateSymbol( const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero); const begin = code.items.len; - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = error_ty, .val = error_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -568,10 +607,10 @@ pub fn generateSymbol( if (payload_ty.hasRuntimeBits()) { const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef); - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = payload_ty, .val = payload_val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -618,23 +657,28 @@ pub fn generateSymbol( } } +const RelocInfo = struct { + parent_atom_index: u32, + addend: ?u32 = null, +}; + fn lowerDeclRef( bin_file: *link.File, - parent_atom_index: u32, src_loc: Module.SrcLoc, typed_value: TypedValue, decl: *Module.Decl, code: *std.ArrayList(u8), debug_output: DebugInfoOutput, + reloc_info: RelocInfo, ) GenerateSymbolError!Result { if (typed_value.ty.isSlice()) { // generate ptr var buf: Type.SlicePtrFieldTypeBuffer = undefined; const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf); - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = slice_ptr_field_type, .val = typed_value.val, - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -647,10 +691,10 @@ fn lowerDeclRef( .base = .{ .tag = .int_u64 }, .data = typed_value.val.sliceLen(), }; - switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ + switch (try generateSymbol(bin_file, src_loc, .{ .ty = Type.usize, .val = Value.initPayload(&slice_len.base), - }, code, debug_output)) { + }, code, debug_output, reloc_info)) { .appended => {}, .externally_managed => |external_slice| { code.appendSliceAssumeCapacity(external_slice); @@ -670,7 +714,11 @@ fn lowerDeclRef( } decl.markAlive(); - const vaddr = try bin_file.getDeclVAddr(decl, parent_atom_index, code.items.len); + const vaddr = try bin_file.getDeclVAddr(decl, .{ + .parent_atom_index = reloc_info.parent_atom_index, + .offset = code.items.len, + .addend = reloc_info.addend orelse 0, + }); const endian = target.cpu.arch.endian(); switch (ptr_width) { 16 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(u16, vaddr), endian), diff --git a/src/link.zig b/src/link.zig index 46314327d9..996622443a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -685,16 +685,22 @@ pub const File = struct { } } + pub const RelocInfo = struct { + parent_atom_index: u32, + offset: u64, + addend: u32, + }; + /// Get allocated `Decl`'s address in virtual memory. /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory. - pub fn getDeclVAddr(base: *File, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { + pub fn getDeclVAddr(base: *File, decl: *const Module.Decl, reloc_info: RelocInfo) !u64 { switch (base.tag) { - .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl, parent_atom_index, offset), - .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl, parent_atom_index, offset), - .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, parent_atom_index, offset), - .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, parent_atom_index, offset), + .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl, reloc_info), + .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl, reloc_info), + .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, reloc_info), + .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, reloc_info), .c => unreachable, .wasm => unreachable, .spirv => unreachable, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 3ee34682e9..3293cf2dfc 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -724,10 +724,12 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { var code_buffer = std.ArrayList(u8).init(self.base.allocator); defer code_buffer.deinit(); - const res = try codegen.generateSymbol(&self.base, 0, decl.srcLoc(), .{ + const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, .val = decl.val, - }, &code_buffer, .none); + }, &code_buffer, .none, .{ + .parent_atom_index = 0, + }); const code = switch (res) { .externally_managed => |x| x, .appended => code_buffer.items, @@ -1463,9 +1465,8 @@ fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 { return null; } -pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { - _ = parent_atom_index; - _ = offset; +pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { + _ = reloc_info; assert(self.llvm_object == null); return self.text_section_virtual_address + decl.link.coff.text_offset; } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 2b063dd1d2..1424a521b9 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -188,6 +188,7 @@ relocs: RelocTable = .{}, const Reloc = struct { target: u32, offset: u64, + addend: u32, prev_vaddr: u64, }; @@ -421,20 +422,21 @@ pub fn deinit(self: *Elf) void { self.atom_by_index_table.deinit(self.base.allocator); } -pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { +pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { assert(self.llvm_object == null); assert(decl.link.elf.local_sym_index != 0); const target = decl.link.elf.local_sym_index; const vaddr = self.local_symbols.items[target].st_value; - const atom = self.atom_by_index_table.get(parent_atom_index).?; + const atom = self.atom_by_index_table.get(reloc_info.parent_atom_index).?; const gop = try self.relocs.getOrPut(self.base.allocator, atom); if (!gop.found_existing) { gop.value_ptr.* = .{}; } try gop.value_ptr.append(self.base.allocator, .{ .target = target, - .offset = offset, + .offset = reloc_info.offset, + .addend = reloc_info.addend, .prev_vaddr = vaddr, }); @@ -1039,7 +1041,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { for (relocs.items) |*reloc| { const target_sym = self.local_symbols.items[reloc.target]; - const target_vaddr = target_sym.st_value; + const target_vaddr = target_sym.st_value + reloc.addend; if (target_vaddr == reloc.prev_vaddr) continue; @@ -3074,7 +3076,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { // TODO implement .debug_info for global variables const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; - const res = try codegen.generateSymbol(&self.base, decl.link.elf.local_sym_index, decl.srcLoc(), .{ + const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, .val = decl_val, }, &code_buffer, .{ @@ -3083,6 +3085,8 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { .dbg_info = &dbg_info_buffer, .dbg_info_type_relocs = &dbg_info_type_relocs, }, + }, .{ + .parent_atom_index = decl.link.elf.local_sym_index, }); const code = switch (res) { .externally_managed => |x| x, @@ -3130,8 +3134,10 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl atom.local_sym_index = try self.allocateLocalSymbol(); try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom); - const res = try codegen.generateSymbol(&self.base, atom.local_sym_index, decl.srcLoc(), typed_value, &code_buffer, .{ + const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{ .none = .{}, + }, .{ + .parent_atom_index = atom.local_sym_index, }); const code = switch (res) { .externally_managed => |x| x, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 9f038d9b9f..2f55c69b3a 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3781,8 +3781,10 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), math.log2(required_alignment)); try self.atom_by_index_table.putNoClobber(self.base.allocator, local_sym_index, atom); - const res = try codegen.generateSymbol(&self.base, local_sym_index, decl.srcLoc(), typed_value, &code_buffer, .{ + const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{ .none = .{}, + }, .{ + .parent_atom_index = local_sym_index, }); const code = switch (res) { .externally_managed => |x| x, @@ -3790,6 +3792,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De .fail => |em| { decl.analysis = .codegen_failure; try module.failed_decls.put(module.gpa, decl, em); + log.err("{s}", .{em.msg}); return error.AnalysisFail; }, }; @@ -3860,7 +3863,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; const res = if (debug_buffers) |dbg| - try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{ + try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, .val = decl_val, }, &code_buffer, .{ @@ -3869,12 +3872,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { .dbg_info = &dbg.dbg_info_buffer, .dbg_info_type_relocs = &dbg.dbg_info_type_relocs, }, + }, .{ + .parent_atom_index = decl.link.macho.local_sym_index, }) else - try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{ + try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, .val = decl_val, - }, &code_buffer, .none); + }, &code_buffer, .none, .{ + .parent_atom_index = decl.link.macho.local_sym_index, + }); const code = blk: { switch (res) { @@ -4357,15 +4364,15 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { } } -pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { +pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { assert(self.llvm_object == null); assert(decl.link.macho.local_sym_index != 0); - const atom = self.atom_by_index_table.get(parent_atom_index).?; + const atom = self.atom_by_index_table.get(reloc_info.parent_atom_index).?; try atom.relocs.append(self.base.allocator, .{ - .offset = @intCast(u32, offset), + .offset = @intCast(u32, reloc_info.offset), .target = .{ .local = decl.link.macho.local_sym_index }, - .addend = 0, + .addend = reloc_info.addend, .subtractor = null, .pcrel = false, .length = 3, @@ -4375,7 +4382,7 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u else => unreachable, }, }); - try atom.rebases.append(self.base.allocator, offset); + try atom.rebases.append(self.base.allocator, reloc_info.offset); return 0; } diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 4648a6a673..8096b2d38c 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -304,10 +304,12 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void { const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; // TODO we need the symbol index for symbol in the table of locals for the containing atom const sym_index = decl.link.plan9.sym_index orelse 0; - const res = try codegen.generateSymbol(&self.base, @intCast(u32, sym_index), decl.srcLoc(), .{ + const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, .val = decl_val, - }, &code_buffer, .{ .none = .{} }); + }, &code_buffer, .{ .none = .{} }, .{ + .parent_atom_index = @intCast(u32, sym_index), + }); const code = switch (res) { .externally_managed => |x| x, .appended => code_buffer.items, @@ -752,9 +754,8 @@ pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void { _ = self; _ = decl; } -pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { - _ = parent_atom_index; - _ = offset; +pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { + _ = reloc_info; if (decl.ty.zigTypeTag() == .Fn) { var start = self.bases.text; var it_file = self.fn_decl_table.iterator(); diff --git a/test/behavior/bugs/3046.zig b/test/behavior/bugs/3046.zig index dc18256d33..1122ab4fe9 100644 --- a/test/behavior/bugs/3046.zig +++ b/test/behavior/bugs/3046.zig @@ -13,7 +13,6 @@ fn couldFail() anyerror!i32 { var some_struct: SomeStruct = undefined; test "fixed" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; -- cgit v1.2.3