mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
Merge pull request #11026 from ziglang/codegen-field-ptr
codegen: lower field_ptr to memory across linking backends
This commit is contained in:
commit
7cfc3f0cfa
@ -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,
|
||||
|
||||
135
src/codegen.zig
135
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,58 @@ 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,
|
||||
});
|
||||
},
|
||||
.field_ptr => {
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = typed_value.ty,
|
||||
.val = container_ptr,
|
||||
}, code, debug_output, reloc_info)) {
|
||||
.appended => {},
|
||||
.externally_managed => |external_slice| {
|
||||
code.appendSliceAssumeCapacity(external_slice);
|
||||
},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
return Result{ .appended = {} };
|
||||
},
|
||||
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 +493,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 +524,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 +538,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 +557,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 +575,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 +607,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 +620,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 +670,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 +704,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 +727,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),
|
||||
|
||||
16
src/link.zig
16
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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -780,7 +780,6 @@ test "packed struct with u0 field access" {
|
||||
|
||||
test "access to global struct fields" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user