aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2024-09-10 17:31:06 -0400
committerGitHub <noreply@github.com>2024-09-10 17:31:06 -0400
commit8ec68c63fa1d0f7e267ff92c054e8aa335f91da4 (patch)
treee2fbdd384dbc2509c4a3b633b41e651a6e01b157 /src/link
parent90075345519f165a0164c52b62b78453068c6ce6 (diff)
parent6aa6d088d93174767d3a8387d536f4083c39e14f (diff)
downloadzig-8ec68c63fa1d0f7e267ff92c054e8aa335f91da4.tar.gz
zig-8ec68c63fa1d0f7e267ff92c054e8aa335f91da4.zip
Merge pull request #21323 from jacobly0/dwarf-decls
Dwarf: implement more decls
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Coff.zig19
-rw-r--r--src/link/Dwarf.zig1014
-rw-r--r--src/link/Elf/ZigObject.zig63
-rw-r--r--src/link/MachO/ZigObject.zig96
-rw-r--r--src/link/Plan9.zig35
-rw-r--r--src/link/Wasm/ZigObject.zig20
6 files changed, 683 insertions, 564 deletions
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index 6bf47e2602..f67c7d54d7 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -1163,8 +1163,8 @@ fn lowerConst(
try self.setSymbolName(sym, name);
sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1));
- const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .none, .{
- .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
+ const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{
+ .atom_index = self.getAtom(atom_index).getSymbolIndex().?,
});
const code = switch (res) {
.ok => code_buffer.items,
@@ -1235,8 +1235,7 @@ pub fn updateNav(
zcu.navSrcLoc(nav_index),
nav_init,
&code_buffer,
- .none,
- .{ .parent_atom_index = atom.getSymbolIndex().? },
+ .{ .atom_index = atom.getSymbolIndex().? },
);
const code = switch (res) {
.ok => code_buffer.items,
@@ -1284,7 +1283,7 @@ fn updateLazySymbolAtom(
&required_alignment,
&code_buffer,
.none,
- .{ .parent_atom_index = local_sym_index },
+ .{ .atom_index = local_sym_index },
);
const code = switch (res) {
.ok => code_buffer.items,
@@ -1823,7 +1822,10 @@ pub fn getNavVAddr(
.@"extern" => |@"extern"| try self.getGlobalSymbol(nav.name.toSlice(ip), @"extern".lib_name.toSlice(ip)),
else => self.getAtom(try self.getOrCreateAtomForNav(nav_index)).getSymbolIndex().?,
};
- const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
+ const atom_index = self.getAtomIndexForSymbol(.{
+ .sym_index = reloc_info.parent.atom_index,
+ .file = null,
+ }).?;
const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
try Atom.addRelocation(self, atom_index, .{
.type = .direct,
@@ -1901,7 +1903,10 @@ pub fn getUavVAddr(
const this_atom_index = self.uavs.get(uav).?.atom;
const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?;
- const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
+ const atom_index = self.getAtomIndexForSymbol(.{
+ .sym_index = reloc_info.parent.atom_index,
+ .file = null,
+ }).?;
const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
try Atom.addRelocation(self, atom_index, .{
.type = .direct,
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index bff33ecf14..9ec0fa3012 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -19,8 +19,8 @@ debug_rnglists: DebugRngLists,
debug_str: StringSection,
pub const UpdateError = error{
+ CodegenFail,
ReinterpretDeclRef,
- IllDefinedMemoryLayout,
Unimplemented,
OutOfMemory,
EndOfStream,
@@ -847,10 +847,11 @@ const Entry = struct {
unit.len -| (unit.header_len + unit.trailer_len);
if (entry_ptr.off + len > end) {
if (entry_ptr.next.unwrap()) |next_entry| {
- if (entry_ptr.prev.unwrap()) |prev_entry|
- unit.getEntry(prev_entry).next = entry_ptr.next
- else
- unit.first = entry_ptr.next;
+ if (entry_ptr.prev.unwrap()) |prev_entry| {
+ const prev_entry_ptr = unit.getEntry(prev_entry);
+ prev_entry_ptr.next = entry_ptr.next;
+ try prev_entry_ptr.pad(unit, sec, dwarf);
+ } else unit.first = entry_ptr.next;
const next_entry_ptr = unit.getEntry(next_entry);
const entry = next_entry_ptr.prev;
next_entry_ptr.prev = entry_ptr.prev;
@@ -860,6 +861,7 @@ const Entry = struct {
entry_ptr.next = .none;
entry_ptr.off = last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
unit.last = entry;
+ try last_entry_ptr.pad(unit, sec, dwarf);
}
try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(len) + unit.trailer_len));
}
@@ -1582,6 +1584,18 @@ pub const WipNav = struct {
wip_nav.func = func;
}
+ fn externalReloc(wip_nav: *WipNav, sec: *Section, reloc: ExternalReloc) std.mem.Allocator.Error!void {
+ try sec.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(wip_nav.dwarf.gpa, reloc);
+ }
+
+ pub fn infoExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void {
+ try wip_nav.externalReloc(&wip_nav.dwarf.debug_info.section, reloc);
+ }
+
+ fn frameExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void {
+ try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc);
+ }
+
fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) UpdateError!void {
try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), try wip_nav.dwarf.refAbbrevCode(abbrev_code));
}
@@ -1658,12 +1672,11 @@ pub const WipNav = struct {
}
fn infoAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void {
- const dwarf = wip_nav.dwarf;
- try dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
+ try wip_nav.infoExternalReloc(.{
.source_off = @intCast(wip_nav.debug_info.items.len),
.target_sym = sym_index,
});
- try wip_nav.debug_info.appendNTimes(dwarf.gpa, 0, @intFromEnum(dwarf.address_size));
+ try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
}
fn frameExprloc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
@@ -1690,12 +1703,11 @@ pub const WipNav = struct {
}
fn frameAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void {
- const dwarf = wip_nav.dwarf;
- try dwarf.debug_frame.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
+ try wip_nav.frameExternalReloc(.{
.source_off = @intCast(wip_nav.debug_frame.items.len),
.target_sym = sym_index,
});
- try wip_nav.debug_frame.appendNTimes(dwarf.gpa, 0, @intFromEnum(dwarf.address_size));
+ try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
}
fn getTypeEntry(wip_nav: *WipNav, ty: Type) UpdateError!struct { Unit.Index, Entry.Index } {
@@ -1747,6 +1759,27 @@ pub const WipNav = struct {
reloc.target_off = @intCast(wip_nav.debug_info.items.len);
}
+ fn blockValue(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc, val: Value) UpdateError!void {
+ const ty = val.typeOf(wip_nav.pt.zcu);
+ const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
+ const bytes = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0;
+ try uleb128(diw, bytes);
+ if (bytes == 0) return;
+ var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);
+ defer wip_nav.debug_info = dim.moveToUnmanaged();
+ switch (try codegen.generateSymbol(
+ wip_nav.dwarf.bin_file,
+ wip_nav.pt,
+ src_loc,
+ val,
+ &dim,
+ .{ .debug_output = .{ .dwarf = wip_nav } },
+ )) {
+ .ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes),
+ .fail => unreachable,
+ }
+ }
+
fn enumConstValue(
wip_nav: *WipNav,
loaded_enum: InternPool.LoadedEnumType,
@@ -1812,8 +1845,8 @@ pub const WipNav = struct {
}
}
- fn flush(wip_nav: *WipNav) UpdateError!void {
- while (wip_nav.pending_types.popOrNull()) |ty| try wip_nav.dwarf.updateType(wip_nav.pt, ty, &wip_nav.pending_types);
+ fn flush(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {
+ while (wip_nav.pending_types.popOrNull()) |ty| try wip_nav.dwarf.updateType(wip_nav.pt, src_loc, ty, &wip_nav.pending_types);
}
};
@@ -2169,15 +2202,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
try diw.writeByte(accessibility);
try wip_nav.strp(nav.name.toSlice(ip));
try wip_nav.strp(nav.fqn.toSlice(ip));
- const ty = nav_val.typeOf(zcu);
- const ty_reloc_index = try wip_nav.refForward();
+ const nav_ty = nav_val.typeOf(zcu);
+ const nav_ty_reloc_index = try wip_nav.refForward();
try wip_nav.exprloc(.{ .addr = .{ .sym = sym_index } });
try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
- ty.abiAlignment(zcu).toByteUnits().?);
+ nav_ty.abiAlignment(zcu).toByteUnits().?);
try diw.writeByte(@intFromBool(false));
- wip_nav.finishForward(ty_reloc_index);
+ wip_nav.finishForward(nav_ty_reloc_index);
try wip_nav.abbrevCode(.is_const);
- try wip_nav.refType(ty);
+ try wip_nav.refType(nav_ty);
},
.variable => |variable| {
assert(file.zir_loaded);
@@ -2286,20 +2319,16 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
.source_off = @intCast(wip_nav.debug_frame.items.len),
});
try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
- try entry.external_relocs.append(dwarf.gpa, .{
- .source_off = @intCast(wip_nav.debug_frame.items.len),
- .target_sym = sym_index,
- });
- try dfw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
+ try wip_nav.frameAddrSym(sym_index);
try dfw.writeByteNTimes(undefined, @intFromEnum(dwarf.address_size));
},
.eh_frame => {
try dfw.writeInt(u32, undefined, dwarf.endian);
- try entry.external_relocs.append(dwarf.gpa, .{
+ try wip_nav.frameExternalReloc(.{
.source_off = @intCast(wip_nav.debug_frame.items.len),
.target_sym = sym_index,
});
- try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
+ try dfw.writeInt(u32, 0, dwarf.endian);
try dfw.writeInt(u32, undefined, dwarf.endian);
try uleb128(dfw, 0);
},
@@ -2479,12 +2508,13 @@ pub fn finishWipNav(
}
try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items);
- try wip_nav.flush();
+ try wip_nav.flush(zcu.navSrcLoc(nav_index));
}
pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateError!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
+ const nav_src_loc = zcu.navSrcLoc(nav_index);
const nav_val = zcu.navValue(nav_index);
const nav = ip.getNav(nav_index);
@@ -2507,6 +2537,19 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
return;
}
+ const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
+ const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
+ break :parent .{
+ parent_namespace_ptr.owner_type,
+ if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
+ DW.ACCESS.public
+ else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
+ DW.ACCESS.private
+ else
+ unreachable,
+ };
+ } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
+
const tree = try file.getTree(dwarf.gpa);
const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]);
assert(loc.line == zcu.navSrcLine(nav_index));
@@ -2532,8 +2575,341 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
errdefer _ = dwarf.navs.pop();
- switch (ip.indexToKey(nav_val.toIntern())) {
- .func => |func| {
+
+ const tag: enum { done, decl_alias, decl_var, decl_const } = switch (ip.indexToKey(nav_val.toIntern())) {
+ .int_type,
+ .ptr_type,
+ .array_type,
+ .vector_type,
+ .opt_type,
+ .anyframe_type,
+ .error_union_type,
+ .simple_type,
+ .anon_struct_type,
+ .func_type,
+ .error_set_type,
+ .inferred_error_set_type,
+ => .decl_alias,
+ .struct_type => tag: {
+ const loaded_struct = ip.loadStructType(nav_val.toIntern());
+ if (loaded_struct.zir_index == .none) break :tag .decl_alias;
+
+ const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
+ if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
+
+ const value_inst = value_inst: {
+ const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
+ const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
+ if (break_inst.tag != .break_inline) break :value_inst null;
+ assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
+ var value_inst = break_inst.data.@"break".operand.toIndex();
+ while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
+ else => break,
+ .as_node => value_inst = file.zir.extraData(
+ Zir.Inst.As,
+ file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
+ ).data.operand.toIndex(),
+ };
+ break :value_inst value_inst;
+ };
+ if (type_inst_info.inst != value_inst) break :tag .decl_alias;
+
+ const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
+ if (type_gop.found_existing) {
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
+ nav_gop.value_ptr.* = type_gop.value_ptr.*;
+ } else {
+ if (nav_gop.found_existing)
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
+ else
+ nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
+ type_gop.value_ptr.* = nav_gop.value_ptr.*;
+ }
+ wip_nav.entry = nav_gop.value_ptr.*;
+
+ const diw = wip_nav.debug_info.writer(dwarf.gpa);
+
+ switch (loaded_struct.layout) {
+ .auto, .@"extern" => {
+ try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
+ try wip_nav.refType(Type.fromInterned(parent_type));
+ assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
+ try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
+ try uleb128(diw, loc.column + 1);
+ try diw.writeByte(accessibility);
+ try wip_nav.strp(nav.name.toSlice(ip));
+ if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
+ try uleb128(diw, nav_val.toType().abiSize(zcu));
+ try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
+ for (0..loaded_struct.field_types.len) |field_index| {
+ const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
+ const field_init = if (loaded_struct.haveFieldInits(ip))
+ loaded_struct.fieldInit(ip, field_index)
+ else
+ .none;
+ try wip_nav.abbrevCode(if (is_comptime)
+ .struct_field_comptime
+ else if (field_init != .none)
+ .struct_field_default
+ else
+ .struct_field);
+ if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
+ const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
+ defer dwarf.gpa.free(field_name);
+ try wip_nav.strp(field_name);
+ }
+ if (is_comptime and field_init == .none) {
+ // workaround frontend bug
+ try wip_nav.refType(Type.void);
+ try wip_nav.blockValue(nav_src_loc, Value.void);
+ } else {
+ const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ if (!is_comptime) {
+ try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
+ try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
+ field_type.abiAlignment(zcu).toByteUnits().?);
+ }
+ if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init));
+ }
+ }
+ try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ }
+ },
+ .@"packed" => {
+ try wip_nav.abbrevCode(.decl_packed_struct);
+ try wip_nav.refType(Type.fromInterned(parent_type));
+ assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
+ try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
+ try uleb128(diw, loc.column + 1);
+ try diw.writeByte(accessibility);
+ try wip_nav.strp(nav.name.toSlice(ip));
+ try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
+ var field_bit_offset: u16 = 0;
+ for (0..loaded_struct.field_types.len) |field_index| {
+ try wip_nav.abbrevCode(.packed_struct_field);
+ try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
+ const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ try uleb128(diw, field_bit_offset);
+ field_bit_offset += @intCast(field_type.bitSize(zcu));
+ }
+ try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ },
+ }
+ break :tag .done;
+ },
+ .enum_type => tag: {
+ const loaded_enum = ip.loadEnumType(nav_val.toIntern());
+ if (loaded_enum.zir_index == .none) break :tag .decl_alias;
+
+ const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
+ if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
+
+ const value_inst = value_inst: {
+ const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
+ const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
+ if (break_inst.tag != .break_inline) break :value_inst null;
+ assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
+ var value_inst = break_inst.data.@"break".operand.toIndex();
+ while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
+ else => break,
+ .as_node => value_inst = file.zir.extraData(
+ Zir.Inst.As,
+ file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
+ ).data.operand.toIndex(),
+ };
+ break :value_inst value_inst;
+ };
+ if (type_inst_info.inst != value_inst) break :tag .decl_alias;
+
+ const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
+ if (type_gop.found_existing) {
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
+ nav_gop.value_ptr.* = type_gop.value_ptr.*;
+ } else {
+ if (nav_gop.found_existing)
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
+ else
+ nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
+ type_gop.value_ptr.* = nav_gop.value_ptr.*;
+ }
+ wip_nav.entry = nav_gop.value_ptr.*;
+ const diw = wip_nav.debug_info.writer(dwarf.gpa);
+ try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
+ try wip_nav.refType(Type.fromInterned(parent_type));
+ assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
+ try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
+ try uleb128(diw, loc.column + 1);
+ try diw.writeByte(accessibility);
+ try wip_nav.strp(nav.name.toSlice(ip));
+ try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
+ for (0..loaded_enum.names.len) |field_index| {
+ try wip_nav.enumConstValue(loaded_enum, .{
+ .sdata = .signed_enum_field,
+ .udata = .unsigned_enum_field,
+ .block = .big_enum_field,
+ }, field_index);
+ try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
+ }
+ if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ break :tag .done;
+ },
+ .union_type => tag: {
+ const loaded_union = ip.loadUnionType(nav_val.toIntern());
+
+ const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
+ if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
+
+ const value_inst = value_inst: {
+ const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
+ const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
+ if (break_inst.tag != .break_inline) break :value_inst null;
+ assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
+ var value_inst = break_inst.data.@"break".operand.toIndex();
+ while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
+ else => break,
+ .as_node => value_inst = file.zir.extraData(
+ Zir.Inst.As,
+ file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
+ ).data.operand.toIndex(),
+ };
+ break :value_inst value_inst;
+ };
+ if (type_inst_info.inst != value_inst) break :tag .decl_alias;
+
+ const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
+ if (type_gop.found_existing) {
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
+ nav_gop.value_ptr.* = type_gop.value_ptr.*;
+ } else {
+ if (nav_gop.found_existing)
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
+ else
+ nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
+ type_gop.value_ptr.* = nav_gop.value_ptr.*;
+ }
+ wip_nav.entry = nav_gop.value_ptr.*;
+ const diw = wip_nav.debug_info.writer(dwarf.gpa);
+ try wip_nav.abbrevCode(.decl_union);
+ try wip_nav.refType(Type.fromInterned(parent_type));
+ assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
+ try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
+ try uleb128(diw, loc.column + 1);
+ try diw.writeByte(accessibility);
+ try wip_nav.strp(nav.name.toSlice(ip));
+ const union_layout = Type.getUnionLayout(loaded_union, zcu);
+ try uleb128(diw, union_layout.abi_size);
+ try uleb128(diw, union_layout.abi_align.toByteUnits().?);
+ const loaded_tag = loaded_union.loadTagType(ip);
+ if (loaded_union.hasTag(ip)) {
+ try wip_nav.abbrevCode(.tagged_union);
+ try wip_nav.infoSectionOffset(
+ .debug_info,
+ wip_nav.unit,
+ wip_nav.entry,
+ @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
+ );
+ {
+ try wip_nav.abbrevCode(.generated_field);
+ try wip_nav.strp("tag");
+ try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
+ try uleb128(diw, union_layout.tagOffset());
+
+ for (0..loaded_union.field_types.len) |field_index| {
+ try wip_nav.enumConstValue(loaded_tag, .{
+ .sdata = .signed_tagged_union_field,
+ .udata = .unsigned_tagged_union_field,
+ .block = .big_tagged_union_field,
+ }, field_index);
+ {
+ try wip_nav.abbrevCode(.struct_field);
+ try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
+ const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ try uleb128(diw, union_layout.payloadOffset());
+ try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
+ if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
+ }
+ try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ }
+ }
+ try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ } else for (0..loaded_union.field_types.len) |field_index| {
+ try wip_nav.abbrevCode(.untagged_union_field);
+ try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
+ const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
+ field_type.abiAlignment(zcu).toByteUnits().?);
+ }
+ try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ break :tag .done;
+ },
+ .opaque_type => tag: {
+ const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
+
+ const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
+ if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
+
+ const value_inst = value_inst: {
+ const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
+ const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
+ if (break_inst.tag != .break_inline) break :value_inst null;
+ assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
+ var value_inst = break_inst.data.@"break".operand.toIndex();
+ while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
+ else => break,
+ .as_node => value_inst = file.zir.extraData(
+ Zir.Inst.As,
+ file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
+ ).data.operand.toIndex(),
+ };
+ break :value_inst value_inst;
+ };
+ if (type_inst_info.inst != value_inst) break :tag .decl_alias;
+
+ const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
+ if (type_gop.found_existing) {
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
+ nav_gop.value_ptr.* = type_gop.value_ptr.*;
+ } else {
+ if (nav_gop.found_existing)
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
+ else
+ nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
+ type_gop.value_ptr.* = nav_gop.value_ptr.*;
+ }
+ wip_nav.entry = nav_gop.value_ptr.*;
+ const diw = wip_nav.debug_info.writer(dwarf.gpa);
+ try wip_nav.abbrevCode(.decl_namespace_struct);
+ try wip_nav.refType(Type.fromInterned(parent_type));
+ assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
+ try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
+ try uleb128(diw, loc.column + 1);
+ try diw.writeByte(accessibility);
+ try wip_nav.strp(nav.name.toSlice(ip));
+ try diw.writeByte(@intFromBool(false));
+ break :tag .done;
+ },
+ .undef,
+ .simple_value,
+ .@"extern",
+ .int,
+ .err,
+ .error_union,
+ .enum_literal,
+ .enum_tag,
+ .empty_enum_value,
+ .float,
+ .ptr,
+ .slice,
+ .opt,
+ .aggregate,
+ .un,
+ => .decl_const,
+ .variable => .decl_var,
+ .func => |func| tag: {
if (nav_gop.found_existing) {
const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit);
const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
@@ -2557,19 +2933,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
} else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
wip_nav.entry = nav_gop.value_ptr.*;
- const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
- const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
- break :parent .{
- parent_namespace_ptr.owner_type,
- if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.public
- else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.private
- else
- unreachable,
- };
- } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
-
const func_type = ip.indexToKey(func.ty).func_type;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
@@ -2591,208 +2954,21 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
try uleb128(diw, @intFromEnum(AbbrevCode.null));
}
+ break :tag .done;
},
- .struct_type => done: {
- const loaded_struct = ip.loadStructType(nav_val.toIntern());
-
- const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
- const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
- break :parent .{
- parent_namespace_ptr.owner_type,
- if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.public
- else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.private
- else
- unreachable,
- };
- } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
-
- decl_struct: {
- if (loaded_struct.zir_index == .none) break :decl_struct;
-
- const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
- if (type_inst_info.file != inst_info.file) break :decl_struct;
-
- const value_inst = value_inst: {
- const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
- const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
- if (break_inst.tag != .break_inline) break :value_inst null;
- assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
- var value_inst = break_inst.data.@"break".operand.toIndex();
- while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
- else => break,
- .as_node => value_inst = file.zir.extraData(
- Zir.Inst.As,
- file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
- ).data.operand.toIndex(),
- };
- break :value_inst value_inst;
- };
- if (type_inst_info.inst != value_inst) break :decl_struct;
-
- const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
- if (type_gop.found_existing) {
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
- nav_gop.value_ptr.* = type_gop.value_ptr.*;
- } else {
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- type_gop.value_ptr.* = nav_gop.value_ptr.*;
- }
- wip_nav.entry = nav_gop.value_ptr.*;
-
- const diw = wip_nav.debug_info.writer(dwarf.gpa);
-
- switch (loaded_struct.layout) {
- .auto, .@"extern" => {
- try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
- try uleb128(diw, nav_val.toType().abiSize(zcu));
- try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
- for (0..loaded_struct.field_types.len) |field_index| {
- const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
- if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
- const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
- defer dwarf.gpa.free(field_name);
- try wip_nav.strp(field_name);
- }
- const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- if (!is_comptime) {
- try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
- try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
- field_type.abiAlignment(zcu).toByteUnits().?);
- }
- }
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
- }
- },
- .@"packed" => {
- try wip_nav.abbrevCode(.decl_packed_struct);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
- var field_bit_offset: u16 = 0;
- for (0..loaded_struct.field_types.len) |field_index| {
- try wip_nav.abbrevCode(.packed_struct_field);
- try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
- const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- try uleb128(diw, field_bit_offset);
- field_bit_offset += @intCast(field_type.bitSize(zcu));
- }
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
- },
- }
- break :done;
- }
-
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- wip_nav.entry = nav_gop.value_ptr.*;
- const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(.decl_alias);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- try wip_nav.refType(nav_val.toType());
- },
- .enum_type => done: {
- const loaded_enum = ip.loadEnumType(nav_val.toIntern());
-
- const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
- const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
- break :parent .{
- parent_namespace_ptr.owner_type,
- if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.public
- else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.private
- else
- unreachable,
- };
- } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
-
- decl_enum: {
- if (loaded_enum.zir_index == .none) break :decl_enum;
-
- const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
- if (type_inst_info.file != inst_info.file) break :decl_enum;
-
- const value_inst = value_inst: {
- const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
- const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
- if (break_inst.tag != .break_inline) break :value_inst null;
- assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
- var value_inst = break_inst.data.@"break".operand.toIndex();
- while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
- else => break,
- .as_node => value_inst = file.zir.extraData(
- Zir.Inst.As,
- file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
- ).data.operand.toIndex(),
- };
- break :value_inst value_inst;
- };
- if (type_inst_info.inst != value_inst) break :decl_enum;
-
- const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
- if (type_gop.found_existing) {
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
- nav_gop.value_ptr.* = type_gop.value_ptr.*;
- } else {
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- type_gop.value_ptr.* = nav_gop.value_ptr.*;
- }
- wip_nav.entry = nav_gop.value_ptr.*;
- const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
- for (0..loaded_enum.names.len) |field_index| {
- try wip_nav.enumConstValue(loaded_enum, .{
- .sdata = .signed_enum_field,
- .udata = .unsigned_enum_field,
- .block = .big_enum_field,
- }, field_index);
- try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
- }
- if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
- break :done;
- }
-
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- wip_nav.entry = nav_gop.value_ptr.*;
+ // memoization, not types
+ .memoized_call => unreachable,
+ };
+ if (tag != .done) {
+ if (nav_gop.found_existing)
+ dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
+ else
+ nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
+ wip_nav.entry = nav_gop.value_ptr.*;
+ }
+ switch (tag) {
+ .done => {},
+ .decl_alias => {
const diw = wip_nav.debug_info.writer(dwarf.gpa);
try wip_nav.abbrevCode(.decl_alias);
try wip_nav.refType(Type.fromInterned(parent_type));
@@ -2803,215 +2979,52 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
try wip_nav.strp(nav.name.toSlice(ip));
try wip_nav.refType(nav_val.toType());
},
- .union_type => done: {
- const loaded_union = ip.loadUnionType(nav_val.toIntern());
-
- const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
- const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
- break :parent .{
- parent_namespace_ptr.owner_type,
- if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.public
- else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.private
- else
- unreachable,
- };
- } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
-
- decl_union: {
- const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
- if (type_inst_info.file != inst_info.file) break :decl_union;
-
- const value_inst = value_inst: {
- const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
- const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
- if (break_inst.tag != .break_inline) break :value_inst null;
- assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
- var value_inst = break_inst.data.@"break".operand.toIndex();
- while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
- else => break,
- .as_node => value_inst = file.zir.extraData(
- Zir.Inst.As,
- file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
- ).data.operand.toIndex(),
- };
- break :value_inst value_inst;
- };
- if (type_inst_info.inst != value_inst) break :decl_union;
-
- const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
- if (type_gop.found_existing) {
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
- nav_gop.value_ptr.* = type_gop.value_ptr.*;
- } else {
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- type_gop.value_ptr.* = nav_gop.value_ptr.*;
- }
- wip_nav.entry = nav_gop.value_ptr.*;
- const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(.decl_union);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- const union_layout = Type.getUnionLayout(loaded_union, zcu);
- try uleb128(diw, union_layout.abi_size);
- try uleb128(diw, union_layout.abi_align.toByteUnits().?);
- const loaded_tag = loaded_union.loadTagType(ip);
- if (loaded_union.hasTag(ip)) {
- try wip_nav.abbrevCode(.tagged_union);
- try wip_nav.infoSectionOffset(
- .debug_info,
- wip_nav.unit,
- wip_nav.entry,
- @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
- );
- {
- try wip_nav.abbrevCode(.generated_field);
- try wip_nav.strp("tag");
- try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
- try uleb128(diw, union_layout.tagOffset());
-
- for (0..loaded_union.field_types.len) |field_index| {
- try wip_nav.enumConstValue(loaded_tag, .{
- .sdata = .signed_tagged_union_field,
- .udata = .unsigned_tagged_union_field,
- .block = .big_tagged_union_field,
- }, field_index);
- {
- try wip_nav.abbrevCode(.struct_field);
- try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
- const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- try uleb128(diw, union_layout.payloadOffset());
- try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
- if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
- }
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
- }
- }
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
- } else for (0..loaded_union.field_types.len) |field_index| {
- try wip_nav.abbrevCode(.untagged_union_field);
- try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
- const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
- field_type.abiAlignment(zcu).toByteUnits().?);
- }
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
- break :done;
- }
-
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- wip_nav.entry = nav_gop.value_ptr.*;
+ .decl_var => {
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(.decl_alias);
+ try wip_nav.abbrevCode(.decl_var);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
try uleb128(diw, loc.column + 1);
try diw.writeByte(accessibility);
try wip_nav.strp(nav.name.toSlice(ip));
- try wip_nav.refType(nav_val.toType());
+ try wip_nav.strp(nav.fqn.toSlice(ip));
+ const nav_ty = nav_val.typeOf(zcu);
+ try wip_nav.refType(nav_ty);
+ try wip_nav.blockValue(nav_src_loc, nav_val);
+ try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
+ nav_ty.abiAlignment(zcu).toByteUnits().?);
+ try diw.writeByte(@intFromBool(false));
},
- .opaque_type => done: {
- const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
-
- const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
- const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
- break :parent .{
- parent_namespace_ptr.owner_type,
- if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.public
- else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
- DW.ACCESS.private
- else
- unreachable,
- };
- } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
-
- decl_opaque: {
- const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
- if (type_inst_info.file != inst_info.file) break :decl_opaque;
-
- const value_inst = value_inst: {
- const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
- const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
- if (break_inst.tag != .break_inline) break :value_inst null;
- assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
- var value_inst = break_inst.data.@"break".operand.toIndex();
- while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
- else => break,
- .as_node => value_inst = file.zir.extraData(
- Zir.Inst.As,
- file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
- ).data.operand.toIndex(),
- };
- break :value_inst value_inst;
- };
- if (type_inst_info.inst != value_inst) break :decl_opaque;
-
- const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
- if (type_gop.found_existing) {
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
- nav_gop.value_ptr.* = type_gop.value_ptr.*;
- } else {
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- type_gop.value_ptr.* = nav_gop.value_ptr.*;
- }
- wip_nav.entry = nav_gop.value_ptr.*;
- const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(.decl_namespace_struct);
- try wip_nav.refType(Type.fromInterned(parent_type));
- assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
- try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
- try uleb128(diw, loc.column + 1);
- try diw.writeByte(accessibility);
- try wip_nav.strp(nav.name.toSlice(ip));
- try diw.writeByte(@intFromBool(false));
- break :done;
- }
-
- if (nav_gop.found_existing)
- dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
- else
- nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
- wip_nav.entry = nav_gop.value_ptr.*;
+ .decl_const => {
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.abbrevCode(.decl_alias);
+ try wip_nav.abbrevCode(.decl_const);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
try uleb128(diw, loc.column + 1);
try diw.writeByte(accessibility);
try wip_nav.strp(nav.name.toSlice(ip));
- try wip_nav.refType(nav_val.toType());
- },
- else => {
- _ = dwarf.navs.pop();
- return;
+ try wip_nav.strp(nav.fqn.toSlice(ip));
+ const nav_ty = nav_val.typeOf(zcu);
+ const nav_ty_reloc_index = try wip_nav.refForward();
+ try wip_nav.blockValue(nav_src_loc, nav_val);
+ try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
+ nav_ty.abiAlignment(zcu).toByteUnits().?);
+ try diw.writeByte(@intFromBool(false));
+ wip_nav.finishForward(nav_ty_reloc_index);
+ try wip_nav.abbrevCode(.is_const);
+ try wip_nav.refType(nav_ty);
},
}
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
- try wip_nav.flush();
+ try wip_nav.flush(nav_src_loc);
}
fn updateType(
dwarf: *Dwarf,
pt: Zcu.PerThread,
+ src_loc: Zcu.LazySrcLoc,
type_index: InternPool.Index,
pending_types: *std.ArrayListUnmanaged(InternPool.Index),
) UpdateError!void {
@@ -3068,15 +3081,10 @@ fn updateType(
const ptr_child_type = Type.fromInterned(ptr_type.child);
try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type);
try wip_nav.strp(name);
- if (ptr_type.sentinel != .none) {
- const bytes = ptr_child_type.abiSize(zcu);
- try uleb128(diw, bytes);
- const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes));
- Value.fromInterned(ptr_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) {
- error.IllDefinedMemoryLayout => @memset(mem, 0),
- else => |e| return e,
- };
- }
+ if (ptr_type.sentinel != .none) try wip_nav.blockValue(
+ src_loc,
+ Value.fromInterned(ptr_type.sentinel),
+ );
try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
ptr_child_type.abiAlignment(zcu).toByteUnits().?);
try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
@@ -3122,15 +3130,10 @@ fn updateType(
const array_child_type = Type.fromInterned(array_type.child);
try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);
try wip_nav.strp(name);
- if (array_type.sentinel != .none) {
- const bytes = array_child_type.abiSize(zcu);
- try uleb128(diw, bytes);
- const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes));
- Value.fromInterned(array_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) {
- error.IllDefinedMemoryLayout => @memset(mem, 0),
- else => |e| return e,
- };
- }
+ if (array_type.sentinel != .none) try wip_nav.blockValue(
+ src_loc,
+ Value.fromInterned(array_type.sentinel),
+ );
try wip_nav.refType(array_child_type);
try wip_nav.abbrevCode(.array_index);
try wip_nav.refType(Type.usize);
@@ -3360,7 +3363,10 @@ fn updateType(
}
const field_type = Type.fromInterned(anon_struct_type.types.get(ip)[field_index]);
try wip_nav.refType(field_type);
- if (comptime_value == .none) {
+ if (comptime_value != .none) try wip_nav.blockValue(
+ src_loc,
+ Value.fromInterned(comptime_value),
+ ) else {
const field_align = field_type.abiAlignment(zcu);
field_byte_offset = field_align.forward(field_byte_offset);
try uleb128(diw, field_byte_offset);
@@ -3427,16 +3433,13 @@ fn updateType(
}
if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
},
- .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {
- .none => {
- try wip_nav.abbrevCode(.void_type);
- try wip_nav.strp(name);
- },
- else => |ies| {
- try wip_nav.abbrevCode(.inferred_error_set_type);
- try wip_nav.strp(name);
- try wip_nav.refType(Type.fromInterned(ies));
- },
+ .inferred_error_set_type => |func| {
+ try wip_nav.abbrevCode(.inferred_error_set_type);
+ try wip_nav.strp(name);
+ try wip_nav.refType(Type.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {
+ .none => .anyerror_type,
+ else => |ies| ies,
+ }));
},
// values, not types
@@ -3468,6 +3471,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const ty = Type.fromInterned(type_index);
+ const ty_src_loc = ty.srcLoc(zcu);
log.debug("updateContainerType({}({d}))", .{ ty.fmt(pt), @intFromEnum(type_index) });
const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
@@ -3507,25 +3511,41 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
+ const field_init = if (loaded_struct.haveFieldInits(ip))
+ loaded_struct.fieldInit(ip, field_index)
+ else
+ .none;
+ try wip_nav.abbrevCode(if (is_comptime)
+ .struct_field_comptime
+ else if (field_init != .none)
+ .struct_field_default
+ else
+ .struct_field);
if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
try wip_nav.strp(field_name);
}
- const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- if (!is_comptime) {
- try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
- try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
- field_type.abiAlignment(zcu).toByteUnits().?);
+ if (is_comptime and field_init == .none) {
+ // workaround frontend bug
+ try wip_nav.refType(Type.void);
+ try wip_nav.blockValue(ty_src_loc, Value.void);
+ } else {
+ const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ if (!is_comptime) {
+ try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
+ try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
+ field_type.abiAlignment(zcu).toByteUnits().?);
+ }
+ if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
}
}
try uleb128(diw, @intFromEnum(AbbrevCode.null));
}
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
- try wip_nav.flush();
+ try wip_nav.flush(ty_src_loc);
} else {
const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
assert(decl_inst.tag == .extended);
@@ -3575,18 +3595,34 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
+ const field_init = if (loaded_struct.haveFieldInits(ip))
+ loaded_struct.fieldInit(ip, field_index)
+ else
+ .none;
+ try wip_nav.abbrevCode(if (is_comptime)
+ .struct_field_comptime
+ else if (field_init != .none)
+ .struct_field_default
+ else
+ .struct_field);
if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
try wip_nav.strp(field_name);
}
- const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
- try wip_nav.refType(field_type);
- if (!is_comptime) {
- try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
- try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
- field_type.abiAlignment(zcu).toByteUnits().?);
+ if (is_comptime and field_init == .none) {
+ // workaround frontend bug
+ try wip_nav.refType(Type.void);
+ try wip_nav.blockValue(ty_src_loc, Value.void);
+ } else {
+ const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
+ try wip_nav.refType(field_type);
+ if (!is_comptime) {
+ try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
+ try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
+ field_type.abiAlignment(zcu).toByteUnits().?);
+ }
+ if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
}
}
try uleb128(diw, @intFromEnum(AbbrevCode.null));
@@ -3684,7 +3720,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
}
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items);
- try wip_nav.flush();
+ try wip_nav.flush(ty_src_loc);
}
}
@@ -3732,12 +3768,15 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A
pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
- if (dwarf.types.get(.anyerror_type)) |entry| {
+
+ {
+ const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type);
+ if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main);
var wip_nav: WipNav = .{
.dwarf = dwarf,
.pt = pt,
.unit = .main,
- .entry = entry,
+ .entry = type_gop.value_ptr.*,
.any_children = false,
.func = .none,
.func_sym_index = undefined,
@@ -4150,6 +4189,7 @@ const AbbrevCode = enum {
decl_packed_struct,
decl_union,
decl_var,
+ decl_const,
decl_func,
decl_empty_func,
decl_func_generic,
@@ -4164,6 +4204,7 @@ const AbbrevCode = enum {
big_enum_field,
generated_field,
struct_field,
+ struct_field_default,
struct_field_comptime,
packed_struct_field,
untagged_union_field,
@@ -4285,6 +4326,16 @@ const AbbrevCode = enum {
.{ .external, .flag },
},
},
+ .decl_const = .{
+ .tag = .constant,
+ .attrs = decl_abbrev_common_attrs ++ .{
+ .{ .linkage_name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
+ .{ .alignment, .udata },
+ .{ .external, .flag },
+ },
+ },
.decl_func = .{
.tag = .subprogram,
.children = true,
@@ -4401,12 +4452,23 @@ const AbbrevCode = enum {
.{ .alignment, .udata },
},
},
- .struct_field_comptime = .{
+ .struct_field_default = .{
.tag = .member,
.attrs = &.{
.{ .name, .strp },
.{ .type, .ref_addr },
+ .{ .data_member_location, .udata },
+ .{ .alignment, .udata },
+ .{ .default_value, .block },
+ },
+ },
+ .struct_field_comptime = .{
+ .tag = .member,
+ .attrs = &.{
.{ .const_expr, .flag_present },
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
},
},
.packed_struct_field = .{
diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig
index 0dc4bd9dae..98449d6a5b 100644
--- a/src/link/Elf/ZigObject.zig
+++ b/src/link/Elf/ZigObject.zig
@@ -957,13 +957,26 @@ pub fn getNavVAddr(
};
const this_sym = self.symbol(this_sym_index);
const vaddr = this_sym.address(.{}, elf_file);
- const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
- const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
- try parent_atom.addReloc(elf_file.base.comp.gpa, .{
- .r_offset = reloc_info.offset,
- .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
- .r_addend = reloc_info.addend,
- }, self);
+ switch (reloc_info.parent) {
+ .atom_index => |atom_index| {
+ const parent_atom = self.symbol(atom_index).atom(elf_file).?;
+ const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
+ try parent_atom.addReloc(elf_file.base.comp.gpa, .{
+ .r_offset = reloc_info.offset,
+ .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
+ .r_addend = reloc_info.addend,
+ }, self);
+ },
+ .debug_output => |debug_output| switch (debug_output) {
+ .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
+ .source_off = @intCast(reloc_info.offset),
+ .target_sym = this_sym_index,
+ .target_off = reloc_info.addend,
+ }),
+ .plan9 => unreachable,
+ .none => unreachable,
+ },
+ }
return @intCast(vaddr);
}
@@ -976,13 +989,26 @@ pub fn getUavVAddr(
const sym_index = self.uavs.get(uav).?.symbol_index;
const sym = self.symbol(sym_index);
const vaddr = sym.address(.{}, elf_file);
- const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
- const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
- try parent_atom.addReloc(elf_file.base.comp.gpa, .{
- .r_offset = reloc_info.offset,
- .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
- .r_addend = reloc_info.addend,
- }, self);
+ switch (reloc_info.parent) {
+ .atom_index => |atom_index| {
+ const parent_atom = self.symbol(atom_index).atom(elf_file).?;
+ const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
+ try parent_atom.addReloc(elf_file.base.comp.gpa, .{
+ .r_offset = reloc_info.offset,
+ .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
+ .r_addend = reloc_info.addend,
+ }, self);
+ },
+ .debug_output => |debug_output| switch (debug_output) {
+ .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
+ .source_off = @intCast(reloc_info.offset),
+ .target_sym = sym_index,
+ .target_off = reloc_info.addend,
+ }),
+ .plan9 => unreachable,
+ .none => unreachable,
+ },
+ }
return @intCast(vaddr);
}
@@ -1600,15 +1626,13 @@ pub fn updateNav(
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
- // TODO implement .debug_info for global variables
const res = try codegen.generateSymbol(
&elf_file.base,
pt,
zcu.navSrcLoc(nav_index),
Value.fromInterned(nav_init),
&code_buffer,
- if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
- .{ .parent_atom_index = sym_index },
+ .{ .atom_index = sym_index },
);
const code = switch (res) {
@@ -1691,7 +1715,7 @@ fn updateLazySymbol(
&required_alignment,
&code_buffer,
.none,
- .{ .parent_atom_index = symbol_index },
+ .{ .atom_index = symbol_index },
);
const code = switch (res) {
.ok => code_buffer.items,
@@ -1780,8 +1804,7 @@ fn lowerConst(
src_loc,
val,
&code_buffer,
- .{ .none = {} },
- .{ .parent_atom_index = sym_index },
+ .{ .atom_index = sym_index },
);
const code = switch (res) {
.ok => code_buffer.items,
diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig
index 6a771a3b84..3ffa9c4745 100644
--- a/src/link/MachO/ZigObject.zig
+++ b/src/link/MachO/ZigObject.zig
@@ -633,20 +633,33 @@ pub fn getNavVAddr(
};
const sym = self.symbols.items[sym_index];
const vaddr = sym.getAddress(.{}, macho_file);
- const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
- try parent_atom.addReloc(macho_file, .{
- .tag = .@"extern",
- .offset = @intCast(reloc_info.offset),
- .target = sym_index,
- .addend = reloc_info.addend,
- .type = .unsigned,
- .meta = .{
- .pcrel = false,
- .has_subtractor = false,
- .length = 3,
- .symbolnum = @intCast(sym.nlist_idx),
+ switch (reloc_info.parent) {
+ .atom_index => |atom_index| {
+ const parent_atom = self.symbols.items[atom_index].getAtom(macho_file).?;
+ try parent_atom.addReloc(macho_file, .{
+ .tag = .@"extern",
+ .offset = @intCast(reloc_info.offset),
+ .target = sym_index,
+ .addend = reloc_info.addend,
+ .type = .unsigned,
+ .meta = .{
+ .pcrel = false,
+ .has_subtractor = false,
+ .length = 3,
+ .symbolnum = @intCast(sym.nlist_idx),
+ },
+ });
},
- });
+ .debug_output => |debug_output| switch (debug_output) {
+ .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
+ .source_off = @intCast(reloc_info.offset),
+ .target_sym = sym_index,
+ .target_off = reloc_info.addend,
+ }),
+ .plan9 => unreachable,
+ .none => unreachable,
+ },
+ }
return vaddr;
}
@@ -659,20 +672,33 @@ pub fn getUavVAddr(
const sym_index = self.uavs.get(uav).?.symbol_index;
const sym = self.symbols.items[sym_index];
const vaddr = sym.getAddress(.{}, macho_file);
- const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
- try parent_atom.addReloc(macho_file, .{
- .tag = .@"extern",
- .offset = @intCast(reloc_info.offset),
- .target = sym_index,
- .addend = reloc_info.addend,
- .type = .unsigned,
- .meta = .{
- .pcrel = false,
- .has_subtractor = false,
- .length = 3,
- .symbolnum = @intCast(sym.nlist_idx),
+ switch (reloc_info.parent) {
+ .atom_index => |atom_index| {
+ const parent_atom = self.symbols.items[atom_index].getAtom(macho_file).?;
+ try parent_atom.addReloc(macho_file, .{
+ .tag = .@"extern",
+ .offset = @intCast(reloc_info.offset),
+ .target = sym_index,
+ .addend = reloc_info.addend,
+ .type = .unsigned,
+ .meta = .{
+ .pcrel = false,
+ .has_subtractor = false,
+ .length = 3,
+ .symbolnum = @intCast(sym.nlist_idx),
+ },
+ });
},
- });
+ .debug_output => |debug_output| switch (debug_output) {
+ .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
+ .source_off = @intCast(reloc_info.offset),
+ .target_sym = sym_index,
+ .target_off = reloc_info.addend,
+ }),
+ .plan9 => unreachable,
+ .none => unreachable,
+ },
+ }
return vaddr;
}
@@ -903,8 +929,7 @@ pub fn updateNav(
zcu.navSrcLoc(nav_index),
Value.fromInterned(nav_init),
&code_buffer,
- if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
- .{ .parent_atom_index = sym_index },
+ .{ .atom_index = sym_index },
);
const code = switch (res) {
@@ -1212,11 +1237,14 @@ fn lowerConst(
const name_str = try self.addString(gpa, name);
const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
- const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
- .none = {},
- }, .{
- .parent_atom_index = sym_index,
- });
+ const res = try codegen.generateSymbol(
+ &macho_file.base,
+ pt,
+ src_loc,
+ val,
+ &code_buffer,
+ .{ .atom_index = sym_index },
+ );
const code = switch (res) {
.ok => code_buffer.items,
.fail => |em| return .{ .fail = em },
@@ -1378,7 +1406,7 @@ fn updateLazySymbol(
&required_alignment,
&code_buffer,
.none,
- .{ .parent_atom_index = symbol_index },
+ .{ .atom_index = symbol_index },
);
const code = switch (res) {
.ok => code_buffer.items,
diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig
index 080b6853e7..7737c22d05 100644
--- a/src/link/Plan9.zig
+++ b/src/link/Plan9.zig
@@ -422,10 +422,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
);
const code = switch (res) {
.ok => try code_buffer.toOwnedSlice(),
- .fail => |em| {
- try zcu.failed_codegen.put(gpa, func.owner_nav, em);
- return;
- },
+ .fail => |em| return zcu.failed_codegen.put(gpa, func.owner_nav, em),
};
self.getAtomPtr(atom_idx).code = .{
.code_ptr = null,
@@ -463,15 +460,17 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
var code_buffer = std.ArrayList(u8).init(gpa);
defer code_buffer.deinit();
// TODO we need the symbol index for symbol in the table of locals for the containing atom
- const res = try codegen.generateSymbol(&self.base, pt, zcu.navSrcLoc(nav_index), nav_init, &code_buffer, .none, .{
- .parent_atom_index = @intCast(atom_idx),
- });
+ const res = try codegen.generateSymbol(
+ &self.base,
+ pt,
+ zcu.navSrcLoc(nav_index),
+ nav_init,
+ &code_buffer,
+ .{ .atom_index = @intCast(atom_idx) },
+ );
const code = switch (res) {
.ok => code_buffer.items,
- .fail => |em| {
- try zcu.failed_codegen.put(gpa, nav_index, em);
- return;
- },
+ .fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em),
};
try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
const duped_code = try gpa.dupe(u8, code);
@@ -1116,7 +1115,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a
&required_alignment,
&code_buffer,
.none,
- .{ .parent_atom_index = @as(Atom.Index, @intCast(atom_index)) },
+ .{ .atom_index = @intCast(atom_index) },
);
const code = switch (res) {
.ok => code_buffer.items,
@@ -1373,21 +1372,21 @@ pub fn getNavVAddr(
log.debug("getDeclVAddr for {}", .{nav.name.fmt(ip)});
if (ip.indexToKey(nav.status.resolved.val) == .@"extern") {
if (nav.name.eqlSlice("etext", ip)) {
- try self.addReloc(reloc_info.parent_atom_index, .{
+ try self.addReloc(reloc_info.parent.atom_index, .{
.target = undefined,
.offset = reloc_info.offset,
.addend = reloc_info.addend,
.type = .special_etext,
});
} else if (nav.name.eqlSlice("edata", ip)) {
- try self.addReloc(reloc_info.parent_atom_index, .{
+ try self.addReloc(reloc_info.parent.atom_index, .{
.target = undefined,
.offset = reloc_info.offset,
.addend = reloc_info.addend,
.type = .special_edata,
});
} else if (nav.name.eqlSlice("end", ip)) {
- try self.addReloc(reloc_info.parent_atom_index, .{
+ try self.addReloc(reloc_info.parent.atom_index, .{
.target = undefined,
.offset = reloc_info.offset,
.addend = reloc_info.addend,
@@ -1400,7 +1399,7 @@ pub fn getNavVAddr(
// otherwise, we just add a relocation
const atom_index = try self.seeNav(pt, nav_index);
// the parent_atom_index in this case is just the decl_index of the parent
- try self.addReloc(reloc_info.parent_atom_index, .{
+ try self.addReloc(reloc_info.parent.atom_index, .{
.target = atom_index,
.offset = reloc_info.offset,
.addend = reloc_info.addend,
@@ -1435,7 +1434,7 @@ pub fn lowerUav(
gop.value_ptr.* = index;
// we need to free name latex
var code_buffer = std.ArrayList(u8).init(gpa);
- const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
+ const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
const code = switch (res) {
.ok => code_buffer.items,
.fail => |em| return .{ .fail = em },
@@ -1459,7 +1458,7 @@ pub fn lowerUav(
pub fn getUavVAddr(self: *Plan9, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
const atom_index = self.uavs.get(uav).?;
- try self.addReloc(reloc_info.parent_atom_index, .{
+ try self.addReloc(reloc_info.parent.atom_index, .{
.target = atom_index,
.offset = reloc_info.offset,
.addend = reloc_info.addend,
diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig
index c0d531582f..afb0216fd7 100644
--- a/src/link/Wasm/ZigObject.zig
+++ b/src/link/Wasm/ZigObject.zig
@@ -277,8 +277,7 @@ pub fn updateNav(
zcu.navSrcLoc(nav_index),
nav_init,
&code_writer,
- .none,
- .{ .parent_atom_index = @intFromEnum(atom.sym_index) },
+ .{ .atom_index = @intFromEnum(atom.sym_index) },
);
const code = switch (res) {
@@ -520,10 +519,7 @@ fn lowerConst(
src_loc,
val,
&value_bytes,
- .none,
- .{
- .parent_atom_index = @intFromEnum(atom.sym_index),
- },
+ .{ .atom_index = @intFromEnum(atom.sym_index) },
);
break :code switch (result) {
.ok => value_bytes.items,
@@ -762,8 +758,11 @@ pub fn getNavVAddr(
else => {},
}
- std.debug.assert(reloc_info.parent_atom_index != 0);
- const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
+ std.debug.assert(reloc_info.parent.atom_index != 0);
+ const atom_index = wasm_file.symbol_atom.get(.{
+ .file = zig_object.index,
+ .index = @enumFromInt(reloc_info.parent.atom_index),
+ }).?;
const atom = wasm_file.getAtomPtr(atom_index);
const is_wasm32 = target.cpu.arch == .wasm32;
if (ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) {
@@ -800,7 +799,10 @@ pub fn getUavVAddr(
const atom_index = zig_object.uavs.get(uav).?;
const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
- const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
+ const parent_atom_index = wasm_file.symbol_atom.get(.{
+ .file = zig_object.index,
+ .index = @enumFromInt(reloc_info.parent.atom_index),
+ }).?;
const parent_atom = wasm_file.getAtomPtr(parent_atom_index);
const is_wasm32 = target.cpu.arch == .wasm32;
const zcu = wasm_file.base.comp.zcu.?;