| author | |
| committer | |
| log | e0f5627d4a9cb1b3a1361d70d40043c8c170b2af |
| tree | c46515f91973faaf597ab9758743bd2190652a2e |
| parent | 4b14384989362f93cd014628810c63b5cd9d3fff |
Unless the pointer is a pointer to a function, if the pointee type
has zero-bits, we need to return `MCValue.none` as the `Decl` has
not been lowered to memory, and therefore, any GOT reference will be
wrong.6 files changed, 27 insertions(+), 4 deletions(-)
src/arch/aarch64/CodeGen.zig+10| ... | ... | @@ -3550,6 +3550,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 3550 | 3550 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { |
| 3551 | 3551 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 3552 | 3552 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 3553 | ||
| 3554 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? | |
| 3555 | if (tv.ty.zigTypeTag() == .Pointer) blk: { | |
| 3556 | if (tv.ty.castPtrToFn()) |_| break :blk; | |
| 3557 | if (!tv.ty.elemType2().hasRuntimeBits()) { | |
| 3558 | return MCValue.none; | |
| 3559 | } | |
| 3560 | } | |
| 3561 | ||
| 3553 | 3562 | decl.alive = true; |
| 3554 | 3563 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 3555 | 3564 | const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?]; |
| ... | ... | @@ -3558,6 +3567,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 3558 | 3567 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 3559 | 3568 | // Because MachO is PIE-always-on, we defer memory address resolution until |
| 3560 | 3569 | // the linker has enough info to perform relocations. |
| 3570 | assert(decl.link.macho.local_sym_index != 0); | |
| 3561 | 3571 | return MCValue{ .got_load = decl.link.macho.local_sym_index }; |
| 3562 | 3572 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 3563 | 3573 | const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes; |
src/arch/x86_64/CodeGen.zig+9| ... | ... | @@ -5333,6 +5333,14 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 5333 | 5333 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 5334 | 5334 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 5335 | 5335 | |
| 5336 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? | |
| 5337 | if (tv.ty.zigTypeTag() == .Pointer) blk: { | |
| 5338 | if (tv.ty.castPtrToFn()) |_| break :blk; | |
| 5339 | if (!tv.ty.elemType2().hasRuntimeBits()) { | |
| 5340 | return MCValue.none; | |
| 5341 | } | |
| 5342 | } | |
| 5343 | ||
| 5336 | 5344 | decl.alive = true; |
| 5337 | 5345 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 5338 | 5346 | const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?]; |
| ... | ... | @@ -5341,6 +5349,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 5341 | 5349 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 5342 | 5350 | // Because MachO is PIE-always-on, we defer memory address resolution until |
| 5343 | 5351 | // the linker has enough info to perform relocations. |
| 5352 | assert(decl.link.macho.local_sym_index != 0); | |
| 5344 | 5353 | return MCValue{ .got_load = decl.link.macho.local_sym_index }; |
| 5345 | 5354 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 5346 | 5355 | const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes; |
src/arch/x86_64/Emit.zig+1| ... | ... | @@ -857,6 +857,7 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 857 | 857 | else => return emit.fail("TODO unused LEA PIE variants 0b10 and 0b11", .{}), |
| 858 | 858 | }; |
| 859 | 859 | const atom = macho_file.atom_by_index_table.get(load_reloc.atom_index).?; |
| 860 | log.debug("adding reloc of type {} to local @{d}", .{ reloc_type, load_reloc.sym_index }); | |
| 860 | 861 | try atom.relocs.append(emit.bin_file.allocator, .{ |
| 861 | 862 | .offset = @intCast(u32, end_offset - 4), |
| 862 | 863 | .target = .{ .local = load_reloc.sym_index }, |
src/link/MachO.zig+7| ... | ... | @@ -4286,6 +4286,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 4286 | 4286 | } |
| 4287 | 4287 | |
| 4288 | 4288 | fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void { |
| 4289 | log.debug("freeUnnamedConsts for decl {*}", .{decl}); | |
| 4289 | 4290 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl) orelse return; |
| 4290 | 4291 | for (unnamed_consts.items) |atom| { |
| 4291 | 4292 | self.freeAtom(atom, .{ |
| ... | ... | @@ -4295,6 +4296,7 @@ fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void { |
| 4295 | 4296 | self.locals_free_list.append(self.base.allocator, atom.local_sym_index) catch {}; |
| 4296 | 4297 | self.locals.items[atom.local_sym_index].n_type = 0; |
| 4297 | 4298 | _ = self.atom_by_index_table.remove(atom.local_sym_index); |
| 4299 | log.debug(" adding local symbol index {d} to free list", .{atom.local_sym_index}); | |
| 4298 | 4300 | atom.local_sym_index = 0; |
| 4299 | 4301 | } |
| 4300 | 4302 | unnamed_consts.clearAndFree(self.base.allocator); |
| ... | ... | @@ -4319,10 +4321,15 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 4319 | 4321 | self.got_entries_free_list.append(self.base.allocator, @intCast(u32, got_index)) catch {}; |
| 4320 | 4322 | self.got_entries.items[got_index] = .{ .target = .{ .local = 0 }, .atom = undefined }; |
| 4321 | 4323 | _ = self.got_entries_table.swapRemove(.{ .local = decl.link.macho.local_sym_index }); |
| 4324 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ | |
| 4325 | got_index, | |
| 4326 | decl.link.macho.local_sym_index, | |
| 4327 | }); | |
| 4322 | 4328 | } |
| 4323 | 4329 | |
| 4324 | 4330 | self.locals.items[decl.link.macho.local_sym_index].n_type = 0; |
| 4325 | 4331 | _ = self.atom_by_index_table.remove(decl.link.macho.local_sym_index); |
| 4332 | log.debug(" adding local symbol index {d} to free list", .{decl.link.macho.local_sym_index}); | |
| 4326 | 4333 | decl.link.macho.local_sym_index = 0; |
| 4327 | 4334 | } |
| 4328 | 4335 | if (self.d_sym) |*d_sym| { |
test/behavior/basic.zig-2| ... | ... | @@ -399,8 +399,6 @@ fn testTakeAddressOfParameter(f: f32) !void { |
| 399 | 399 | |
| 400 | 400 | test "pointer to void return type" { |
| 401 | 401 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 402 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | |
| 403 | if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .macos) return error.SkipZigTest; | |
| 404 | 402 | |
| 405 | 403 | try testPointerToVoidReturnType(); |
| 406 | 404 | } |
test/behavior/struct.zig-2| ... | ... | @@ -370,8 +370,6 @@ test "empty struct method call" { |
| 370 | 370 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 371 | 371 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 372 | 372 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 373 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO | |
| 374 | if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO | |
| 375 | 373 | |
| 376 | 374 | const es = EmptyStruct{}; |
| 377 | 375 | try expect(es.method() == 1234); |