mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 13:58:20 +00:00
feat: better panic handler
This commit is contained in:
@@ -45,14 +45,15 @@ pub fn build(b: *std.Build) void {
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ksyms_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/ksyms.zig"), // Use the static wrapper
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
// first pass
|
// first pass
|
||||||
const empty_cmd = b.addSystemCommand(&.{ "python3", "build/ksyms.py", "--empty" });
|
const empty_cmd = b.addSystemCommand(&.{ "python3", "build/ksyms.py", "--empty" });
|
||||||
empty_cmd.addArg("--output");
|
empty_cmd.addArg("--output");
|
||||||
const empty_zig = empty_cmd.addOutputFileArg("ksyms_empty.gen.zig");
|
const empty_ksyms_s = empty_cmd.addOutputFileArg("ksyms_empty.s");
|
||||||
const empty_ksyms_module = b.createModule(.{
|
|
||||||
.root_source_file = empty_zig,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rtl_module = b.createModule(.{
|
const rtl_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/rtl/root.zig"),
|
.root_source_file = b.path("src/rtl/root.zig"),
|
||||||
@@ -61,17 +62,6 @@ pub fn build(b: *std.Build) void {
|
|||||||
|
|
||||||
rtl_module.addImport("rtl", rtl_module);
|
rtl_module.addImport("rtl", rtl_module);
|
||||||
|
|
||||||
const base_module = b.createModule(.{
|
|
||||||
.root_source_file = b.path("src/root.zig"),
|
|
||||||
.imports = &.{
|
|
||||||
.{ .name = "config", .module = config_module },
|
|
||||||
.{ .name = "rtl", .module = rtl_module },
|
|
||||||
},
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
base_module.addImport("base", base_module);
|
|
||||||
|
|
||||||
const arch = if (plat.os == .freestanding) switch (plat.arch) {
|
const arch = if (plat.os == .freestanding) switch (plat.arch) {
|
||||||
.x86_64 => "amd64",
|
.x86_64 => "amd64",
|
||||||
else => @tagName(plat.arch),
|
else => @tagName(plat.arch),
|
||||||
@@ -86,7 +76,10 @@ pub fn build(b: *std.Build) void {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const kernel_nosym = addKernel(b, plat, optimize, config_module, empty_ksyms_module, rtl_module, base_module, arch_module);
|
const base_nosym = makeBaseModule(b, optimize, config_module, rtl_module, ksyms_module);
|
||||||
|
const kernel_nosym = addKernel(b, plat, optimize, config_module, ksyms_module, rtl_module, base_nosym, arch_module);
|
||||||
|
|
||||||
|
kernel_nosym.root_module.addAssemblyFile(empty_ksyms_s);
|
||||||
|
|
||||||
b.step("kernel-nosym", "Build nosym kernel").dependOn(&kernel_nosym.step);
|
b.step("kernel-nosym", "Build nosym kernel").dependOn(&kernel_nosym.step);
|
||||||
|
|
||||||
@@ -96,14 +89,13 @@ pub fn build(b: *std.Build) void {
|
|||||||
ksyms.step.dependOn(&kernel_nosym.step);
|
ksyms.step.dependOn(&kernel_nosym.step);
|
||||||
ksyms.addFileArg(kernel_nosym.getEmittedBin());
|
ksyms.addFileArg(kernel_nosym.getEmittedBin());
|
||||||
ksyms.addArg("--output");
|
ksyms.addArg("--output");
|
||||||
const ksyms_zig = ksyms.addOutputFileArg("ksyms.gen.zig");
|
const ksyms_s = ksyms.addOutputFileArg("ksyms.s");
|
||||||
const ksyms_module = b.createModule(.{
|
|
||||||
.root_source_file = ksyms_zig,
|
const base_module = makeBaseModule(b, optimize, config_module, rtl_module, ksyms_module);
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
// second pass
|
// second pass
|
||||||
const kernel = addKernel(b, plat, optimize, config_module, ksyms_module, rtl_module, base_module, arch_module);
|
const kernel = addKernel(b, plat, optimize, config_module, ksyms_module, rtl_module, base_module, arch_module);
|
||||||
|
kernel.root_module.addAssemblyFile(ksyms_s);
|
||||||
|
|
||||||
b.default_step.dependOn(&b.addInstallArtifact(kernel, .{}).step);
|
b.default_step.dependOn(&b.addInstallArtifact(kernel, .{}).step);
|
||||||
|
|
||||||
@@ -181,6 +173,26 @@ fn targetQueryForPlatform(plat: config.Platform) std.Target.Query {
|
|||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn makeBaseModule(
|
||||||
|
b: *std.Build,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
config_module: *std.Build.Module,
|
||||||
|
rtl_module: *std.Build.Module,
|
||||||
|
ksyms_module: *std.Build.Module,
|
||||||
|
) *std.Build.Module {
|
||||||
|
const base = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/root.zig"),
|
||||||
|
.imports = &.{
|
||||||
|
.{ .name = "config", .module = config_module },
|
||||||
|
.{ .name = "rtl", .module = rtl_module },
|
||||||
|
.{ .name = "ksyms", .module = ksyms_module },
|
||||||
|
},
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
base.addImport("base", base);
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
fn addKernel(b: *std.Build, plat: config.Platform, optimize: std.builtin.OptimizeMode, config_module: *std.Build.Module, ksyms_module: *std.Build.Module, rtl: *std.Build.Module, base: *std.Build.Module, arch: *std.Build.Module) *std.Build.Step.Compile {
|
fn addKernel(b: *std.Build, plat: config.Platform, optimize: std.builtin.OptimizeMode, config_module: *std.Build.Module, ksyms_module: *std.Build.Module, rtl: *std.Build.Module, base: *std.Build.Module, arch: *std.Build.Module) *std.Build.Step.Compile {
|
||||||
const target = b.resolveTargetQuery(targetQueryForPlatform(plat));
|
const target = b.resolveTargetQuery(targetQueryForPlatform(plat));
|
||||||
|
|
||||||
@@ -205,6 +217,7 @@ fn addKernel(b: *std.Build, plat: config.Platform, optimize: std.builtin.Optimiz
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
base.addImport("ksyms", ksyms_module);
|
||||||
kernel.root_module.addImport("config", config_module);
|
kernel.root_module.addImport("config", config_module);
|
||||||
kernel.root_module.addImport("ksyms", ksyms_module);
|
kernel.root_module.addImport("ksyms", ksyms_module);
|
||||||
kernel.root_module.addImport("base", base);
|
kernel.root_module.addImport("base", base);
|
||||||
@@ -213,6 +226,8 @@ fn addKernel(b: *std.Build, plat: config.Platform, optimize: std.builtin.Optimiz
|
|||||||
kernel.use_llvm = true;
|
kernel.use_llvm = true;
|
||||||
kernel.use_lld = true;
|
kernel.use_lld = true;
|
||||||
|
|
||||||
|
kernel.root_module.omit_frame_pointer = false;
|
||||||
|
|
||||||
if (plat.os == .freestanding) {
|
if (plat.os == .freestanding) {
|
||||||
kernel.linkage = .static;
|
kernel.linkage = .static;
|
||||||
kernel.pie = false;
|
kernel.pie = false;
|
||||||
|
|||||||
+54
-32
@@ -2,66 +2,88 @@
|
|||||||
# Simple kernel symbol dumper
|
# Simple kernel symbol dumper
|
||||||
# Usage: ksyms.py --input <kernel binary> --output <output file>
|
# Usage: ksyms.py --input <kernel binary> --output <output file>
|
||||||
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
excluded_symbols = ['text_start_addr', 'text_end_addr', 'rodata_start_addr', 'rodata_end_addr', 'data_start_addr', 'data_end_addr']
|
excluded_symbols = [
|
||||||
|
"text_start_addr",
|
||||||
|
"text_end_addr",
|
||||||
|
"rodata_start_addr",
|
||||||
|
"rodata_end_addr",
|
||||||
|
"data_start_addr",
|
||||||
|
"data_end_addr",
|
||||||
|
]
|
||||||
|
|
||||||
def parse_nm_line(line: str) -> tuple[int, str]:
|
|
||||||
|
def parse_nm_line(line: str):
|
||||||
parts = line.split()
|
parts = line.split()
|
||||||
if len(parts) < 3:
|
if len(parts) < 3:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
addr_str, type, name = parts[0], parts[1], parts[2]
|
addr_str, type, name = parts[0], parts[1], parts[2]
|
||||||
|
|
||||||
# Only get symbols in text
|
# Only get symbols in text
|
||||||
if type.lower() != 't':
|
if type.lower() != "t":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if name in excluded_symbols:
|
if name in excluded_symbols:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
addr = int(addr_str, 16)
|
addr = int(addr_str, 16)
|
||||||
return addr, name
|
return addr, name
|
||||||
|
|
||||||
def run_nm(binary: str) -> list[str]:
|
|
||||||
|
|
||||||
|
def run_nm(binary: str):
|
||||||
result = subprocess.run(["nm", "-n", binary], capture_output=True, text=True)
|
result = subprocess.run(["nm", "-n", binary], capture_output=True, text=True)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise RuntimeError(f"nm failed: {result.stderr}")
|
raise RuntimeError(f"nm failed: {result.stderr}")
|
||||||
return result.stdout.splitlines()
|
return result.stdout.splitlines()
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Generate kernel symbols from a binary")
|
parser = argparse.ArgumentParser(description="Generate kernel symbols from a binary")
|
||||||
parser.add_argument("--input", help="Input kernel binary")
|
parser.add_argument("--input", help="Input kernel binary")
|
||||||
parser.add_argument("--output", help="Output C file")
|
parser.add_argument("--output", help="Output Assembly file (.s)")
|
||||||
parser.add_argument("--empty", action="store_true", help="Generate empty ksyms")
|
parser.add_argument("--empty", action="store_true", help="Generate empty ksyms")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.empty:
|
with open(args.output, "w") as f:
|
||||||
with open(args.output, 'w') as f:
|
f.write("/* Auto-generated by build/ksyms.py - do not edit */\n")
|
||||||
f.write("// Auto-generated by build/ksyms.py - do not edit\n\n")
|
f.write(".section .rodata\n")
|
||||||
f.write("pub const KSym = struct {\n addr: u64,\n name: []const u8,\n};\n\n")
|
|
||||||
f.write("pub const ksyms: []const KSym = &.{};\n")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
lines = run_nm(args.input)
|
if args.empty:
|
||||||
|
f.write(".global ksyms_array\n")
|
||||||
|
f.write(".global ksyms_count\n")
|
||||||
|
f.write(".align 8\n")
|
||||||
|
f.write("ksyms_array:\n")
|
||||||
|
f.write("ksyms_count:\n")
|
||||||
|
f.write(" .quad 0\n")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
symbols = []
|
lines = run_nm(args.input)
|
||||||
for line in lines:
|
symbols = []
|
||||||
parsed = parse_nm_line(line)
|
for line in lines:
|
||||||
if parsed:
|
parsed = parse_nm_line(line)
|
||||||
symbols.append(parsed)
|
if parsed:
|
||||||
|
symbols.append(parsed)
|
||||||
|
|
||||||
# Sort by address
|
# Sort by address
|
||||||
symbols.sort(key=lambda x: x[0])
|
symbols.sort(key=lambda x: x[0])
|
||||||
|
|
||||||
with open(args.output, 'w') as f:
|
for i, (addr, name) in enumerate(symbols):
|
||||||
f.write("// Auto-generated by build/ksyms.py - do not edit\n\n")
|
escaped = name.replace("\\", "\\\\").replace('"', '\\"')
|
||||||
f.write("pub const KSym = struct {\n addr: u64,\n name: []const u8,\n};\n\n")
|
f.write(f'.Lstr{i}: .asciz "{escaped}"\n')
|
||||||
f.write("pub const ksyms: []const KSym = &.{\n")
|
|
||||||
for addr, name in symbols:
|
f.write("\n.global ksyms_array\n")
|
||||||
escaped = name.replace('\\', '\\\\').replace('"', '\\"')
|
f.write(".global ksyms_count\n")
|
||||||
f.write(f" .{{ .addr = 0x{addr:016x}, .name = \"{escaped}\" }},\n")
|
f.write(".align 8\n")
|
||||||
f.write("};\n")
|
f.write("ksyms_array:\n")
|
||||||
|
|
||||||
|
for i, (addr, name) in enumerate(symbols):
|
||||||
|
name_len = len(name.encode("utf-8"))
|
||||||
|
f.write(f" .quad 0x{addr:016x}\n")
|
||||||
|
f.write(f" .quad .Lstr{i}\n")
|
||||||
|
f.write(f" .quad {name_len}\n")
|
||||||
|
|
||||||
|
f.write("\nksyms_count:\n")
|
||||||
|
f.write(f" .quad {len(symbols)}\n")
|
||||||
|
|||||||
@@ -10,5 +10,8 @@ SECTIONS {
|
|||||||
KEEP(*(.percpu_init_array))
|
KEEP(*(.percpu_init_array))
|
||||||
__init_array_percpu_end = .;
|
__init_array_percpu_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
} INSERT AFTER .data;
|
} INSERT AFTER .data;
|
||||||
|
|
||||||
|
PROVIDE(text_start_addr = ADDR(.text));
|
||||||
|
PROVIDE(text_end_addr = ADDR(.text) + SIZEOF(.text));
|
||||||
|
|||||||
+27
-7
@@ -1,6 +1,8 @@
|
|||||||
const amd64 = @import("arch");
|
const amd64 = @import("arch");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const b = @import("base");
|
const b = @import("base");
|
||||||
|
const ke = b.ke;
|
||||||
|
const ki = ke.private;
|
||||||
|
|
||||||
extern const __interrupt_vectors: [256]usize;
|
extern const __interrupt_vectors: [256]usize;
|
||||||
|
|
||||||
@@ -43,17 +45,35 @@ const exception_msg = [32][]const u8{
|
|||||||
|
|
||||||
export fn isr_handler_main(frame: *const amd64.IrqFrame) callconv(.{ .x86_64_sysv = .{} }) void {
|
export fn isr_handler_main(frame: *const amd64.IrqFrame) callconv(.{ .x86_64_sysv = .{} }) void {
|
||||||
if (frame.intno < 32) {
|
if (frame.intno < 32) {
|
||||||
std.log.info("Unhandled exception: 0x{x} ({s}), err=0x{x}, pc=0x{x}", .{ frame.intno, exception_msg[frame.intno], frame.errcode, frame.rip });
|
std.log.err("Unhandled exception: 0x{x} ({s}), err=0x{x}, pc=0x{x}", .{ frame.intno, exception_msg[frame.intno], frame.errcode, frame.rip });
|
||||||
std.log.info("RAX=0x{x:0>16} RBX=0x{x:0>16} RCX=0x{x:0>16} RDX=0x{x:0>16}", .{ frame.rax, frame.rbx, frame.rcx, frame.rdx });
|
std.log.err("RAX=0x{x:0>16} RBX=0x{x:0>16} RCX=0x{x:0>16} RDX=0x{x:0>16}", .{ frame.rax, frame.rbx, frame.rcx, frame.rdx });
|
||||||
std.log.info("RSI=0x{x:0>16} RDI=0x{x:0>16} RBP=0x{x:0>16} RSP=0x{x:0>16}", .{ frame.rsi, frame.rdi, frame.rbp, frame.rsp });
|
std.log.err("RSI=0x{x:0>16} RDI=0x{x:0>16} RBP=0x{x:0>16} RSP=0x{x:0>16}", .{ frame.rsi, frame.rdi, frame.rbp, frame.rsp });
|
||||||
std.log.info("R8= 0x{x:0>16} R9=0x{x:0>16} R10=0x{x:0>16} R11=0x{x:0>16}", .{ frame.r8, frame.r9, frame.r10, frame.r11 });
|
std.log.err("R8= 0x{x:0>16} R9=0x{x:0>16} R10=0x{x:0>16} R11=0x{x:0>16}", .{ frame.r8, frame.r9, frame.r10, frame.r11 });
|
||||||
std.log.info("R12=0x{x:0>16} R13=0x{x:0>16} R14=0x{x:0>16} R15=0x{x:0>16}", .{ frame.r12, frame.r13, frame.r14, frame.r15 });
|
std.log.err("R12=0x{x:0>16} R13=0x{x:0>16} R14=0x{x:0>16} R15=0x{x:0>16}", .{ frame.r12, frame.r13, frame.r14, frame.r15 });
|
||||||
const cr2 = amd64.read_cr(2);
|
const cr2 = amd64.read_cr(2);
|
||||||
const cr3 = amd64.read_cr(3);
|
const cr3 = amd64.read_cr(3);
|
||||||
const rflags = amd64.rflags();
|
const rflags = amd64.rflags();
|
||||||
std.log.info("CR2=0x{x:0>16} CR3=0x{x:0>16} RFLAGS={x}", .{ cr2, cr3, @as(u64, @bitCast(rflags)) });
|
|
||||||
|
|
||||||
@panic("Unhandled exception");
|
var buf: [128]u8 = undefined;
|
||||||
|
var writer = std.Io.Writer.fixed(&buf);
|
||||||
|
|
||||||
|
writer.print("0x{x:0>8} [", .{@as(u64, @bitCast(rflags))}) catch {};
|
||||||
|
if (rflags.carry) writer.writeAll(" CF") catch {};
|
||||||
|
if (rflags.parity) writer.writeAll(" PF") catch {};
|
||||||
|
if (rflags.auxiliary) writer.writeAll(" AF") catch {};
|
||||||
|
if (rflags.zero) writer.writeAll(" ZF") catch {};
|
||||||
|
if (rflags.sign) writer.writeAll(" SF") catch {};
|
||||||
|
if (rflags.trap) writer.writeAll(" TF") catch {};
|
||||||
|
if (rflags.interrupt_enable) writer.writeAll(" IF") catch {};
|
||||||
|
if (rflags.direction) writer.writeAll(" DF") catch {};
|
||||||
|
if (rflags.overflow) writer.writeAll(" OF") catch {};
|
||||||
|
if (rflags.resume_) writer.writeAll(" RF") catch {};
|
||||||
|
if (rflags.virtual_8086_mode) writer.writeAll(" VM") catch {};
|
||||||
|
writer.print(" IOPL={d}]", .{rflags.iopl}) catch {};
|
||||||
|
|
||||||
|
std.log.err("CR2=0x{x:0>16} CR3=0x{x:0>16} RFLAGS={s}", .{ cr2, cr3, buf[0..writer.end] });
|
||||||
|
|
||||||
|
ki.panic.panic_with_frame("Unhandled exception", frame.rbp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+82
-5
@@ -1,15 +1,92 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const config = @import("config");
|
||||||
const b = @import("base");
|
const b = @import("base");
|
||||||
|
const ksyms = @import("ksyms");
|
||||||
const ke = b.ke;
|
const ke = b.ke;
|
||||||
const ki = ke.private;
|
const ki = ke.private;
|
||||||
|
|
||||||
|
extern var text_start_addr: u8;
|
||||||
|
extern var text_end_addr: u8;
|
||||||
|
|
||||||
|
const StackFrame = struct {
|
||||||
|
prev: ?*StackFrame,
|
||||||
|
return_addr: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Symbol = struct {
|
||||||
|
name: []const u8,
|
||||||
|
offset: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_symbol_name(addr: usize) ?Symbol {
|
||||||
|
const symbols = ksyms.get_symbols();
|
||||||
|
|
||||||
|
// Do a binary search on the ksyms array.
|
||||||
|
// The address may not be exact, so we look for the closest
|
||||||
|
// symbol that is less than or equal to the address.
|
||||||
|
var left: usize = 0;
|
||||||
|
var right: usize = symbols.len;
|
||||||
|
while (left < right) {
|
||||||
|
const mid = left + (right - left) / 2;
|
||||||
|
const sym = symbols[mid];
|
||||||
|
if (sym.addr == addr) {
|
||||||
|
return .{ .name = sym.name_ptr[0..sym.name_len], .offset = 0 };
|
||||||
|
} else if (sym.addr < addr) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
right = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left > 0) {
|
||||||
|
const sym = symbols[left - 1];
|
||||||
|
|
||||||
|
if (sym.addr <= addr) {
|
||||||
|
return .{ .name = sym.name_ptr[0..sym.name_len], .offset = addr - sym.addr };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_kernel_text(addr: usize) bool {
|
||||||
|
const s = @intFromPtr(&text_start_addr);
|
||||||
|
const e = @intFromPtr(&text_end_addr);
|
||||||
|
return addr >= s and addr < e;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn walk_stack_frame(base: usize) void {
|
||||||
|
var frame: ?*StackFrame = @ptrFromInt(base);
|
||||||
|
var depth: usize = 0;
|
||||||
|
while (frame) |f| : (depth += 1) {
|
||||||
|
if (depth > 64) break;
|
||||||
|
const ret_addr = f.return_addr;
|
||||||
|
if (!is_kernel_text(ret_addr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const sym = get_symbol_name(ret_addr) orelse Symbol{ .name = "???", .offset = 0 };
|
||||||
|
std.log.err(" #{d} {s}+0x{x} - 0x{x}", .{ depth, sym.name, sym.offset, ret_addr });
|
||||||
|
frame = f.prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn panic_with_frame(
|
||||||
|
msg: []const u8,
|
||||||
|
frame: usize,
|
||||||
|
) noreturn {
|
||||||
|
std.log.err("KERNEL PANIC: {s}", .{msg});
|
||||||
|
std.log.err("Stack trace:", .{});
|
||||||
|
walk_stack_frame(frame);
|
||||||
|
|
||||||
|
while (true) {}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn panic(
|
pub fn panic(
|
||||||
msg: []const u8,
|
msg: []const u8,
|
||||||
first_trace_addr: ?usize,
|
first_trace_addr: ?usize,
|
||||||
) noreturn {
|
) noreturn {
|
||||||
_ = first_trace_addr;
|
if (@hasDecl(config, "CONFIG_ARCH_UM")) {
|
||||||
|
std.debug.defaultPanic(msg, first_trace_addr);
|
||||||
std.log.err("KERNEL PANIC: {s}", .{msg});
|
}
|
||||||
|
panic_with_frame(msg, @frameAddress());
|
||||||
while (true) {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
pub const KSym = extern struct {
|
||||||
|
addr: u64,
|
||||||
|
name_ptr: [*]const u8,
|
||||||
|
name_len: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const ksyms_array: [0]KSym;
|
||||||
|
extern const ksyms_count: usize;
|
||||||
|
|
||||||
|
pub fn get_symbols() []const KSym {
|
||||||
|
const ptr = @as([*]const KSym, @ptrCast(&ksyms_array));
|
||||||
|
return ptr[0..ksyms_count];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user