mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:27:45 +00:00
Kernel: Reduce code duplication in exception handlers.
This commit is contained in:
parent
9763eb44f9
commit
809ffa56d7
2 changed files with 44 additions and 84 deletions
|
@ -171,6 +171,16 @@ template<class T> struct RemovePointer<T* const> { typedef T Type; };
|
||||||
template<class T> struct RemovePointer<T* volatile> { typedef T Type; };
|
template<class T> struct RemovePointer<T* volatile> { typedef T Type; };
|
||||||
template<class T> struct RemovePointer<T* const volatile> { typedef T Type; };
|
template<class T> struct RemovePointer<T* const volatile> { typedef T Type; };
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct IsSame {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsSame<T, T> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using AK::min;
|
using AK::min;
|
||||||
|
@ -180,4 +190,4 @@ using AK::forward;
|
||||||
using AK::exchange;
|
using AK::exchange;
|
||||||
using AK::swap;
|
using AK::swap;
|
||||||
using AK::ceil_div;
|
using AK::ceil_div;
|
||||||
|
using AK::IsSame;
|
||||||
|
|
116
Kernel/i386.cpp
116
Kernel/i386.cpp
|
@ -121,12 +121,9 @@ asm( \
|
||||||
" iret\n" \
|
" iret\n" \
|
||||||
);
|
);
|
||||||
|
|
||||||
// 6: Invalid Opcode
|
template<typename DumpType>
|
||||||
EH_ENTRY_NO_CODE(6);
|
static void dump(const DumpType& regs)
|
||||||
void exception_6_handler(RegisterDump& regs)
|
|
||||||
{
|
{
|
||||||
kprintf("%s invalid opcode: %u(%s)\n", current->is_ring0() ? "Kernel" : "Process", current->pid(), current->name().characters());
|
|
||||||
|
|
||||||
word ss;
|
word ss;
|
||||||
dword esp;
|
dword esp;
|
||||||
if (current->is_ring0()) {
|
if (current->is_ring0()) {
|
||||||
|
@ -137,11 +134,37 @@ void exception_6_handler(RegisterDump& regs)
|
||||||
esp = regs.esp_if_crossRing;
|
esp = regs.esp_if_crossRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (IsSame<DumpType, RegisterDumpWithExceptionCode>::value) {
|
||||||
|
kprintf("exception code: %w\n", regs.exception_code);
|
||||||
|
}
|
||||||
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
||||||
kprintf("stk=%w:%x\n", ss, esp);
|
kprintf("stk=%w:%x\n", ss, esp);
|
||||||
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
||||||
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
||||||
|
|
||||||
|
if (current->validate_read((void*)regs.eip, 8)) {
|
||||||
|
byte* codeptr = (byte*)regs.eip;
|
||||||
|
kprintf("code: %b %b %b %b %b %b %b %b\n",
|
||||||
|
codeptr[0],
|
||||||
|
codeptr[1],
|
||||||
|
codeptr[2],
|
||||||
|
codeptr[3],
|
||||||
|
codeptr[4],
|
||||||
|
codeptr[5],
|
||||||
|
codeptr[6],
|
||||||
|
codeptr[7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 6: Invalid Opcode
|
||||||
|
EH_ENTRY_NO_CODE(6);
|
||||||
|
void exception_6_handler(RegisterDump& regs)
|
||||||
|
{
|
||||||
|
kprintf("%s invalid opcode: %u(%s)\n", current->is_ring0() ? "Kernel" : "Process", current->pid(), current->name().characters());
|
||||||
|
|
||||||
|
dump(regs);
|
||||||
|
|
||||||
if (current->is_ring0()) {
|
if (current->is_ring0()) {
|
||||||
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
||||||
hang();
|
hang();
|
||||||
|
@ -176,21 +199,7 @@ void exception_7_handler(RegisterDump& regs)
|
||||||
|
|
||||||
#ifdef FPU_EXCEPTION_DEBUG
|
#ifdef FPU_EXCEPTION_DEBUG
|
||||||
kprintf("%s FPU not available exception: %u(%s)\n", current->is_ring0() ? "Kernel" : "Process", current->pid(), current->name().characters());
|
kprintf("%s FPU not available exception: %u(%s)\n", current->is_ring0() ? "Kernel" : "Process", current->pid(), current->name().characters());
|
||||||
|
dump(regs);
|
||||||
word ss;
|
|
||||||
dword esp;
|
|
||||||
if (current->is_ring0()) {
|
|
||||||
ss = regs.ds;
|
|
||||||
esp = regs.esp;
|
|
||||||
} else {
|
|
||||||
ss = regs.ss_if_crossRing;
|
|
||||||
esp = regs.esp_if_crossRing;
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
|
||||||
kprintf("stk=%w:%x\n", ss, esp);
|
|
||||||
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
|
||||||
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,20 +210,7 @@ void exception_0_handler(RegisterDump& regs)
|
||||||
{
|
{
|
||||||
kprintf("%s DIVIDE ERROR: %u(%s)\n", current->is_ring0() ? "Kernel" : "User", current->pid(), current->name().characters());
|
kprintf("%s DIVIDE ERROR: %u(%s)\n", current->is_ring0() ? "Kernel" : "User", current->pid(), current->name().characters());
|
||||||
|
|
||||||
word ss;
|
dump(regs);
|
||||||
dword esp;
|
|
||||||
if (current->is_ring0()) {
|
|
||||||
ss = regs.ds;
|
|
||||||
esp = regs.esp;
|
|
||||||
} else {
|
|
||||||
ss = regs.ss_if_crossRing;
|
|
||||||
esp = regs.esp_if_crossRing;
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
|
||||||
kprintf("stk=%w:%x\n", ss, esp);
|
|
||||||
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
|
||||||
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
|
||||||
|
|
||||||
if (current->is_ring0()) {
|
if (current->is_ring0()) {
|
||||||
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
||||||
|
@ -231,21 +227,7 @@ void exception_13_handler(RegisterDumpWithExceptionCode& regs)
|
||||||
{
|
{
|
||||||
kprintf("%s GPF: %u(%s)\n", current->is_ring0() ? "Kernel" : "User", current->pid(), current->name().characters());
|
kprintf("%s GPF: %u(%s)\n", current->is_ring0() ? "Kernel" : "User", current->pid(), current->name().characters());
|
||||||
|
|
||||||
word ss;
|
dump(regs);
|
||||||
dword esp;
|
|
||||||
if (current->is_ring0()) {
|
|
||||||
ss = regs.ds;
|
|
||||||
esp = regs.esp;
|
|
||||||
} else {
|
|
||||||
ss = regs.ss_if_crossRing;
|
|
||||||
esp = regs.esp_if_crossRing;
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("exception code: %w\n", regs.exception_code);
|
|
||||||
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
|
||||||
kprintf("stk=%w:%x\n", ss, esp);
|
|
||||||
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
|
||||||
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
|
||||||
|
|
||||||
if (current->is_ring0()) {
|
if (current->is_ring0()) {
|
||||||
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
kprintf("Oh shit, we've crashed in ring 0 :(\n");
|
||||||
|
@ -278,40 +260,8 @@ void exception_14_handler(RegisterDumpWithExceptionCode& regs)
|
||||||
faultAddress);
|
faultAddress);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
word ss;
|
|
||||||
dword esp;
|
|
||||||
if (current->is_ring0()) {
|
|
||||||
ss = regs.ds;
|
|
||||||
esp = regs.esp;
|
|
||||||
} else {
|
|
||||||
ss = regs.ss_if_crossRing;
|
|
||||||
esp = regs.esp_if_crossRing;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dump_registers_and_code = [&] {
|
|
||||||
dbgprintf("exception code: %w\n", regs.exception_code);
|
|
||||||
dbgprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
|
||||||
dbgprintf("stk=%w:%x\n", ss, esp);
|
|
||||||
dbgprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
|
||||||
dbgprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
|
|
||||||
|
|
||||||
if (current->validate_read((void*)regs.eip, 8)) {
|
|
||||||
byte* codeptr = (byte*)regs.eip;
|
|
||||||
dbgprintf("code: %b %b %b %b %b %b %b %b\n",
|
|
||||||
codeptr[0],
|
|
||||||
codeptr[1],
|
|
||||||
codeptr[2],
|
|
||||||
codeptr[3],
|
|
||||||
codeptr[4],
|
|
||||||
codeptr[5],
|
|
||||||
codeptr[6],
|
|
||||||
codeptr[7]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef PAGE_FAULT_DEBUG
|
#ifdef PAGE_FAULT_DEBUG
|
||||||
dump_registers_and_code();
|
dump(regs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto response = MM.handle_page_fault(PageFault(regs.exception_code, LinearAddress(faultAddress)));
|
auto response = MM.handle_page_fault(PageFault(regs.exception_code, LinearAddress(faultAddress)));
|
||||||
|
@ -322,7 +272,7 @@ void exception_14_handler(RegisterDumpWithExceptionCode& regs)
|
||||||
current->pid(),
|
current->pid(),
|
||||||
regs.exception_code & 2 ? "write" : "read",
|
regs.exception_code & 2 ? "write" : "read",
|
||||||
faultAddress);
|
faultAddress);
|
||||||
dump_registers_and_code();
|
dump(regs);
|
||||||
current->crash();
|
current->crash();
|
||||||
} else if (response == PageFaultResponse::Continue) {
|
} else if (response == PageFaultResponse::Continue) {
|
||||||
#ifdef PAGE_FAULT_DEBUG
|
#ifdef PAGE_FAULT_DEBUG
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue