authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-09-12 12:02:21-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-10-09 07:48:09-04:00
logc127c06fd73689987db6c336090d6432d9ee40a6
tree944e56368d388ce7d2f8073e35f5a28fa91be3d0
parentd354daf143525cda701e46473d7d2785ae4c05ab

Dwarf: implement and test lexical blocks


6 files changed, 226 insertions(+), 71 deletions(-)

src/arch/x86_64/CodeGen.zig+14-7
...@@ -2180,6 +2180,12 @@ fn checkInvariantsAfterAirInst(self: *Self, inst: Air.Inst.Index, old_air_bookke...@@ -2180,6 +2180,12 @@ fn checkInvariantsAfterAirInst(self: *Self, inst: Air.Inst.Index, old_air_bookke
2180 }2180 }
2181}2181}
21822182
2183fn genBodyBlock(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2184 try self.asmPseudo(.pseudo_dbg_enter_block_none);
2185 try self.genBody(body);
2186 try self.asmPseudo(.pseudo_dbg_leave_block_none);
2187}
2188
2183fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {2189fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2184 const pt = self.pt;2190 const pt = self.pt;
2185 const zcu = pt.zcu;2191 const zcu = pt.zcu;
...@@ -13184,7 +13190,7 @@ fn genTry(...@@ -13184,7 +13190,7 @@ fn genTry(
13184 const state = try self.saveState();13190 const state = try self.saveState();
1318513191
13186 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);13192 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);
13187 try self.genBody(body);13193 try self.genBodyBlock(body);
13188 try self.restoreState(state, &.{}, .{13194 try self.restoreState(state, &.{}, .{
13189 .emit_instructions = false,13195 .emit_instructions = false,
13190 .update_tracking = true,13196 .update_tracking = true,
...@@ -13293,7 +13299,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -13293,7 +13299,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
13293 const reloc = try self.genCondBrMir(cond_ty, cond);13299 const reloc = try self.genCondBrMir(cond_ty, cond);
1329413300
13295 for (liveness_cond_br.then_deaths) |death| try self.processDeath(death);13301 for (liveness_cond_br.then_deaths) |death| try self.processDeath(death);
13296 try self.genBody(then_body);13302 try self.genBodyBlock(then_body);
13297 try self.restoreState(state, &.{}, .{13303 try self.restoreState(state, &.{}, .{
13298 .emit_instructions = false,13304 .emit_instructions = false,
13299 .update_tracking = true,13305 .update_tracking = true,
...@@ -13304,7 +13310,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -13304,7 +13310,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
13304 self.performReloc(reloc);13310 self.performReloc(reloc);
1330513311
13306 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);13312 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);
13307 try self.genBody(else_body);13313 try self.genBodyBlock(else_body);
13308 try self.restoreState(state, &.{}, .{13314 try self.restoreState(state, &.{}, .{
13309 .emit_instructions = false,13315 .emit_instructions = false,
13310 .update_tracking = true,13316 .update_tracking = true,
...@@ -13665,14 +13671,16 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -13665,14 +13671,16 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
13665 });13671 });
13666 defer assert(self.loops.remove(inst));13672 defer assert(self.loops.remove(inst));
1366713673
13668 try self.genBody(body);13674 try self.genBodyBlock(body);
13669 self.finishAirBookkeeping();13675 self.finishAirBookkeeping();
13670}13676}
1367113677
13672fn airBlock(self: *Self, inst: Air.Inst.Index) !void {13678fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
13673 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;13679 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
13674 const extra = self.air.extraData(Air.Block, ty_pl.payload);13680 const extra = self.air.extraData(Air.Block, ty_pl.payload);
13681 try self.asmPseudo(.pseudo_dbg_enter_block_none);
13675 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));13682 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
13683 try self.asmPseudo(.pseudo_dbg_leave_block_none);
13676}13684}
1367713685
13678fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {13686fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
...@@ -13684,7 +13692,6 @@ fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !...@@ -13684,7 +13692,6 @@ fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !
13684 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });13692 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });
13685 const liveness = self.liveness.getBlock(inst);13693 const liveness = self.liveness.getBlock(inst);
1368613694
13687 // TODO emit debug info lexical block
13688 try self.genBody(body);13695 try self.genBody(body);
1368913696
13690 var block_data = self.blocks.fetchRemove(inst).?;13697 var block_data = self.blocks.fetchRemove(inst).?;
...@@ -13796,7 +13803,7 @@ fn lowerSwitchBr(self: *Self, inst: Air.Inst.Index, switch_br: Air.UnwrappedSwit...@@ -13796,7 +13803,7 @@ fn lowerSwitchBr(self: *Self, inst: Air.Inst.Index, switch_br: Air.UnwrappedSwit
1379613803
13797 // Relocate all success cases to the body we're about to generate.13804 // Relocate all success cases to the body we're about to generate.
13798 for (relocs) |reloc| self.performReloc(reloc);13805 for (relocs) |reloc| self.performReloc(reloc);
13799 try self.genBody(case.body);13806 try self.genBodyBlock(case.body);
13800 try self.restoreState(state, &.{}, .{13807 try self.restoreState(state, &.{}, .{
13801 .emit_instructions = false,13808 .emit_instructions = false,
13802 .update_tracking = true,13809 .update_tracking = true,
...@@ -13814,7 +13821,7 @@ fn lowerSwitchBr(self: *Self, inst: Air.Inst.Index, switch_br: Air.UnwrappedSwit...@@ -13814,7 +13821,7 @@ fn lowerSwitchBr(self: *Self, inst: Air.Inst.Index, switch_br: Air.UnwrappedSwit
13814 const else_deaths = liveness.deaths.len - 1;13821 const else_deaths = liveness.deaths.len - 1;
13815 for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand);13822 for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand);
1381613823
13817 try self.genBody(else_body);13824 try self.genBodyBlock(else_body);
13818 try self.restoreState(state, &.{}, .{13825 try self.restoreState(state, &.{}, .{
13819 .emit_instructions = false,13826 .emit_instructions = false,
13820 .update_tracking = true,13827 .update_tracking = true,
src/arch/x86_64/Emit.zig+24
...@@ -287,6 +287,30 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -287,6 +287,30 @@ pub fn emitMir(emit: *Emit) Error!void {
287 .none => {},287 .none => {},
288 }288 }
289 },289 },
290 .pseudo_dbg_enter_block_none => {
291 switch (emit.debug_output) {
292 .dwarf => |dw| {
293 log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
294 emit.prev_di_line, emit.prev_di_column,
295 });
296 try dw.enterBlock(emit.code.items.len);
297 },
298 .plan9 => {},
299 .none => {},
300 }
301 },
302 .pseudo_dbg_leave_block_none => {
303 switch (emit.debug_output) {
304 .dwarf => |dw| {
305 log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
306 emit.prev_di_line, emit.prev_di_column,
307 });
308 try dw.leaveBlock(emit.code.items.len);
309 },
310 .plan9 => {},
311 .none => {},
312 }
313 },
290 .pseudo_dbg_enter_inline_func => {314 .pseudo_dbg_enter_inline_func => {
291 switch (emit.debug_output) {315 switch (emit.debug_output) {
292 .dwarf => |dw| {316 .dwarf => |dw| {
src/arch/x86_64/Lower.zig+2
...@@ -312,6 +312,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -312,6 +312,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
312 .pseudo_dbg_prologue_end_none,312 .pseudo_dbg_prologue_end_none,
313 .pseudo_dbg_line_line_column,313 .pseudo_dbg_line_line_column,
314 .pseudo_dbg_epilogue_begin_none,314 .pseudo_dbg_epilogue_begin_none,
315 .pseudo_dbg_enter_block_none,
316 .pseudo_dbg_leave_block_none,
315 .pseudo_dbg_enter_inline_func,317 .pseudo_dbg_enter_inline_func,
316 .pseudo_dbg_leave_inline_func,318 .pseudo_dbg_leave_inline_func,
317 .pseudo_dbg_local_a,319 .pseudo_dbg_local_a,
src/arch/x86_64/Mir.zig+4
...@@ -935,6 +935,10 @@ pub const Inst = struct {...@@ -935,6 +935,10 @@ pub const Inst = struct {
935 pseudo_dbg_line_line_column,935 pseudo_dbg_line_line_column,
936 /// Start of epilogue936 /// Start of epilogue
937 pseudo_dbg_epilogue_begin_none,937 pseudo_dbg_epilogue_begin_none,
938 /// Start of lexical block
939 pseudo_dbg_enter_block_none,
940 /// End of lexical block
941 pseudo_dbg_leave_block_none,
938 /// Start of inline function942 /// Start of inline function
939 pseudo_dbg_enter_inline_func,943 pseudo_dbg_enter_inline_func,
940 /// End of inline function944 /// End of inline function
src/link/Dwarf.zig+95-64
...@@ -1374,10 +1374,11 @@ pub const WipNav = struct {...@@ -1374,10 +1374,11 @@ pub const WipNav = struct {
1374 any_children: bool,1374 any_children: bool,
1375 func: InternPool.Index,1375 func: InternPool.Index,
1376 func_sym_index: u32,1376 func_sym_index: u32,
1377 func_high_reloc: u32,1377 func_high_pc: u32,
1378 inlined_funcs: std.ArrayListUnmanaged(struct {1378 blocks: std.ArrayListUnmanaged(struct {
1379 abbrev_code: u32,1379 abbrev_code: u32,
1380 high_reloc: u32,1380 low_pc_off: u64,
1381 high_pc: u32,
1381 }),1382 }),
1382 cfi: struct {1383 cfi: struct {
1383 loc: u32,1384 loc: u32,
...@@ -1391,7 +1392,7 @@ pub const WipNav = struct {...@@ -1391,7 +1392,7 @@ pub const WipNav = struct {
13911392
1392 pub fn deinit(wip_nav: *WipNav) void {1393 pub fn deinit(wip_nav: *WipNav) void {
1393 const gpa = wip_nav.dwarf.gpa;1394 const gpa = wip_nav.dwarf.gpa;
1394 if (wip_nav.func != .none) wip_nav.inlined_funcs.deinit(gpa);1395 if (wip_nav.func != .none) wip_nav.blocks.deinit(gpa);
1395 wip_nav.debug_frame.deinit(gpa);1396 wip_nav.debug_frame.deinit(gpa);
1396 wip_nav.debug_info.deinit(gpa);1397 wip_nav.debug_info.deinit(gpa);
1397 wip_nav.debug_line.deinit(gpa);1398 wip_nav.debug_line.deinit(gpa);
...@@ -1486,49 +1487,72 @@ pub const WipNav = struct {...@@ -1486,49 +1487,72 @@ pub const WipNav = struct {
1486 try dlw.writeByte(DW.LNS.set_epilogue_begin);1487 try dlw.writeByte(DW.LNS.set_epilogue_begin);
1487 }1488 }
14881489
1489 pub fn enterInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64, line: u32, column: u32) UpdateError!void {1490 pub fn enterBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void {
1491 const dwarf = wip_nav.dwarf;
1492 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1493 const block = try wip_nav.blocks.addOne(dwarf.gpa);
1494
1495 block.abbrev_code = @intCast(wip_nav.debug_info.items.len);
1496 try wip_nav.abbrevCode(.block);
1497 block.low_pc_off = code_off;
1498 try wip_nav.infoAddrSym(wip_nav.func_sym_index, code_off);
1499 block.high_pc = @intCast(wip_nav.debug_info.items.len);
1500 try diw.writeInt(u32, 0, dwarf.endian);
1501 wip_nav.any_children = false;
1502 }
1503
1504 pub fn leaveBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void {
1505 const block_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.block));
1506 const block = wip_nav.blocks.pop();
1507 if (wip_nav.any_children)
1508 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
1509 else
1510 std.leb.writeUnsignedFixed(
1511 block_bytes,
1512 wip_nav.debug_info.items[block.abbrev_code..][0..block_bytes],
1513 try wip_nav.dwarf.refAbbrevCode(.empty_block),
1514 );
1515 std.mem.writeInt(u32, wip_nav.debug_info.items[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
1516 wip_nav.any_children = true;
1517 }
1518
1519 pub fn enterInlineFunc(
1520 wip_nav: *WipNav,
1521 func: InternPool.Index,
1522 code_off: u64,
1523 line: u32,
1524 column: u32,
1525 ) UpdateError!void {
1490 const dwarf = wip_nav.dwarf;1526 const dwarf = wip_nav.dwarf;
1491 const zcu = wip_nav.pt.zcu;1527 const zcu = wip_nav.pt.zcu;
1492 const diw = wip_nav.debug_info.writer(dwarf.gpa);1528 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1493 const inlined_func = try wip_nav.inlined_funcs.addOne(dwarf.gpa);1529 const block = try wip_nav.blocks.addOne(dwarf.gpa);
14941530
1495 inlined_func.abbrev_code = @intCast(wip_nav.debug_info.items.len);1531 block.abbrev_code = @intCast(wip_nav.debug_info.items.len);
1496 try wip_nav.abbrevCode(.inlined_func);1532 try wip_nav.abbrevCode(.inlined_func);
1497 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);1533 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
1498 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);1534 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1499 try uleb128(diw, column + 1);1535 try uleb128(diw, column + 1);
1500 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;1536 block.low_pc_off = code_off;
1501 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);1537 try wip_nav.infoAddrSym(wip_nav.func_sym_index, code_off);
1502 external_relocs.appendAssumeCapacity(.{1538 block.high_pc = @intCast(wip_nav.debug_info.items.len);
1503 .source_off = @intCast(wip_nav.debug_info.items.len),1539 try diw.writeInt(u32, 0, dwarf.endian);
1504 .target_sym = wip_nav.func_sym_index,
1505 .target_off = code_off,
1506 });
1507 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1508 inlined_func.high_reloc = @intCast(external_relocs.items.len);
1509 external_relocs.appendAssumeCapacity(.{
1510 .source_off = @intCast(wip_nav.debug_info.items.len),
1511 .target_sym = wip_nav.func_sym_index,
1512 .target_off = undefined,
1513 });
1514 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1515 try wip_nav.setInlineFunc(func);1540 try wip_nav.setInlineFunc(func);
1516 wip_nav.any_children = false;1541 wip_nav.any_children = false;
1517 }1542 }
15181543
1519 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {1544 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
1520 const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func));1545 const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func));
1521 const inlined_func = wip_nav.inlined_funcs.pop();1546 const block = wip_nav.blocks.pop();
1522 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
1523 external_relocs.items[inlined_func.high_reloc].target_off = code_off;
1524 if (wip_nav.any_children)1547 if (wip_nav.any_children)
1525 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))1548 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
1526 else1549 else
1527 std.leb.writeUnsignedFixed(1550 std.leb.writeUnsignedFixed(
1528 inlined_func_bytes,1551 inlined_func_bytes,
1529 wip_nav.debug_info.items[inlined_func.abbrev_code..][0..inlined_func_bytes],1552 wip_nav.debug_info.items[block.abbrev_code..][0..inlined_func_bytes],
1530 try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func),1553 try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func),
1531 );1554 );
1555 std.mem.writeInt(u32, wip_nav.debug_info.items[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
1532 try wip_nav.setInlineFunc(func);1556 try wip_nav.setInlineFunc(func);
1533 wip_nav.any_children = true;1557 wip_nav.any_children = true;
1534 }1558 }
...@@ -1664,17 +1688,18 @@ pub const WipNav = struct {...@@ -1664,17 +1688,18 @@ pub const WipNav = struct {
1664 return ctx.wip_nav.dwarf.endian;1688 return ctx.wip_nav.dwarf.endian;
1665 }1689 }
1666 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {1690 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {
1667 try ctx.wip_nav.infoAddrSym(sym_index);1691 try ctx.wip_nav.infoAddrSym(sym_index, 0);
1668 }1692 }
1669 } = .{ .wip_nav = wip_nav };1693 } = .{ .wip_nav = wip_nav };
1670 try uleb128(adapter.writer(), counter.stream.bytes_written);1694 try uleb128(adapter.writer(), counter.stream.bytes_written);
1671 try loc.write(adapter);1695 try loc.write(adapter);
1672 }1696 }
16731697
1674 fn infoAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void {1698 fn infoAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) UpdateError!void {
1675 try wip_nav.infoExternalReloc(.{1699 try wip_nav.infoExternalReloc(.{
1676 .source_off = @intCast(wip_nav.debug_info.items.len),1700 .source_off = @intCast(wip_nav.debug_info.items.len),
1677 .target_sym = sym_index,1701 .target_sym = sym_index,
1702 .target_off = sym_off,
1678 });1703 });
1679 try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));1704 try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
1680 }1705 }
...@@ -1695,17 +1720,18 @@ pub const WipNav = struct {...@@ -1695,17 +1720,18 @@ pub const WipNav = struct {
1695 return ctx.wip_nav.dwarf.endian;1720 return ctx.wip_nav.dwarf.endian;
1696 }1721 }
1697 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {1722 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {
1698 try ctx.wip_nav.frameAddrSym(sym_index);1723 try ctx.wip_nav.frameAddrSym(sym_index, 0);
1699 }1724 }
1700 } = .{ .wip_nav = wip_nav };1725 } = .{ .wip_nav = wip_nav };
1701 try uleb128(adapter.writer(), counter.stream.bytes_written);1726 try uleb128(adapter.writer(), counter.stream.bytes_written);
1702 try loc.write(adapter);1727 try loc.write(adapter);
1703 }1728 }
17041729
1705 fn frameAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void {1730 fn frameAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) UpdateError!void {
1706 try wip_nav.frameExternalReloc(.{1731 try wip_nav.frameExternalReloc(.{
1707 .source_off = @intCast(wip_nav.debug_frame.items.len),1732 .source_off = @intCast(wip_nav.debug_frame.items.len),
1708 .target_sym = sym_index,1733 .target_sym = sym_index,
1734 .target_off = sym_off,
1709 });1735 });
1710 try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));1736 try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
1711 }1737 }
...@@ -2150,8 +2176,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -2150,8 +2176,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
2150 .any_children = false,2176 .any_children = false,
2151 .func = .none,2177 .func = .none,
2152 .func_sym_index = undefined,2178 .func_sym_index = undefined,
2153 .func_high_reloc = undefined,2179 .func_high_pc = undefined,
2154 .inlined_funcs = undefined,2180 .blocks = undefined,
2155 .cfi = undefined,2181 .cfi = undefined,
2156 .debug_frame = .{},2182 .debug_frame = .{},
2157 .debug_info = .{},2183 .debug_info = .{},
...@@ -2294,7 +2320,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -2294,7 +2320,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
2294 const func_type = ip.indexToKey(func.ty).func_type;2320 const func_type = ip.indexToKey(func.ty).func_type;
2295 wip_nav.func = nav_val.toIntern();2321 wip_nav.func = nav_val.toIntern();
2296 wip_nav.func_sym_index = sym_index;2322 wip_nav.func_sym_index = sym_index;
2297 wip_nav.inlined_funcs = .{};2323 wip_nav.blocks = .{};
2298 if (dwarf.debug_frame.header.format != .none) wip_nav.cfi = .{2324 if (dwarf.debug_frame.header.format != .none) wip_nav.cfi = .{
2299 .loc = 0,2325 .loc = 0,
2300 .cfa = dwarf.debug_frame.header.initial_instructions[0].def_cfa,2326 .cfa = dwarf.debug_frame.header.initial_instructions[0].def_cfa,
...@@ -2319,7 +2345,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -2319,7 +2345,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
2319 .source_off = @intCast(wip_nav.debug_frame.items.len),2345 .source_off = @intCast(wip_nav.debug_frame.items.len),
2320 });2346 });
2321 try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes());2347 try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
2322 try wip_nav.frameAddrSym(sym_index);2348 try wip_nav.frameAddrSym(sym_index, 0);
2323 try dfw.writeByteNTimes(undefined, @intFromEnum(dwarf.address_size));2349 try dfw.writeByteNTimes(undefined, @intFromEnum(dwarf.address_size));
2324 },2350 },
2325 .eh_frame => {2351 .eh_frame => {
...@@ -2346,20 +2372,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -2346,20 +2372,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
2346 try wip_nav.strp(nav.name.toSlice(ip));2372 try wip_nav.strp(nav.name.toSlice(ip));
2347 try wip_nav.strp(nav.fqn.toSlice(ip));2373 try wip_nav.strp(nav.fqn.toSlice(ip));
2348 try wip_nav.refType(Type.fromInterned(func_type.return_type));2374 try wip_nav.refType(Type.fromInterned(func_type.return_type));
2349 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;2375 try wip_nav.infoAddrSym(sym_index, 0);
2350 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);2376 wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len);
2351 external_relocs.appendAssumeCapacity(.{2377 try diw.writeInt(u32, 0, dwarf.endian);
2352 .source_off = @intCast(wip_nav.debug_info.items.len),
2353 .target_sym = sym_index,
2354 });
2355 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
2356 wip_nav.func_high_reloc = @intCast(external_relocs.items.len);
2357 external_relocs.appendAssumeCapacity(.{
2358 .source_off = @intCast(wip_nav.debug_info.items.len),
2359 .target_sym = sym_index,
2360 .target_off = undefined,
2361 });
2362 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
2363 try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse2378 try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
2364 target_info.defaultFunctionAlignment(file.mod.resolved_target.result).toByteUnits().?);2379 target_info.defaultFunctionAlignment(file.mod.resolved_target.result).toByteUnits().?);
2365 try diw.writeByte(@intFromBool(false));2380 try diw.writeByte(@intFromBool(false));
...@@ -2466,8 +2481,7 @@ pub fn finishWipNav(...@@ -2466,8 +2481,7 @@ pub fn finishWipNav(
2466 },2481 },
2467 }2482 }
2468 {2483 {
2469 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;2484 std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(sym.size), dwarf.endian);
2470 external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size;
2471 if (wip_nav.any_children) {2485 if (wip_nav.any_children) {
2472 const diw = wip_nav.debug_info.writer(dwarf.gpa);2486 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2473 try uleb128(diw, @intFromEnum(AbbrevCode.null));2487 try uleb128(diw, @intFromEnum(AbbrevCode.null));
...@@ -2562,8 +2576,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2562,8 +2576,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2562 .any_children = false,2576 .any_children = false,
2563 .func = .none,2577 .func = .none,
2564 .func_sym_index = undefined,2578 .func_sym_index = undefined,
2565 .func_high_reloc = undefined,2579 .func_high_pc = undefined,
2566 .inlined_funcs = undefined,2580 .blocks = undefined,
2567 .cfi = undefined,2581 .cfi = undefined,
2568 .debug_frame = .{},2582 .debug_frame = .{},
2569 .debug_info = .{},2583 .debug_info = .{},
...@@ -3036,8 +3050,8 @@ fn updateType(...@@ -3036,8 +3050,8 @@ fn updateType(
3036 .any_children = false,3050 .any_children = false,
3037 .func = .none,3051 .func = .none,
3038 .func_sym_index = undefined,3052 .func_sym_index = undefined,
3039 .func_high_reloc = undefined,3053 .func_high_pc = undefined,
3040 .inlined_funcs = undefined,3054 .blocks = undefined,
3041 .cfi = undefined,3055 .cfi = undefined,
3042 .debug_frame = .{},3056 .debug_frame = .{},
3043 .debug_info = .{},3057 .debug_info = .{},
...@@ -3480,8 +3494,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3480,8 +3494,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3480 .any_children = false,3494 .any_children = false,
3481 .func = .none,3495 .func = .none,
3482 .func_sym_index = undefined,3496 .func_sym_index = undefined,
3483 .func_high_reloc = undefined,3497 .func_high_pc = undefined,
3484 .inlined_funcs = undefined,3498 .blocks = undefined,
3485 .cfi = undefined,3499 .cfi = undefined,
3486 .debug_frame = .{},3500 .debug_frame = .{},
3487 .debug_info = .{},3501 .debug_info = .{},
...@@ -3553,8 +3567,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3553,8 +3567,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3553 .any_children = false,3567 .any_children = false,
3554 .func = .none,3568 .func = .none,
3555 .func_sym_index = undefined,3569 .func_sym_index = undefined,
3556 .func_high_reloc = undefined,3570 .func_high_pc = undefined,
3557 .inlined_funcs = undefined,3571 .blocks = undefined,
3558 .cfi = undefined,3572 .cfi = undefined,
3559 .debug_frame = .{},3573 .debug_frame = .{},
3560 .debug_info = .{},3574 .debug_info = .{},
...@@ -3756,8 +3770,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3756,8 +3770,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3756 .any_children = false,3770 .any_children = false,
3757 .func = .none,3771 .func = .none,
3758 .func_sym_index = undefined,3772 .func_sym_index = undefined,
3759 .func_high_reloc = undefined,3773 .func_high_pc = undefined,
3760 .inlined_funcs = undefined,3774 .blocks = undefined,
3761 .cfi = undefined,3775 .cfi = undefined,
3762 .debug_frame = .{},3776 .debug_frame = .{},
3763 .debug_info = .{},3777 .debug_info = .{},
...@@ -4212,6 +4226,8 @@ const AbbrevCode = enum {...@@ -4212,6 +4226,8 @@ const AbbrevCode = enum {
4212 empty_packed_struct_type,4226 empty_packed_struct_type,
4213 union_type,4227 union_type,
4214 empty_union_type,4228 empty_union_type,
4229 empty_block,
4230 block,
4215 empty_inlined_func,4231 empty_inlined_func,
4216 inlined_func,4232 inlined_func,
4217 local_arg,4233 local_arg,
...@@ -4319,7 +4335,7 @@ const AbbrevCode = enum {...@@ -4319,7 +4335,7 @@ const AbbrevCode = enum {
4319 .{ .linkage_name, .strp },4335 .{ .linkage_name, .strp },
4320 .{ .type, .ref_addr },4336 .{ .type, .ref_addr },
4321 .{ .low_pc, .addr },4337 .{ .low_pc, .addr },
4322 .{ .high_pc, .addr },4338 .{ .high_pc, .data4 },
4323 .{ .alignment, .udata },4339 .{ .alignment, .udata },
4324 .{ .external, .flag },4340 .{ .external, .flag },
4325 .{ .noreturn, .flag },4341 .{ .noreturn, .flag },
...@@ -4331,7 +4347,7 @@ const AbbrevCode = enum {...@@ -4331,7 +4347,7 @@ const AbbrevCode = enum {
4331 .{ .linkage_name, .strp },4347 .{ .linkage_name, .strp },
4332 .{ .type, .ref_addr },4348 .{ .type, .ref_addr },
4333 .{ .low_pc, .addr },4349 .{ .low_pc, .addr },
4334 .{ .high_pc, .addr },4350 .{ .high_pc, .data4 },
4335 .{ .alignment, .udata },4351 .{ .alignment, .udata },
4336 .{ .external, .flag },4352 .{ .external, .flag },
4337 .{ .noreturn, .flag },4353 .{ .noreturn, .flag },
...@@ -4672,6 +4688,21 @@ const AbbrevCode = enum {...@@ -4672,6 +4688,21 @@ const AbbrevCode = enum {
4672 .{ .alignment, .udata },4688 .{ .alignment, .udata },
4673 },4689 },
4674 },4690 },
4691 .empty_block = .{
4692 .tag = .lexical_block,
4693 .attrs = &.{
4694 .{ .low_pc, .addr },
4695 .{ .high_pc, .data4 },
4696 },
4697 },
4698 .block = .{
4699 .tag = .lexical_block,
4700 .children = true,
4701 .attrs = &.{
4702 .{ .low_pc, .addr },
4703 .{ .high_pc, .data4 },
4704 },
4705 },
4675 .empty_inlined_func = .{4706 .empty_inlined_func = .{
4676 .tag = .inlined_subroutine,4707 .tag = .inlined_subroutine,
4677 .attrs = &.{4708 .attrs = &.{
...@@ -4679,7 +4710,7 @@ const AbbrevCode = enum {...@@ -4679,7 +4710,7 @@ const AbbrevCode = enum {
4679 .{ .call_line, .udata },4710 .{ .call_line, .udata },
4680 .{ .call_column, .udata },4711 .{ .call_column, .udata },
4681 .{ .low_pc, .addr },4712 .{ .low_pc, .addr },
4682 .{ .high_pc, .addr },4713 .{ .high_pc, .data4 },
4683 },4714 },
4684 },4715 },
4685 .inlined_func = .{4716 .inlined_func = .{
...@@ -4690,7 +4721,7 @@ const AbbrevCode = enum {...@@ -4690,7 +4721,7 @@ const AbbrevCode = enum {
4690 .{ .call_line, .udata },4721 .{ .call_line, .udata },
4691 .{ .call_column, .udata },4722 .{ .call_column, .udata },
4692 .{ .low_pc, .addr },4723 .{ .low_pc, .addr },
4693 .{ .high_pc, .addr },4724 .{ .high_pc, .data4 },
4694 },4725 },
4695 },4726 },
4696 .local_arg = .{4727 .local_arg = .{
test/src/Debugger.zig+87
...@@ -721,6 +721,93 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -721,6 +721,93 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
721 \\1 breakpoints deleted; 0 breakpoint locations disabled.721 \\1 breakpoints deleted; 0 breakpoint locations disabled.
722 },722 },
723 );723 );
724 db.addLldbTest(
725 "if_blocks",
726 target,
727 &.{
728 .{
729 .path = "if_blocks.zig",
730 .source =
731 \\pub fn main() void {
732 \\ for (0..2) |i| {
733 \\ if (i == 0) {
734 \\ var x: u32 = 123;
735 \\ _ = &x;
736 \\ } else {
737 \\ var x: f32 = 4.5;
738 \\ _ = &x;
739 \\ }
740 \\ }
741 \\}
742 \\
743 ,
744 },
745 },
746 \\breakpoint set --file if_blocks.zig --source-pattern-regexp '_ = &x;'
747 \\process launch
748 \\frame variable
749 \\process continue
750 \\frame variable
751 \\breakpoint delete --force 1
752 ,
753 &.{
754 \\(lldb) frame variable
755 \\(usize) i = 0
756 \\(u32) x = 123
757 \\(lldb) process continue
758 ,
759 \\(lldb) frame variable
760 \\(usize) i = 1
761 \\(f32) x = 4.5
762 \\(lldb) breakpoint delete --force 1
763 \\1 breakpoints deleted; 0 breakpoint locations disabled.
764 },
765 );
766 db.addLldbTest(
767 "switch_blocks",
768 target,
769 &.{
770 .{
771 .path = "switch_blocks.zig",
772 .source =
773 \\pub fn main() void {
774 \\ for (0..2) |i| {
775 \\ switch (i) {
776 \\ 0 => {
777 \\ var x: u32 = 123;
778 \\ _ = &x;
779 \\ },
780 \\ else => {
781 \\ var x: f32 = 4.5;
782 \\ _ = &x;
783 \\ },
784 \\ }
785 \\ }
786 \\}
787 \\
788 ,
789 },
790 },
791 \\breakpoint set --file switch_blocks.zig --source-pattern-regexp '_ = &x;'
792 \\process launch
793 \\frame variable
794 \\process continue
795 \\frame variable
796 \\breakpoint delete --force 1
797 ,
798 &.{
799 \\(lldb) frame variable
800 \\(usize) i = 0
801 \\(u32) x = 123
802 \\(lldb) process continue
803 ,
804 \\(lldb) frame variable
805 \\(usize) i = 1
806 \\(f32) x = 4.5
807 \\(lldb) breakpoint delete --force 1
808 \\1 breakpoints deleted; 0 breakpoint locations disabled.
809 },
810 );
724 db.addLldbTest(811 db.addLldbTest(
725 "inline_call",812 "inline_call",
726 target,813 target,