Skip to content

Commit aeaffd4

Browse files
committed
x86: fix generating debug info for variables
Add handling for these additional `MCValue`s: * `.immediate` - lower to `DW.OP.consts` or `DW.OP.constu` depending on signedness followed by popping off the DWARF stack with `DW.OP.stack_value` * `.undef` - lower to `DW.OP.implicit_value` * `.none` - lower to `DW.OP.lit0` followed by popping off the DWARF stack with `DW.OP.stack_value` For any remaining unhandled case, we generate `DW.OP.nop` in order not to mess up remaining DWARF info.
1 parent f2f1bb7 commit aeaffd4

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4370,6 +4370,7 @@ fn genVarDbgInfo(
43704370
.dwarf => |dw| {
43714371
const dbg_info = &dw.dbg_info;
43724372
try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
4373+
const endian = self.target.cpu.arch.endian();
43734374

43744375
switch (mcv) {
43754376
.register => |reg| {
@@ -4390,7 +4391,6 @@ fn genVarDbgInfo(
43904391
dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
43914392
},
43924393
.memory, .got_load, .direct_load => {
4393-
const endian = self.target.cpu.arch.endian();
43944394
const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8));
43954395
const is_ptr = switch (tag) {
43964396
.dbg_var_ptr => true,
@@ -4425,7 +4425,53 @@ fn genVarDbgInfo(
44254425
else => {},
44264426
}
44274427
},
4428+
.immediate => |x| {
4429+
const signedness: std.builtin.Signedness = blk: {
4430+
if (ty.zigTypeTag() != .Int) break :blk .unsigned;
4431+
break :blk ty.intInfo(self.target.*).signedness;
4432+
};
4433+
try dbg_info.ensureUnusedCapacity(2);
4434+
const fixup = dbg_info.items.len;
4435+
dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
4436+
1,
4437+
switch (signedness) {
4438+
.signed => DW.OP.consts,
4439+
.unsigned => DW.OP.constu,
4440+
},
4441+
});
4442+
switch (signedness) {
4443+
.signed => try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)),
4444+
.unsigned => try leb128.writeULEB128(dbg_info.writer(), x),
4445+
}
4446+
try dbg_info.append(DW.OP.stack_value);
4447+
dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
4448+
},
4449+
.undef => {
4450+
// DW.AT.location, DW.FORM.exprloc
4451+
// uleb128(exprloc_len)
4452+
// DW.OP.implicit_value uleb128(len_of_bytes) bytes
4453+
const abi_size = @intCast(u32, ty.abiSize(self.target.*));
4454+
var implicit_value_len = std.ArrayList(u8).init(self.gpa);
4455+
defer implicit_value_len.deinit();
4456+
try leb128.writeULEB128(implicit_value_len.writer(), abi_size);
4457+
const total_exprloc_len = 1 + implicit_value_len.items.len + abi_size;
4458+
try leb128.writeULEB128(dbg_info.writer(), total_exprloc_len);
4459+
try dbg_info.ensureUnusedCapacity(total_exprloc_len);
4460+
dbg_info.appendAssumeCapacity(DW.OP.implicit_value);
4461+
dbg_info.appendSliceAssumeCapacity(implicit_value_len.items);
4462+
dbg_info.appendNTimesAssumeCapacity(0xaa, abi_size);
4463+
},
4464+
.none => {
4465+
try dbg_info.ensureUnusedCapacity(3);
4466+
dbg_info.appendSliceAssumeCapacity(&[3]u8{ // DW.AT.location, DW.FORM.exprloc
4467+
2, DW.OP.lit0, DW.OP.stack_value,
4468+
});
4469+
},
44284470
else => {
4471+
try dbg_info.ensureUnusedCapacity(2);
4472+
dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
4473+
1, DW.OP.nop,
4474+
});
44294475
log.debug("TODO generate debug info for {}", .{mcv});
44304476
},
44314477
}

src/link/Dwarf.zig

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub const DeclState = struct {
102102
}
103103

104104
pub fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
105-
log.debug("{x}: target sym @{d}, via GOT {}", .{ offset, target, is_ptr });
105+
log.debug("{x}: target sym %{d}, via GOT {}", .{ offset, target, is_ptr });
106106
try self.exprloc_relocs.append(self.gpa, .{
107107
.@"type" = if (is_ptr) .got_load else .direct_load,
108108
.target = target,
@@ -135,15 +135,15 @@ pub const DeclState = struct {
135135
.@"type" = ty,
136136
.offset = undefined,
137137
});
138-
log.debug("@{d}: {}", .{ sym_index, ty.fmtDebug() });
138+
log.debug("%{d}: {}", .{ sym_index, ty.fmtDebug() });
139139
try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{
140140
.mod = self.mod,
141141
});
142142
break :blk self.abbrev_resolver.getContext(ty, .{
143143
.mod = self.mod,
144144
}).?;
145145
};
146-
log.debug("{x}: @{d} + 0", .{ offset, resolv });
146+
log.debug("{x}: %{d} + 0", .{ offset, resolv });
147147
try self.abbrev_relocs.append(self.gpa, .{
148148
.target = resolv,
149149
.atom = atom,
@@ -1056,17 +1056,20 @@ pub fn commitDeclState(
10561056
break :blk false;
10571057
};
10581058
if (deferred) {
1059+
log.debug("resolving %{d} deferred until flush", .{target});
10591060
try self.global_abbrev_relocs.append(gpa, .{
10601061
.target = null,
10611062
.offset = reloc.offset,
10621063
.atom = reloc.atom,
10631064
.addend = reloc.addend,
10641065
});
10651066
} else {
1067+
const value = symbol.atom.off + symbol.offset + reloc.addend;
1068+
log.debug("{x}: [() => {x}] (%{d}, '{}')", .{ reloc.offset, value, target, ty.fmtDebug() });
10661069
mem.writeInt(
10671070
u32,
10681071
dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
1069-
symbol.atom.off + symbol.offset + reloc.addend,
1072+
value,
10701073
target_endian,
10711074
);
10721075
}

0 commit comments

Comments
 (0)