Skip to content

Commit bfe8a4d

Browse files
authored
Merge pull request #12425 from ziglang/dwarf-fixes
x86: fix generating debug info for variables
2 parents 92568a0 + aeaffd4 commit bfe8a4d

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
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: 8 additions & 5 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
}
@@ -1259,7 +1262,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
12591262
debug_info_sect.addr = dwarf_segment.vmaddr + new_offset - dwarf_segment.fileoff;
12601263
}
12611264
debug_info_sect.size = needed_size;
1262-
d_sym.debug_line_header_dirty = true;
1265+
d_sym.debug_info_header_dirty = true;
12631266
}
12641267
const file_pos = debug_info_sect.offset + atom.off;
12651268
try pwriteDbgInfoNops(

src/link/MachO/DebugSymbols.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,16 @@ pub const Reloc = struct {
6363
pub fn populateMissingMetadata(self: *DebugSymbols, allocator: Allocator) !void {
6464
if (self.linkedit_segment_cmd_index == null) {
6565
self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len);
66-
log.debug("found __LINKEDIT segment free space 0x{x} to 0x{x}", .{
67-
self.base.page_size,
68-
self.base.page_size * 2,
69-
});
66+
const fileoff = @intCast(u64, self.base.page_size);
67+
const needed_size = @intCast(u64, self.base.page_size) * 2;
68+
log.debug("found __LINKEDIT segment free space 0x{x} to 0x{x}", .{ fileoff, needed_size });
7069
// TODO this needs reworking
7170
try self.segments.append(allocator, .{
7271
.segname = makeStaticString("__LINKEDIT"),
73-
.vmaddr = self.base.page_size,
74-
.vmsize = self.base.page_size,
75-
.fileoff = self.base.page_size,
76-
.filesize = self.base.page_size,
72+
.vmaddr = fileoff,
73+
.vmsize = needed_size,
74+
.fileoff = fileoff,
75+
.filesize = needed_size,
7776
.maxprot = macho.PROT.READ,
7877
.initprot = macho.PROT.READ,
7978
.cmdsize = @sizeOf(macho.segment_command_64),
@@ -284,6 +283,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti
284283
const lc_writer = lc_buffer.writer();
285284
var ncmds: u32 = 0;
286285

286+
self.updateDwarfSegment();
287287
try self.writeLinkeditSegmentData(&ncmds, lc_writer);
288288
self.updateDwarfSegment();
289289

0 commit comments

Comments
 (0)