Commit 5ebca4392e

kcbanner <kcbanner@gmail.com>
2023-05-27 20:14:43
debug: fixing more compile errors on arches that I hadn't tested on yet
1 parent 551f153
Changed files (3)
lib/std/dwarf/abi.zig
@@ -8,6 +8,17 @@ pub const RegisterContext = struct {
     is_macho: bool,
 };
 
+pub fn isSupportedArch(arch: std.Target.Cpu.Arch) bool {
+    return switch (arch) {
+        .x86,
+        .x86_64,
+        .arm,
+        .aarch64,
+        => true,
+        else => false,
+    };
+}
+
 pub fn ipRegNum() u8 {
     return switch (builtin.cpu.arch) {
         .x86 => 8,
lib/std/debug.zig
@@ -421,7 +421,11 @@ pub const StackIterator = struct {
     // stacks with frames that don't use a frame pointer (ie. -fomit-frame-pointer).
     debug_info: ?*DebugInfo,
     dwarf_context: if (supports_context) DW.UnwindContext else void = undefined,
-    const supports_context = @hasDecl(os.system, "ucontext_t");
+    const supports_context = @hasDecl(os.system, "ucontext_t") and
+        (builtin.os.tag != .linux or switch (builtin.cpu.arch) {
+        .mips, .riscv64 => false,
+        else => true,
+    });
 
     pub fn init(first_address: ?usize, fp: ?usize) StackIterator {
         if (native_arch == .sparc64) {
@@ -528,7 +532,7 @@ pub const StackIterator = struct {
 
     fn next_dwarf(self: *StackIterator) !void {
         const module = try self.debug_info.?.getModuleForAddress(self.dwarf_context.pc);
-        if (module.getDwarfInfo()) |di| {
+        if (try module.getDwarfInfoForAddress(self.debug_info.?.allocator, self.dwarf_context.pc)) |di| {
             self.dwarf_context.reg_ctx.eh_frame = true;
             self.dwarf_context.reg_ctx.is_macho = di.is_macho;
             try di.unwindFrame(self.debug_info.?.allocator, &self.dwarf_context, module.base_address);
@@ -1684,6 +1688,26 @@ pub const ModuleDebugInfo = switch (native_os) {
             return info;
         }
 
+        fn getOFileForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*OFileInfo {
+            nosuspend {
+                const relocated_address = address - self.base_address;
+                const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse
+                    return null;
+
+                const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0);
+                var o_file_info = self.ofiles.get(o_file_path) orelse
+                    (self.loadOFile(allocator, o_file_path) catch |err| switch (err) {
+                    error.FileNotFound,
+                    error.MissingDebugInfo,
+                    error.InvalidDebugInfo,
+                    => return null,
+                    else => return err,
+                });
+
+                return &o_file_info.di;
+            }
+        }
+
         pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
             nosuspend {
                 // Translate the VA into an address into this object
@@ -1749,40 +1773,38 @@ pub const ModuleDebugInfo = switch (native_os) {
             }
         }
 
-        pub fn getDwarfInfo(self: *@This()) ?*const DW.DwarfInfo {
-            // TODO: Implement
-            _ = self;
-            return null;
+        pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
+            nosuspend {
+                const relocated_address = address - self.base_address;
+                const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse
+                    return null;
+
+                const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0);
+                var o_file_info = self.ofiles.get(o_file_path) orelse
+                    (self.loadOFile(allocator, o_file_path) catch |err| switch (err) {
+                    error.FileNotFound,
+                    error.MissingDebugInfo,
+                    error.InvalidDebugInfo,
+                    => return null,
+                    else => return err,
+                });
+
+                return &o_file_info.di;
+            }
         }
     },
     .uefi, .windows => struct {
         base_address: usize,
         debug_data: PdbOrDwarf,
         coff_image_base: u64,
+        /// Only used if debug_data is .pdb
         coff_section_headers: []coff.SectionHeader,
 
         fn deinit(self: *@This(), allocator: mem.Allocator) void {
-            switch (self.debug_data) {
-                .dwarf => |*dwarf| {
-                    allocator.free(dwarf.debug_info);
-                    allocator.free(dwarf.debug_abbrev);
-                    allocator.free(dwarf.debug_str);
-                    allocator.free(dwarf.debug_line);
-                    if (dwarf.debug_str_offsets) |d| allocator.free(d);
-                    if (dwarf.debug_line_str) |d| allocator.free(d);
-                    if (dwarf.debug_ranges) |d| allocator.free(d);
-                    if (dwarf.debug_loclists) |d| allocator.free(d);
-                    if (dwarf.debug_rnglists) |d| allocator.free(d);
-                    if (dwarf.debug_addr) |d| allocator.free(d);
-                    if (dwarf.debug_names) |d| allocator.free(d);
-                    if (dwarf.debug_frame) |d| allocator.free(d);
-                },
-                .pdb => {
-                    allocator.free(self.coff_section_headers);
-                },
-            }
-
             self.debug_data.deinit(allocator);
+            if (self.debug_data == .pdb) {
+                allocator.free(self.coff_section_headers);
+            }
         }
 
         pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
@@ -1835,7 +1857,10 @@ pub const ModuleDebugInfo = switch (native_os) {
             };
         }
 
-        pub fn getDwarfInfo(self: *@This()) ?*const DW.DwarfInfo {
+        pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
+            _ = allocator;
+            _ = address;
+
             return switch (self.debug_data) {
                 .dwarf => |*dwarf| dwarf,
                 else => null,
@@ -1860,7 +1885,9 @@ pub const ModuleDebugInfo = switch (native_os) {
             return getSymbolFromDwarf(allocator, relocated_address, &self.dwarf);
         }
 
-        pub fn getDwarfInfo(self: *@This()) ?*const DW.DwarfInfo {
+        pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
+            _ = allocator;
+            _ = address;
             return &self.dwarf;
         }
     },
@@ -1877,8 +1904,10 @@ pub const ModuleDebugInfo = switch (native_os) {
             return SymbolInfo{};
         }
 
-        pub fn getDwarfInfo(self: *@This()) ?*const DW.DwarfInfo {
+        pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
             _ = self;
+            _ = allocator;
+            _ = address;
             return null;
         }
     },
lib/std/dwarf.zig
@@ -1556,6 +1556,7 @@ pub const DwarfInfo = struct {
     }
 
     pub fn unwindFrame(di: *const DwarfInfo, allocator: mem.Allocator, context: *UnwindContext, module_base_address: usize) !void {
+        if (!comptime abi.isSupportedArch(builtin.target.cpu.arch)) return error.UnsupportedCpuArchitecture;
         if (context.pc == 0) return;
 
         // TODO: Handle signal frame (ie. use_prev_instr in libunwind)