authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-19 22:16:20-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-20 15:08:23-04:00
logeaa227449c894a9205d63c2e963b967d13446591
tree706fb67c264173754b3b99f5c816e042eb54d57f
parent62f7276501bee7460cd004c17fdc1545487ad99b

Dwarf: fix issues with inline call sites


10 files changed, 337 insertions(+), 173 deletions(-)

src/Zcu/PerThread.zig+14-15
......@@ -1240,14 +1240,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
12401240 };
12411241 }
12421242
1243 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1244 .func => |f| status: {
1245 const func_type = ip.indexToKey(f.ty).func_type;
1246 break :status .{ f.owner_nav == nav_index, func_type.is_generic or func_type.cc == .Inline };
1247 },
1248 .variable => |v| .{ false, v.owner_nav == nav_index },
1249 .@"extern" => .{ false, false },
1250 else => .{ false, true },
1243 const nav_already_populated, const queue_linker_work, const resolve_type = switch (ip.indexToKey(decl_val.toIntern())) {
1244 .func => |f| .{ f.owner_nav == nav_index, true, false },
1245 .variable => |v| .{ false, v.owner_nav == nav_index, true },
1246 .@"extern" => .{ false, false, false },
1247 else => .{ false, true, true },
12511248 };
12521249
12531250 if (nav_already_populated) {
......@@ -1320,14 +1317,16 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
13201317 queue_codegen: {
13211318 if (!queue_linker_work) break :queue_codegen;
13221319
1323 // Needed for codegen_nav which will call updateDecl and then the
1324 // codegen backend wants full access to the Decl Type.
1325 // We also need this for the `isFnOrHasRuntimeBits` check below.
1326 // TODO: we could make the language more lenient by deferring this work
1327 // to the `codegen_nav` job.
1328 try decl_ty.resolveFully(pt);
1320 if (resolve_type) {
1321 // Needed for codegen_nav which will call updateDecl and then the
1322 // codegen backend wants full access to the Decl Type.
1323 // We also need this for the `isFnOrHasRuntimeBits` check below.
1324 // TODO: we could make the language more lenient by deferring this work
1325 // to the `codegen_nav` job.
1326 try decl_ty.resolveFully(pt);
1327 }
13291328
1330 if (!decl_ty.isFnOrHasRuntimeBits(pt)) {
1329 if (!resolve_type or !decl_ty.hasRuntimeBits(pt)) {
13311330 if (zcu.comp.config.use_llvm) break :queue_codegen;
13321331 if (file.mod.strip) break :queue_codegen;
13331332 }
src/arch/x86_64/CodeGen.zig+4
......@@ -12033,6 +12033,10 @@ fn genLocalDebugInfo(
1203312033 .disp = sym_off.off,
1203412034 } },
1203512035 }),
12036 .lea_direct, .lea_got, .lea_tlv => |sym| try self.asmAirMemory(.dbg_local, inst, .{
12037 .base = .{ .reloc = .{ .atom_index = undefined, .sym_index = sym } },
12038 .mod = .{ .rm = .{ .size = .qword } },
12039 }),
1203612040 },
1203712041 }
1203812042}
src/link/C.zig+11-1
......@@ -317,8 +317,18 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !
317317 defer tracy.end();
318318
319319 const gpa = self.base.comp.gpa;
320
321320 const zcu = pt.zcu;
321 const ip = &zcu.intern_pool;
322
323 const nav = ip.getNav(nav_index);
324 const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) {
325 .func => return,
326 .@"extern" => .none,
327 .variable => |variable| variable.init,
328 else => nav.status.resolved.val,
329 };
330 if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) return;
331
322332 const gop = try self.navs.getOrPut(gpa, nav_index);
323333 errdefer _ = self.navs.pop();
324334 if (!gop.found_existing) gop.value_ptr.* = .{};
src/link/Coff.zig+2-1
......@@ -1207,6 +1207,7 @@ pub fn updateNav(
12071207
12081208 const nav_val = zcu.navValue(nav_index);
12091209 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1210 .func => return,
12101211 .variable => |variable| Value.fromInterned(variable.init),
12111212 .@"extern" => |@"extern"| {
12121213 if (ip.isFunctionType(@"extern".ty)) return;
......@@ -1220,7 +1221,7 @@ pub fn updateNav(
12201221 else => nav_val,
12211222 };
12221223
1223 if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) {
1224 if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) {
12241225 const atom_index = try self.getOrCreateAtomForNav(nav_index);
12251226 Atom.freeRelocations(self, atom_index);
12261227 const atom = self.getAtom(atom_index);
src/link/Dwarf.zig+217-129
......@@ -21,8 +21,9 @@ pub const UpdateError =
2121 std.fs.File.OpenError ||
2222 std.fs.File.SetEndPosError ||
2323 std.fs.File.CopyRangeError ||
24 std.fs.File.PReadError ||
2425 std.fs.File.PWriteError ||
25 error{ Overflow, Underflow, UnexpectedEndOfFile };
26 error{ EndOfStream, Overflow, Underflow, UnexpectedEndOfFile };
2627
2728pub const FlushError =
2829 UpdateError ||
......@@ -253,10 +254,8 @@ const Section = struct {
253254 .trailer_len = trailer_len,
254255 .len = header_len + trailer_len,
255256 .entries = .{},
256 .cross_entry_relocs = .{},
257257 .cross_unit_relocs = .{},
258258 .cross_section_relocs = .{},
259 .external_relocs = .{},
260259 };
261260 if (sec.last.unwrap()) |last_unit| {
262261 const last_unit_ptr = sec.getUnit(last_unit);
......@@ -358,10 +357,8 @@ const Unit = struct {
358357 /// data length in bytes
359358 len: u32,
360359 entries: std.ArrayListUnmanaged(Entry),
361 cross_entry_relocs: std.ArrayListUnmanaged(CrossEntryReloc),
362360 cross_unit_relocs: std.ArrayListUnmanaged(CrossUnitReloc),
363361 cross_section_relocs: std.ArrayListUnmanaged(CrossSectionReloc),
364 external_relocs: std.ArrayListUnmanaged(ExternalReloc),
365362
366363 const Index = enum(u32) {
367364 main,
......@@ -381,12 +378,16 @@ const Unit = struct {
381378 }
382379 };
383380
381 fn clear(unit: *Unit) void {
382 unit.cross_unit_relocs.clearRetainingCapacity();
383 unit.cross_section_relocs.clearRetainingCapacity();
384 }
385
384386 fn deinit(unit: *Unit, gpa: std.mem.Allocator) void {
387 for (unit.entries.items) |*entry| entry.deinit(gpa);
385388 unit.entries.deinit(gpa);
386 unit.cross_entry_relocs.deinit(gpa);
387389 unit.cross_unit_relocs.deinit(gpa);
388390 unit.cross_section_relocs.deinit(gpa);
389 unit.external_relocs.deinit(gpa);
390391 unit.* = undefined;
391392 }
392393
......@@ -398,6 +399,10 @@ const Unit = struct {
398399 .next = .none,
399400 .off = 0,
400401 .len = 0,
402 .cross_entry_relocs = .{},
403 .cross_unit_relocs = .{},
404 .cross_section_relocs = .{},
405 .external_relocs = .{},
401406 };
402407 if (unit.last.unwrap()) |last_entry| {
403408 const last_entry_ptr = unit.getEntry(last_entry);
......@@ -451,6 +456,14 @@ const Unit = struct {
451456 unit_ptr.len = len;
452457 }
453458
459 fn trim(unit: *Unit) void {
460 const len = unit.getEntry(unit.first.unwrap() orelse return).off;
461 if (len == 0) return;
462 for (unit.entries.items) |*entry| entry.off -= len;
463 unit.off += len;
464 unit.len -= len;
465 }
466
454467 fn move(unit: *Unit, sec: *Section, dwarf: *Dwarf, new_off: u32) UpdateError!void {
455468 if (unit.off == new_off) return;
456469 if (try dwarf.getFile().?.copyRangeAll(
......@@ -463,6 +476,7 @@ const Unit = struct {
463476 }
464477
465478 fn resizeHeader(unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void {
479 unit.trim();
466480 if (unit.header_len == len) return;
467481 const available_len = if (unit.prev.unwrap()) |prev_unit| prev_excess: {
468482 const prev_unit_ptr = sec.getUnit(prev_unit);
......@@ -535,23 +549,11 @@ const Unit = struct {
535549 }
536550
537551 fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void {
538 for (unit.cross_entry_relocs.items) |reloc| {
539 try dwarf.resolveReloc(
540 sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry|
541 unit.header_len + unit.getEntry(source_entry).off
542 else
543 0) + reloc.source_off,
544 unit.off + unit.header_len + unit.getEntry(reloc.target_entry).assertNonEmpty(unit, sec, dwarf).off + reloc.target_off,
545 dwarf.sectionOffsetBytes(),
546 );
547 }
552 const unit_off = sec.off + unit.off;
548553 for (unit.cross_unit_relocs.items) |reloc| {
549554 const target_unit = sec.getUnit(reloc.target_unit);
550555 try dwarf.resolveReloc(
551 sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry|
552 unit.header_len + unit.getEntry(source_entry).off
553 else
554 0) + reloc.source_off,
556 unit_off + reloc.source_off,
555557 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
556558 target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
557559 else
......@@ -565,10 +567,7 @@ const Unit = struct {
565567 };
566568 const target_unit = target_sec.getUnit(reloc.target_unit);
567569 try dwarf.resolveReloc(
568 sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry|
569 unit.header_len + unit.getEntry(source_entry).off
570 else
571 0) + reloc.source_off,
570 unit_off + reloc.source_off,
572571 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
573572 target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
574573 else
......@@ -576,57 +575,8 @@ const Unit = struct {
576575 dwarf.sectionOffsetBytes(),
577576 );
578577 }
579 if (dwarf.bin_file.cast(.elf)) |elf_file| {
580 const zo = elf_file.zigObjectPtr().?;
581 for (unit.external_relocs.items) |reloc| {
582 const symbol = zo.symbol(reloc.target_sym);
583 try dwarf.resolveReloc(
584 sec.off + unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off,
585 @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(reloc.target_off)) -
586 if (symbol.flags.is_tls) elf_file.dtpAddress() else 0),
587 @intFromEnum(dwarf.address_size),
588 );
589 }
590 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
591 const zo = macho_file.getZigObject().?;
592 for (unit.external_relocs.items) |reloc| {
593 const ref = zo.getSymbolRef(reloc.target_sym, macho_file);
594 try dwarf.resolveReloc(
595 sec.off + unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off,
596 ref.getSymbol(macho_file).?.getAddress(.{}, macho_file),
597 @intFromEnum(dwarf.address_size),
598 );
599 }
600 }
578 for (unit.entries.items) |*entry| try entry.resolveRelocs(unit, sec, dwarf);
601579 }
602
603 const CrossEntryReloc = struct {
604 source_entry: Entry.Index.Optional = .none,
605 source_off: u32 = 0,
606 target_entry: Entry.Index,
607 target_off: u32 = 0,
608 };
609 const CrossUnitReloc = struct {
610 source_entry: Entry.Index.Optional = .none,
611 source_off: u32 = 0,
612 target_unit: Unit.Index,
613 target_entry: Entry.Index.Optional = .none,
614 target_off: u32 = 0,
615 };
616 const CrossSectionReloc = struct {
617 source_entry: Entry.Index.Optional = .none,
618 source_off: u32 = 0,
619 target_sec: Section.Index,
620 target_unit: Unit.Index,
621 target_entry: Entry.Index.Optional = .none,
622 target_off: u32 = 0,
623 };
624 const ExternalReloc = struct {
625 source_entry: Entry.Index,
626 source_off: u32 = 0,
627 target_sym: u32,
628 target_off: u64 = 0,
629 };
630580};
631581
632582/// An indivisible entry within a `Unit` containing section-specific data.
......@@ -637,6 +587,25 @@ const Entry = struct {
637587 off: u32,
638588 /// data length in bytes
639589 len: u32,
590 cross_entry_relocs: std.ArrayListUnmanaged(CrossEntryReloc),
591 cross_unit_relocs: std.ArrayListUnmanaged(CrossUnitReloc),
592 cross_section_relocs: std.ArrayListUnmanaged(CrossSectionReloc),
593 external_relocs: std.ArrayListUnmanaged(ExternalReloc),
594
595 fn clear(entry: *Entry) void {
596 entry.cross_entry_relocs.clearRetainingCapacity();
597 entry.cross_unit_relocs.clearRetainingCapacity();
598 entry.cross_section_relocs.clearRetainingCapacity();
599 entry.external_relocs.clearRetainingCapacity();
600 }
601
602 fn deinit(entry: *Entry, gpa: std.mem.Allocator) void {
603 entry.cross_entry_relocs.deinit(gpa);
604 entry.cross_unit_relocs.deinit(gpa);
605 entry.cross_section_relocs.deinit(gpa);
606 entry.external_relocs.deinit(gpa);
607 entry.* = undefined;
608 }
640609
641610 const Index = enum(u32) {
642611 _,
......@@ -803,6 +772,88 @@ const Entry = struct {
803772 }
804773 @panic("missing dwarf relocation target");
805774 }
775
776 fn resolveRelocs(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void {
777 const entry_off = sec.off + unit.off + unit.header_len + entry.off;
778 for (entry.cross_entry_relocs.items) |reloc| {
779 try dwarf.resolveReloc(
780 entry_off + reloc.source_off,
781 unit.off + unit.header_len + unit.getEntry(reloc.target_entry).assertNonEmpty(unit, sec, dwarf).off + reloc.target_off,
782 dwarf.sectionOffsetBytes(),
783 );
784 }
785 for (entry.cross_unit_relocs.items) |reloc| {
786 const target_unit = sec.getUnit(reloc.target_unit);
787 try dwarf.resolveReloc(
788 entry_off + reloc.source_off,
789 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
790 target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
791 else
792 0) + reloc.target_off,
793 dwarf.sectionOffsetBytes(),
794 );
795 }
796 for (entry.cross_section_relocs.items) |reloc| {
797 const target_sec = switch (reloc.target_sec) {
798 inline else => |target_sec| &@field(dwarf, @tagName(target_sec)).section,
799 };
800 const target_unit = target_sec.getUnit(reloc.target_unit);
801 try dwarf.resolveReloc(
802 entry_off + reloc.source_off,
803 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
804 target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
805 else
806 0) + reloc.target_off,
807 dwarf.sectionOffsetBytes(),
808 );
809 }
810 if (dwarf.bin_file.cast(.elf)) |elf_file| {
811 const zo = elf_file.zigObjectPtr().?;
812 for (entry.external_relocs.items) |reloc| {
813 const symbol = zo.symbol(reloc.target_sym);
814 try dwarf.resolveReloc(
815 entry_off + reloc.source_off,
816 @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(reloc.target_off)) -
817 if (symbol.flags.is_tls) elf_file.dtpAddress() else 0),
818 @intFromEnum(dwarf.address_size),
819 );
820 }
821 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
822 const zo = macho_file.getZigObject().?;
823 for (entry.external_relocs.items) |reloc| {
824 const ref = zo.getSymbolRef(reloc.target_sym, macho_file);
825 try dwarf.resolveReloc(
826 entry_off + reloc.source_off,
827 ref.getSymbol(macho_file).?.getAddress(.{}, macho_file),
828 @intFromEnum(dwarf.address_size),
829 );
830 }
831 }
832 }
833};
834
835const CrossEntryReloc = struct {
836 source_off: u32 = 0,
837 target_entry: Entry.Index,
838 target_off: u32 = 0,
839};
840const CrossUnitReloc = struct {
841 source_off: u32 = 0,
842 target_unit: Unit.Index,
843 target_entry: Entry.Index.Optional = .none,
844 target_off: u32 = 0,
845};
846const CrossSectionReloc = struct {
847 source_off: u32 = 0,
848 target_sec: Section.Index,
849 target_unit: Unit.Index,
850 target_entry: Entry.Index.Optional = .none,
851 target_off: u32 = 0,
852};
853const ExternalReloc = struct {
854 source_off: u32 = 0,
855 target_sym: u32,
856 target_off: u64 = 0,
806857};
807858
808859pub const Loc = union(enum) {
......@@ -1087,14 +1138,13 @@ pub const WipNav = struct {
10871138 const diw = wip_nav.debug_info.writer(dwarf.gpa);
10881139 try wip_nav.inlined_funcs_high_reloc.ensureUnusedCapacity(dwarf.gpa, 1);
10891140
1090 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1091 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);
10921141 try uleb128(diw, @intFromEnum(AbbrevCode.inlined_func));
10931142 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
10941143 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1095 try uleb128(diw, column);
1144 try uleb128(diw, column + 1);
1145 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
1146 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);
10961147 external_relocs.appendAssumeCapacity(.{
1097 .source_entry = wip_nav.entry,
10981148 .source_off = @intCast(wip_nav.debug_info.items.len),
10991149 .target_sym = wip_nav.func_sym_index,
11001150 .target_off = code_off,
......@@ -1102,7 +1152,6 @@ pub const WipNav = struct {
11021152 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
11031153 wip_nav.inlined_funcs_high_reloc.appendAssumeCapacity(@intCast(external_relocs.items.len));
11041154 external_relocs.appendAssumeCapacity(.{
1105 .source_entry = wip_nav.entry,
11061155 .source_off = @intCast(wip_nav.debug_info.items.len),
11071156 .target_sym = wip_nav.func_sym_index,
11081157 .target_off = undefined,
......@@ -1112,7 +1161,7 @@ pub const WipNav = struct {
11121161 }
11131162
11141163 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
1115 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1164 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
11161165 external_relocs.items[wip_nav.inlined_funcs_high_reloc.pop()].target_off = code_off;
11171166 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null));
11181167 try wip_nav.setInlineFunc(func);
......@@ -1137,8 +1186,7 @@ pub const WipNav = struct {
11371186 try dlw.writeByte(DW.LNS.extended_op);
11381187 try uleb128(dlw, 1 + dwarf.sectionOffsetBytes());
11391188 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1140 try dwarf.debug_line.section.getUnit(wip_nav.unit).cross_section_relocs.append(dwarf.gpa, .{
1141 .source_entry = wip_nav.entry.toOptional(),
1189 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{
11421190 .source_off = @intCast(wip_nav.debug_line.items.len),
11431191 .target_sec = .debug_info,
11441192 .target_unit = new_unit,
......@@ -1174,9 +1222,9 @@ pub const WipNav = struct {
11741222 fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void {
11751223 const dwarf = wip_nav.dwarf;
11761224 const gpa = dwarf.gpa;
1225 const entry_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry);
11771226 if (sec != .debug_info) {
1178 try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_section_relocs.append(gpa, .{
1179 .source_entry = wip_nav.entry.toOptional(),
1227 try entry_ptr.cross_section_relocs.append(gpa, .{
11801228 .source_off = @intCast(wip_nav.debug_info.items.len),
11811229 .target_sec = sec,
11821230 .target_unit = unit,
......@@ -1184,16 +1232,14 @@ pub const WipNav = struct {
11841232 .target_off = off,
11851233 });
11861234 } else if (unit != wip_nav.unit) {
1187 try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_unit_relocs.append(gpa, .{
1188 .source_entry = wip_nav.entry.toOptional(),
1235 try entry_ptr.cross_unit_relocs.append(gpa, .{
11891236 .source_off = @intCast(wip_nav.debug_info.items.len),
11901237 .target_unit = unit,
11911238 .target_entry = entry.toOptional(),
11921239 .target_off = off,
11931240 });
11941241 } else {
1195 try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs.append(gpa, .{
1196 .source_entry = wip_nav.entry.toOptional(),
1242 try entry_ptr.cross_entry_relocs.append(gpa, .{
11971243 .source_off = @intCast(wip_nav.debug_info.items.len),
11981244 .target_entry = entry,
11991245 .target_off = off,
......@@ -1208,8 +1254,7 @@ pub const WipNav = struct {
12081254
12091255 fn addrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void {
12101256 const dwarf = wip_nav.dwarf;
1211 try dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{
1212 .source_entry = wip_nav.entry,
1257 try dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
12131258 .source_off = @intCast(wip_nav.debug_info.items.len),
12141259 .target_sym = sym_index,
12151260 });
......@@ -1269,10 +1314,9 @@ pub const WipNav = struct {
12691314
12701315 fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {
12711316 const dwarf = wip_nav.dwarf;
1272 const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs;
1317 const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs;
12731318 const reloc_index: u32 = @intCast(cross_entry_relocs.items.len);
12741319 try cross_entry_relocs.append(dwarf.gpa, .{
1275 .source_entry = wip_nav.entry.toOptional(),
12761320 .source_off = @intCast(wip_nav.debug_info.items.len),
12771321 .target_entry = undefined,
12781322 .target_off = undefined,
......@@ -1282,7 +1326,7 @@ pub const WipNav = struct {
12821326 }
12831327
12841328 fn finishForward(wip_nav: *WipNav, reloc_index: u32) void {
1285 const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs.items[reloc_index];
1329 const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs.items[reloc_index];
12861330 reloc.target_entry = wip_nav.entry;
12871331 reloc.target_off = @intCast(wip_nav.debug_info.items.len);
12881332 }
......@@ -1595,7 +1639,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
15951639 const unit = try dwarf.getUnit(file.mod);
15961640 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
15971641 errdefer _ = dwarf.navs.pop();
1598 if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
1642 if (nav_gop.found_existing) {
1643 for ([_]*Section{
1644 &dwarf.debug_aranges.section,
1645 &dwarf.debug_info.section,
1646 &dwarf.debug_line.section,
1647 &dwarf.debug_loclists.section,
1648 &dwarf.debug_rnglists.section,
1649 }) |sec| sec.getUnit(unit).getEntry(nav_gop.value_ptr.*).clear();
1650 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
15991651 const nav_val = zcu.navValue(nav_index);
16001652 var wip_nav: WipNav = .{
16011653 .dwarf = dwarf,
......@@ -1759,17 +1811,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17591811 try wip_nav.strp(nav.name.toSlice(ip));
17601812 try wip_nav.strp(nav.fqn.toSlice(ip));
17611813 try wip_nav.refType(Type.fromInterned(func_type.return_type));
1762 const external_relocs = &dwarf.debug_info.section.getUnit(unit).external_relocs;
1814 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
17631815 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);
17641816 external_relocs.appendAssumeCapacity(.{
1765 .source_entry = wip_nav.entry,
17661817 .source_off = @intCast(wip_nav.debug_info.items.len),
17671818 .target_sym = sym_index,
17681819 });
17691820 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
17701821 wip_nav.func_high_reloc = @intCast(external_relocs.items.len);
17711822 external_relocs.appendAssumeCapacity(.{
1772 .source_entry = wip_nav.entry,
17731823 .source_off = @intCast(wip_nav.debug_info.items.len),
17741824 .target_sym = sym_index,
17751825 .target_off = undefined,
......@@ -1785,8 +1835,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17851835 if (dwarf.incremental()) {
17861836 try uleb128(dlw, 1 + dwarf.sectionOffsetBytes());
17871837 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1788 try dwarf.debug_line.section.getUnit(wip_nav.unit).cross_section_relocs.append(dwarf.gpa, .{
1789 .source_entry = wip_nav.entry.toOptional(),
1838 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{
17901839 .source_off = @intCast(wip_nav.debug_line.items.len),
17911840 .target_sec = .debug_info,
17921841 .target_unit = wip_nav.unit,
......@@ -1801,8 +1850,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
18011850 } else {
18021851 try uleb128(dlw, 1 + @intFromEnum(dwarf.address_size));
18031852 try dlw.writeByte(DW.LNE.set_address);
1804 try dwarf.debug_line.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{
1805 .source_entry = wip_nav.entry,
1853 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
18061854 .source_off = @intCast(wip_nav.debug_line.items.len),
18071855 .target_sym = sym_index,
18081856 });
......@@ -1835,7 +1883,7 @@ pub fn finishWipNav(
18351883 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
18361884
18371885 if (wip_nav.func != .none) {
1838 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1886 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
18391887 external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size;
18401888 if (wip_nav.any_children) {
18411889 const diw = wip_nav.debug_info.writer(dwarf.gpa);
......@@ -1847,8 +1895,7 @@ pub fn finishWipNav(
18471895 );
18481896
18491897 var aranges_entry = [1]u8{0} ** (8 + 8);
1850 try dwarf.debug_aranges.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{
1851 .source_entry = wip_nav.entry,
1898 try dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
18521899 .target_sym = sym.index,
18531900 });
18541901 dwarf.writeInt(aranges_entry[0..@intFromEnum(dwarf.address_size)], 0);
......@@ -1862,14 +1909,12 @@ pub fn finishWipNav(
18621909 aranges_entry[0 .. @intFromEnum(dwarf.address_size) * 2],
18631910 );
18641911
1865 try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).external_relocs.appendSlice(dwarf.gpa, &.{
1912 try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{
18661913 .{
1867 .source_entry = wip_nav.entry,
18681914 .source_off = 1,
18691915 .target_sym = sym.index,
18701916 },
18711917 .{
1872 .source_entry = wip_nav.entry,
18731918 .source_off = 1 + @intFromEnum(dwarf.address_size),
18741919 .target_sym = sym.index,
18751920 .target_off = sym.size,
......@@ -1935,6 +1980,29 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
19351980 errdefer _ = dwarf.navs.pop();
19361981 switch (ip.indexToKey(nav_val.toIntern())) {
19371982 .func => |func| {
1983 if (nav_gop.found_existing) {
1984 const unit_ptr = dwarf.debug_info.section.getUnit(unit);
1985 const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
1986 if (entry_ptr.len >= AbbrevCode.decl_bytes) {
1987 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
1988 if (try dwarf.getFile().?.preadAll(
1989 &abbrev_code_buf,
1990 dwarf.debug_info.section.off + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
1991 ) != abbrev_code_buf.len) return error.InputOutput;
1992 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
1993 const abbrev_code: AbbrevCode = @enumFromInt(
1994 try std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()),
1995 );
1996 switch (abbrev_code) {
1997 else => unreachable,
1998 .decl_func, .decl_func_empty => return,
1999 .decl_func_generic, .decl_func_generic_empty => {},
2000 }
2001 }
2002 entry_ptr.clear();
2003 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
2004 wip_nav.entry = nav_gop.value_ptr.*;
2005
19382006 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
19392007 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
19402008 break :parent .{
......@@ -1948,12 +2016,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
19482016 };
19492017 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
19502018
1951 if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
1952 wip_nav.entry = nav_gop.value_ptr.*;
1953
19542019 const func_type = ip.indexToKey(func.ty).func_type;
19552020 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1956 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (func_type.param_types.len > 0 and func_type.is_var_args) .decl_func_generic else .decl_func_generic_empty)));
2021 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (func_type.param_types.len > 0 or func_type.is_var_args) .decl_func_generic else .decl_func_generic_empty)));
19572022 try wip_nav.refType(Type.fromInterned(parent_type));
19582023 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
19592024 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -1961,12 +2026,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
19612026 try diw.writeByte(accessibility);
19622027 try wip_nav.strp(nav.name.toSlice(ip));
19632028 try wip_nav.refType(Type.fromInterned(func_type.return_type));
1964 for (0..func_type.param_types.len) |param_index| {
1965 try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
1966 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2029 if (func_type.param_types.len > 0 or func_type.is_var_args) {
2030 for (0..func_type.param_types.len) |param_index| {
2031 try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
2032 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2033 }
2034 if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
2035 try uleb128(diw, @intFromEnum(AbbrevCode.null));
19672036 }
1968 if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
1969 try uleb128(diw, @intFromEnum(AbbrevCode.null));
19702037 },
19712038 .struct_type => done: {
19722039 const loaded_struct = ip.loadStructType(nav_val.toIntern());
......@@ -2535,13 +2602,25 @@ fn updateType(
25352602 .error_union_type => |error_union_type| {
25362603 const error_union_error_set_type = Type.fromInterned(error_union_type.error_set_type);
25372604 const error_union_payload_type = Type.fromInterned(error_union_type.payload_type);
2538 const error_union_error_set_offset = codegen.errUnionErrorOffset(error_union_payload_type, pt);
2539 const error_union_payload_offset = codegen.errUnionPayloadOffset(error_union_payload_type, pt);
2605 const error_union_error_set_offset, const error_union_payload_offset = switch (error_union_type.payload_type) {
2606 .generic_poison_type => .{ 0, 0 },
2607 else => .{
2608 codegen.errUnionErrorOffset(error_union_payload_type, pt),
2609 codegen.errUnionPayloadOffset(error_union_payload_type, pt),
2610 },
2611 };
25402612
25412613 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
25422614 try wip_nav.strp(name);
2543 try uleb128(diw, ty.abiSize(pt));
2544 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2615 if (error_union_type.error_set_type != .generic_poison_type and
2616 error_union_type.payload_type != .generic_poison_type)
2617 {
2618 try uleb128(diw, ty.abiSize(pt));
2619 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2620 } else {
2621 try uleb128(diw, 0);
2622 try uleb128(diw, 1);
2623 }
25452624 {
25462625 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
25472626 try wip_nav.infoSectionOffset(
......@@ -2723,10 +2802,16 @@ fn updateType(
27232802 }
27242803 if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
27252804 },
2726 .inferred_error_set_type => |func| {
2727 try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type));
2728 try wip_nav.strp(name);
2729 try wip_nav.refType(Type.fromInterned(ip.funcIesResolvedUnordered(func)));
2805 .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {
2806 .none => {
2807 try uleb128(diw, @intFromEnum(AbbrevCode.void_type));
2808 try wip_nav.strp(name);
2809 },
2810 else => |ies| {
2811 try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type));
2812 try wip_nav.strp(name);
2813 try wip_nav.refType(Type.fromInterned(ies));
2814 },
27302815 },
27312816
27322817 // values, not types
......@@ -3072,7 +3157,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
30723157 if (dwarf.debug_aranges.section.dirty) {
30733158 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
30743159 const unit: Unit.Index = @enumFromInt(unit_index);
3075 try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 1);
3160 unit_ptr.clear();
3161 try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 1);
30763162 header.clearRetainingCapacity();
30773163 try header.ensureTotalCapacity(unit_ptr.header_len);
30783164 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
......@@ -3103,8 +3189,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31033189 if (dwarf.debug_info.section.dirty) {
31043190 for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| {
31053191 const unit: Unit.Index = @enumFromInt(unit_index);
3106 try unit_ptr.cross_unit_relocs.ensureUnusedCapacity(dwarf.gpa, 1);
3107 try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 7);
3192 unit_ptr.clear();
3193 try unit_ptr.cross_unit_relocs.ensureTotalCapacity(dwarf.gpa, 1);
3194 try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 7);
31083195 header.clearRetainingCapacity();
31093196 try header.ensureTotalCapacity(unit_ptr.header_len);
31103197 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
......@@ -3195,7 +3282,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31953282 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|
31963283 try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));
31973284 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
3198 try unit.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));
3285 unit.clear();
3286 try unit.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));
31993287 header.clearRetainingCapacity();
32003288 try header.ensureTotalCapacity(unit.header_len);
32013289 const unit_len = (if (unit.next.unwrap()) |next_unit|
src/link/Elf/ZigObject.zig+6-6
......@@ -1122,9 +1122,9 @@ pub fn updateNav(
11221122
11231123 log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index });
11241124
1125 const nav_val = zcu.navValue(nav_index);
1126 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1127 .variable => |variable| Value.fromInterned(variable.init),
1125 const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) {
1126 .func => .none,
1127 .variable => |variable| variable.init,
11281128 .@"extern" => |@"extern"| {
11291129 if (ip.isFunctionType(@"extern".ty)) return;
11301130 const sym_index = try self.getGlobalSymbol(
......@@ -1135,10 +1135,10 @@ pub fn updateNav(
11351135 self.symbol(sym_index).flags.is_extern_ptr = true;
11361136 return;
11371137 },
1138 else => nav_val,
1138 else => nav.status.resolved.val,
11391139 };
11401140
1141 if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) {
1141 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) {
11421142 const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);
11431143 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11441144
......@@ -1153,7 +1153,7 @@ pub fn updateNav(
11531153 &elf_file.base,
11541154 pt,
11551155 zcu.navSrcLoc(nav_index),
1156 nav_init,
1156 Value.fromInterned(nav_init),
11571157 &code_buffer,
11581158 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
11591159 .{ .parent_atom_index = sym_index },
src/link/MachO/ZigObject.zig+7-6
......@@ -869,10 +869,11 @@ pub fn updateNav(
869869
870870 const zcu = pt.zcu;
871871 const ip = &zcu.intern_pool;
872 const nav = ip.getNav(nav_index);
872873
873 const nav_val = zcu.navValue(nav_index);
874 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
875 .variable => |variable| Value.fromInterned(variable.init),
874 const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) {
875 .func => .none,
876 .variable => |variable| variable.init,
876877 .@"extern" => |@"extern"| {
877878 if (ip.isFunctionType(@"extern".ty)) return;
878879 // Extern variable gets a __got entry only
......@@ -883,10 +884,10 @@ pub fn updateNav(
883884 sym.flags.is_extern_ptr = true;
884885 return;
885886 },
886 else => nav_val,
887 else => nav.status.resolved.val,
887888 };
888889
889 if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) {
890 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) {
890891 const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index);
891892 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
892893
......@@ -900,7 +901,7 @@ pub fn updateNav(
900901 &macho_file.base,
901902 pt,
902903 zcu.navSrcLoc(nav_index),
903 nav_init,
904 Value.fromInterned(nav_init),
904905 &code_buffer,
905906 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
906907 .{ .parent_atom_index = sym_index },
src/link/Plan9.zig+2-1
......@@ -448,6 +448,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
448448 const nav = ip.getNav(nav_index);
449449 const nav_val = zcu.navValue(nav_index);
450450 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
451 .func => return,
451452 .variable => |variable| Value.fromInterned(variable.init),
452453 .@"extern" => {
453454 log.debug("found extern decl: {}", .{nav.name.fmt(ip)});
......@@ -456,7 +457,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
456457 else => nav_val,
457458 };
458459
459 if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) {
460 if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) {
460461 const atom_idx = try self.seeNav(pt, nav_index);
461462
462463 var code_buffer = std.ArrayList(u8).init(gpa);
src/link/Wasm/ZigObject.zig+1-1
......@@ -259,7 +259,7 @@ pub fn updateNav(
259259 else => .{ false, .none, nav_val },
260260 };
261261
262 if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) {
262 if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) {
263263 const gpa = wasm_file.base.comp.gpa;
264264 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index);
265265 const atom = wasm_file.getAtomPtr(atom_index);
test/src/Debugger.zig+73-13
......@@ -587,7 +587,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
587587 },
588588 );
589589 db.addLldbTest(
590 "cross_module_call",
590 "inline_call",
591591 target,
592592 &.{
593593 .{
......@@ -595,8 +595,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
595595 .source =
596596 \\const module = @import("module");
597597 \\pub fn main() void {
598 \\ module.foo(123);
599 \\ module.bar(456);
598 \\ fa(12);
599 \\ fb(34);
600 \\ module.fc(56);
601 \\ module.fd(78);
602 \\}
603 \\fn fa(pa: u32) void {
604 \\ const la = ~pa;
605 \\ _ = la;
606 \\}
607 \\inline fn fb(pb: u32) void {
608 \\ const lb = ~pb;
609 \\ _ = lb;
600610 \\}
601611 \\
602612 ,
......@@ -605,34 +615,84 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
605615 .import = "module",
606616 .path = "module.zig",
607617 .source =
608 \\pub fn foo(x: u32) void {
609 \\ _ = x;
618 \\pub fn fc(pc: u32) void {
619 \\ const lc = ~pc;
620 \\ _ = lc;
610621 \\}
611 \\pub inline fn bar(y: u32) void {
612 \\ _ = y;
622 \\pub inline fn fd(pd: u32) void {
623 \\ const ld = ~pd;
624 \\ _ = ld;
613625 \\}
614626 \\
615627 ,
616628 },
617629 },
618 \\breakpoint set --file module.zig --source-pattern-regexp '_ = x;'
630 \\settings set frame-format 'frame #${frame.index}:{ ${module.file.basename}{\`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${line.file.basename}:${line.number}{:${line.column}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\n'
631 \\
632 \\breakpoint set --file main.zig --source-pattern-regexp '_ = la;'
619633 \\process launch
620 \\source info
634 \\frame variable pa la
635 \\thread backtrace --count 2
621636 \\breakpoint delete --force 1
622637 \\
623 \\breakpoint set --file module.zig --line 5
638 \\breakpoint set --file main.zig --source-pattern-regexp '_ = lb;'
624639 \\process continue
625 \\source info
640 \\frame variable pb lb
641 \\thread backtrace --count 2
626642 \\breakpoint delete --force 2
643 \\
644 \\breakpoint set --file module.zig --source-pattern-regexp '_ = lc;'
645 \\process continue
646 \\frame variable pc lc
647 \\thread backtrace --count 2
648 \\breakpoint delete --force 3
649 \\
650 \\breakpoint set --file module.zig --line 7
651 \\process continue
652 \\frame variable pd ld
653 \\thread backtrace --count 2
654 \\breakpoint delete --force 4
627655 ,
628656 &.{
629 \\/module.zig:2:5
657 \\(lldb) frame variable pa la
658 \\(u32) pa = 12
659 \\(u32) la = 4294967283
660 \\(lldb) thread backtrace --count 2
661 \\* thread #1, name = 'inline_call', stop reason = breakpoint 1.1
662 \\ * frame #0: inline_call`main.fa(pa=12) at main.zig:10:5
663 \\ frame #1: inline_call`main.main at main.zig:3:7
630664 \\(lldb) breakpoint delete --force 1
631665 \\1 breakpoints deleted; 0 breakpoint locations disabled.
632666 ,
633 \\/module.zig:5:5
667 \\(lldb) frame variable pb lb
668 \\(u32) pb = 34
669 \\(u32) lb = 4294967261
670 \\(lldb) thread backtrace --count 2
671 \\* thread #1, name = 'inline_call', stop reason = breakpoint 2.1
672 \\ * frame #0: inline_call`main.main [inlined] fb(pb=34) at main.zig:14:5
673 \\ frame #1: inline_call`main.main at main.zig:4:7
634674 \\(lldb) breakpoint delete --force 2
635675 \\1 breakpoints deleted; 0 breakpoint locations disabled.
676 ,
677 \\(lldb) frame variable pc lc
678 \\(u32) pc = 56
679 \\(u32) lc = 4294967239
680 \\(lldb) thread backtrace --count 2
681 \\* thread #1, name = 'inline_call', stop reason = breakpoint 3.1
682 \\ * frame #0: inline_call`module.fc(pc=56) at module.zig:3:5
683 \\ frame #1: inline_call`main.main at main.zig:5:14
684 \\(lldb) breakpoint delete --force 3
685 \\1 breakpoints deleted; 0 breakpoint locations disabled.
686 ,
687 \\(lldb) frame variable pd ld
688 \\(u32) pd = 78
689 \\(u32) ld = 4294967217
690 \\(lldb) thread backtrace --count 2
691 \\* thread #1, name = 'inline_call', stop reason = breakpoint 4.1
692 \\ * frame #0: inline_call`main.main [inlined] fd(pd=78) at module.zig:7:5
693 \\ frame #1: inline_call`main.main at main.zig:6:14
694 \\(lldb) breakpoint delete --force 4
695 \\1 breakpoints deleted; 0 breakpoint locations disabled.
636696 },
637697 );
638698}