authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-02 12:22:59+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:49+01:00
logfb88dab4c9c7d89ec7b5842dafdefe93ed939b3c
tree7cb044b7a85e9c8f2931ee31cfff220f78596e46
parented6ed62c42dfad18facde164785a62faa305cb6c
signaturelock-open Commit is signed but in an unrecognized format.

more still


2 files changed, 30 insertions(+), 44 deletions(-)

lib/std/debug/Dwarf.zig+22-36
......@@ -1451,18 +1451,10 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 {
14511451
14521452// MLUGG TODO: i am dubious of this whole thing being here atp. look closely and see if it depends on being the self process
14531453pub const ElfModule = struct {
1454 unwind: Dwarf.Unwind,
14551454 dwarf: Dwarf,
1456 mapped_memory: ?[]align(std.heap.page_size_min) const u8,
1455 mapped_memory: []align(std.heap.page_size_min) const u8,
14571456 external_mapped_memory: ?[]align(std.heap.page_size_min) const u8,
14581457
1459 pub const init: ElfModule = .{
1460 .unwind = .init,
1461 .dwarf = .{},
1462 .mapped_memory = null,
1463 .external_mapped_memory = null,
1464 };
1465
14661458 pub fn deinit(self: *@This(), allocator: Allocator) void {
14671459 self.dwarf.deinit(allocator);
14681460 std.posix.munmap(self.mapped_memory);
......@@ -1476,12 +1468,6 @@ pub const ElfModule = struct {
14761468 return self.dwarf.getSymbol(allocator, endian, vaddr);
14771469 }
14781470
1479 pub fn getDwarfUnwindForAddress(self: *@This(), allocator: Allocator, address: usize) !?*Dwarf.Unwind {
1480 _ = allocator;
1481 _ = address;
1482 return &self.unwind;
1483 }
1484
14851471 pub const LoadError = error{
14861472 InvalidDebugInfo,
14871473 MissingDebugInfo,
......@@ -1506,10 +1492,7 @@ pub const ElfModule = struct {
15061492 /// If the required sections aren't present but a reference to external debug
15071493 /// info is, then this this function will recurse to attempt to load the debug
15081494 /// sections from an external file.
1509 ///
1510 /// MLUGG TODO: this should *return* a thing
15111495 pub fn load(
1512 em: *ElfModule,
15131496 gpa: Allocator,
15141497 mapped_mem: []align(std.heap.page_size_min) const u8,
15151498 build_id: ?[]const u8,
......@@ -1517,9 +1500,7 @@ pub const ElfModule = struct {
15171500 parent_sections: ?*Dwarf.SectionArray,
15181501 parent_mapped_mem: ?[]align(std.heap.page_size_min) const u8,
15191502 elf_filename: ?[]const u8,
1520 ) LoadError!void {
1521 assert(em.mapped_memory == null);
1522
1503 ) LoadError!ElfModule {
15231504 if (expected_crc) |crc| if (crc != std.hash.crc.Crc32.hash(mapped_mem)) return error.InvalidDebugInfo;
15241505
15251506 const hdr: *const elf.Ehdr = @ptrCast(&mapped_mem[0]);
......@@ -1657,7 +1638,7 @@ pub const ElfModule = struct {
16571638 .sub_path = filename,
16581639 };
16591640
1660 return em.loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem) catch break :blk;
1641 return loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem) catch break :blk;
16611642 }
16621643
16631644 const global_debug_directories = [_][]const u8{
......@@ -1685,7 +1666,7 @@ pub const ElfModule = struct {
16851666 };
16861667 defer gpa.free(path.sub_path);
16871668
1688 return em.loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem) catch continue;
1669 return loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem) catch continue;
16891670 }
16901671 }
16911672
......@@ -1701,7 +1682,7 @@ pub const ElfModule = struct {
17011682 defer exe_dir.close();
17021683
17031684 // <exe_dir>/<gnu_debuglink>
1704 if (em.loadPath(
1685 if (loadPath(
17051686 gpa,
17061687 .{
17071688 .root_dir = .{ .path = null, .handle = exe_dir },
......@@ -1711,9 +1692,8 @@ pub const ElfModule = struct {
17111692 separate_debug_crc,
17121693 &sections,
17131694 mapped_mem,
1714 )) |v| {
1715 v;
1716 return;
1695 )) |em| {
1696 return em;
17171697 } else |_| {}
17181698
17191699 // <exe_dir>/.debug/<gnu_debuglink>
......@@ -1723,7 +1703,9 @@ pub const ElfModule = struct {
17231703 };
17241704 defer gpa.free(path.sub_path);
17251705
1726 if (em.loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem)) |debug_info| return debug_info else |_| {}
1706 if (loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem)) |em| {
1707 return em;
1708 } else |_| {}
17271709 }
17281710
17291711 var cwd_buf: [std.fs.max_path_bytes]u8 = undefined;
......@@ -1736,28 +1718,32 @@ pub const ElfModule = struct {
17361718 .sub_path = try std.fs.path.join(gpa, &.{ global_directory, cwd_path, separate_filename }),
17371719 };
17381720 defer gpa.free(path.sub_path);
1739 if (em.loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem)) |debug_info| return debug_info else |_| {}
1721 if (loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem)) |em| {
1722 return em;
1723 } else |_| {}
17401724 }
17411725 }
17421726
17431727 return error.MissingDebugInfo;
17441728 }
17451729
1746 em.mapped_memory = parent_mapped_mem orelse mapped_mem;
1747 em.external_mapped_memory = if (parent_mapped_mem != null) mapped_mem else null;
1748 em.dwarf.sections = sections;
1749 try em.dwarf.open(gpa, endian);
1730 var dwarf: Dwarf = .{ .sections = sections };
1731 try dwarf.open(gpa, endian);
1732 return .{
1733 .mapped_memory = parent_mapped_mem orelse mapped_mem,
1734 .external_mapped_memory = if (parent_mapped_mem != null) mapped_mem else null,
1735 .dwarf = dwarf,
1736 };
17501737 }
17511738
17521739 pub fn loadPath(
1753 em: *ElfModule,
17541740 gpa: Allocator,
17551741 elf_file_path: Path,
17561742 build_id: ?[]const u8,
17571743 expected_crc: ?u32,
17581744 parent_sections: *Dwarf.SectionArray,
17591745 parent_mapped_mem: ?[]align(std.heap.page_size_min) const u8,
1760 ) LoadError!void {
1746 ) LoadError!ElfModule {
17611747 const elf_file = elf_file_path.root_dir.handle.openFile(elf_file_path.sub_path, .{}) catch |err| switch (err) {
17621748 error.FileNotFound => return missing(),
17631749 else => return err,
......@@ -1780,7 +1766,7 @@ pub const ElfModule = struct {
17801766 };
17811767 errdefer std.posix.munmap(mapped_mem);
17821768
1783 return em.load(
1769 return load(
17841770 gpa,
17851771 mapped_mem,
17861772 build_id,
lib/std/debug/SelfInfo.zig+8-8
......@@ -99,10 +99,7 @@ pub fn unwindFrame(self: *SelfInfo, gpa: Allocator, context: *UnwindContext) !us
9999 }
100100 return error.MissingUnwindInfo;
101101 }
102 if (try gop.value_ptr.di.getDwarfUnwindForAddress(gpa, context.pc)) |unwind| {
103 return unwindFrameDwarf(unwind, module.load_offset, context, null);
104 }
105 return error.MissingDebugInfo;
102 return unwindFrameDwarf(&gop.value_ptr.di.unwind, module.load_offset, context, null);
106103}
107104
108105pub fn getSymbolAtAddress(self: *SelfInfo, gpa: Allocator, address: usize) !std.debug.Symbol {
......@@ -409,7 +406,11 @@ const Module = switch (native_os) {
409406 build_id: ?[]const u8,
410407 gnu_eh_frame: ?[]const u8,
411408 const LookupCache = void;
412 const DebugInfo = Dwarf.ElfModule;
409 const DebugInfo = struct {
410 const init: DebugInfo = undefined; // MLUGG TODO: this makes me sad
411 em: Dwarf.ElfModule, // MLUGG TODO: bad field name (and, frankly, type)
412 unwind: Dwarf.Unwind,
413 };
413414 fn key(m: Module) usize {
414415 return m.load_offset; // MLUGG TODO: is this technically valid? idk
415416 }
......@@ -492,8 +493,7 @@ const Module = switch (native_os) {
492493 else => |e| return e,
493494 };
494495 errdefer posix.munmap(mapped_mem);
495 try di.load(gpa, mapped_mem, module.build_id, null, null, null, filename);
496 assert(di.mapped_memory != null);
496 di.em = try .load(gpa, mapped_mem, module.build_id, null, null, null, filename);
497497 }
498498 fn loadUnwindInfo(module: *const Module, gpa: Allocator, di: *Module.DebugInfo) !void {
499499 const section_bytes = module.gnu_eh_frame orelse return error.MissingUnwindInfo; // MLUGG TODO: load from file
......@@ -503,7 +503,7 @@ const Module = switch (native_os) {
503503 try di.unwind.prepareLookup(gpa, @sizeOf(usize), native_endian);
504504 }
505505 fn getSymbolAtAddress(module: *const Module, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol {
506 return di.getSymbolAtAddress(gpa, native_endian, module.load_offset, address);
506 return di.em.getSymbolAtAddress(gpa, native_endian, module.load_offset, address);
507507 }
508508 },
509509 .uefi, .windows => struct {