From 273ede03312a1b5c537d250403ff11065106e186 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 12 Jun 2011 10:24:15 +0800 Subject: [PATCH] Kernel/x86_64 - Bugfixing - Changed page dump to be more readable - Fixed display issues in page dump - Fixed a broken CallWithArgArray implementation --- Kernel/arch/x86_64/errors.c | 54 ++++++++++++++++++++++++++++ Kernel/arch/x86_64/include/mm_virt.h | 1 + Kernel/arch/x86_64/mm_virt.c | 43 +++++++++++----------- Kernel/arch/x86_64/start64.asm | 53 ++++++++++++++++++++++----- Kernel/system.c | 9 ++++- 5 files changed, 131 insertions(+), 29 deletions(-) diff --git a/Kernel/arch/x86_64/errors.c b/Kernel/arch/x86_64/errors.c index 66ba4434..711846c8 100644 --- a/Kernel/arch/x86_64/errors.c +++ b/Kernel/arch/x86_64/errors.c @@ -4,9 +4,13 @@ */ #include #include +#include + +#define MAX_BACKTRACE 6 // === IMPORTS === void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs); +void Error_Backtrace(Uint IP, Uint BP); // === PROTOTYPES === void Error_Handler(tRegs *Regs); @@ -77,3 +81,53 @@ void Error_Handler(tRegs *Regs) for(;;) __asm__ __volatile__ ("hlt"); } + +/** + * \fn void Error_Backtrace(Uint eip, Uint ebp) + * \brief Unrolls the stack to trace execution + * \param eip Current Instruction Pointer + * \param ebp Current Base Pointer (Stack Frame) + */ +void Error_Backtrace(Uint IP, Uint BP) +{ + int i = 0; + + //if(eip < 0xC0000000 && eip > 0x1000) + //{ + // LogF("Backtrace: User - 0x%x\n", eip); + // return; + //} + + if( IP > MM_USER_MAX + && IP < MM_KERNEL_CODE + && (MM_MODULE_MIN > IP || IP > MM_MODULE_MAX) + ) + { + LogF("Backtrace: Data Area - %p\n", IP); + return; + } + + //str = Debug_GetSymbol(eip, &delta); + //if(str == NULL) + LogF("Backtrace: %p", IP); + //else + // LogF("Backtrace: %s+0x%x", str, delta); + if( !MM_GetPhysAddr(BP) ) + { + LogF("\nBacktrace: Invalid BP, stopping\n"); + return; + } + + + while( MM_GetPhysAddr(BP) && i < MAX_BACKTRACE ) + { + //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta); + //if(str == NULL) + LogF(" >> 0x%llx", ((Uint*)BP)[1]); + //else + // LogF(" >> %s+0x%x", str, delta); + BP = ((Uint*)BP)[0]; + i++; + } + LogF("\n"); +} diff --git a/Kernel/arch/x86_64/include/mm_virt.h b/Kernel/arch/x86_64/include/mm_virt.h index f1c56061..dd520a22 100644 --- a/Kernel/arch/x86_64/include/mm_virt.h +++ b/Kernel/arch/x86_64/include/mm_virt.h @@ -72,6 +72,7 @@ #define MM_FRACTAL_BASE (MM_KERNEL_RANGE|(0xFE00##00000000)) #define MM_TMPFRAC_BASE (MM_KERNEL_RANGE|(0xFE80##00000000)) #define MM_LOCALAPIC (MM_KERNEL_RANGE|(0xFF80##00000000)) +#define MM_KERNEL_CODE (MM_KERNEL_RANGE|(0xFFFF##80000000)) // === FUNCTIONS === diff --git a/Kernel/arch/x86_64/mm_virt.c b/Kernel/arch/x86_64/mm_virt.c index 708f78f8..a0b384db 100644 --- a/Kernel/arch/x86_64/mm_virt.c +++ b/Kernel/arch/x86_64/mm_virt.c @@ -36,18 +36,19 @@ #define PAGEDIRPTR(idx) PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK)) #define PAGEMAPLVL4(idx) PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK)) -#define TMPTABLE(idx) (*((tPAddr*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK))) -#define TMPDIR(idx) TMPTABLE((MM_FRACTAL_BASE>>12)+((idx)&TABLE_MASK)) -#define TMPDIRPTR(idx) TMPDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK)) -#define TMPMAPLVL4(idx) TMPDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK)) #define TMPCR3() PAGEMAPLVL4(MM_TMPFRAC_BASE>>39) +#define TMPTABLE(idx) (*((tPAddr*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK))) +#define TMPDIR(idx) PAGETABLE((MM_TMPFRAC_BASE>>12)+((idx)&TABLE_MASK)) +#define TMPDIRPTR(idx) PAGEDIR((MM_TMPFRAC_BASE>>21)+((idx)&PDP_MASK)) +#define TMPMAPLVL4(idx) PAGEDIRPTR((MM_TMPFRAC_BASE>>30)+((idx)&PML4_MASK)) #define INVLPG(__addr) __asm__ __volatile__ ("invlpg (%0)"::"r"(__addr)); // === CONSTS === //tPAddr * const gaPageTable = MM_FRACTAL_BASE; -// === EXTERNS === +// === IMPORTS === +extern void Error_Backtrace(Uint IP, Uint BP); extern tPAddr gInitialPML4[512]; // === PROTOTYPES === @@ -138,7 +139,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) Log("Code at %p accessed %p", Regs->RIP, Addr); // Print Stack Backtrace -// Error_Backtrace(Regs->RIP, Regs->RBP); + Error_Backtrace(Regs->RIP, Regs->RBP); MM_DumpTables(0, -1); @@ -152,6 +153,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) */ void MM_DumpTables(tVAddr Start, tVAddr End) { + #define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr)) const tPAddr CHANGEABLE_BITS = 0xFF8; const tPAddr MASK = ~CHANGEABLE_BITS; // Physical address and access bits tVAddr rangeStart = 0; @@ -186,17 +188,15 @@ void MM_DumpTables(tVAddr Start, tVAddr End) || (PAGETABLE(page) & MASK) != expected) { if(expected != CHANGEABLE_BITS) { - #define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr)) - Log("%016x-0x%016x => %013x-%013x (%c%c%c%c)", - CANOICAL(rangeStart), CANOICAL(curPos - 1), + Log("%016llx => %013llx : 0x%6llx (%c%c%c%c)", + CANOICAL(rangeStart), PAGETABLE(rangeStart>>12) & ~0xFFF, - (expected & ~0xFFF) - 1, + curPos - rangeStart, (expected & PF_PAGED ? 'p' : '-'), (expected & PF_COW ? 'C' : '-'), (expected & PF_USER ? 'U' : '-'), (expected & PF_WRITE ? 'W' : '-') ); - #undef CANOICAL expected = CHANGEABLE_BITS; } if( !(PAGEMAPLVL4(page>>27) & PF_PRESENT) ) { @@ -227,17 +227,18 @@ void MM_DumpTables(tVAddr Start, tVAddr End) } if(expected != CHANGEABLE_BITS) { - Log("%016x-%016x => %013x-%013x (%s%s%s%s)", - rangeStart, curPos - 1, + Log("%016llx => %013llx : 0x%6llx (%c%c%c%c)", + CANOICAL(rangeStart), PAGETABLE(rangeStart>>12) & ~0xFFF, - (expected & ~0xFFF) - 1, - (expected & PF_PAGED ? "p" : "-"), - (expected & PF_COW ? "C" : "-"), - (expected & PF_USER ? "U" : "-"), - (expected & PF_WRITE ? "W" : "-") + curPos - rangeStart, + (expected & PF_PAGED ? 'p' : '-'), + (expected & PF_COW ? 'C' : '-'), + (expected & PF_USER ? 'U' : '-'), + (expected & PF_WRITE ? 'W' : '-') ); expected = 0; } + #undef CANOICAL } /** @@ -646,15 +647,17 @@ tPAddr MM_Clone(void) Mutex_Acquire(&glMM_TempFractalLock); TMPCR3() = ret | 3; - INVLPG(TMPMAPLVL4(0)); + INVLPG(&TMPMAPLVL4(0)); memcpy(&TMPMAPLVL4(0), &PAGEMAPLVL4(0), 0x1000); Log_KernelPanic("MM", "TODO: Implement MM_Clone"); // #3 Set Copy-On-Write to all user pages + + // #4 Return TMPCR3() = 0; - INVLPG(TMPMAPLVL4(0)); + INVLPG(&TMPMAPLVL4(0)); Mutex_Release(&glMM_TempFractalLock); return 0; } diff --git a/Kernel/arch/x86_64/start64.asm b/Kernel/arch/x86_64/start64.asm index d0cc503f..b0a85868 100644 --- a/Kernel/arch/x86_64/start64.asm +++ b/Kernel/arch/x86_64/start64.asm @@ -106,16 +106,53 @@ Proc_ReturnToUser: CallWithArgArray: push rbp mov rbp, rsp - mov rcx, [rbp+3*8] ; Get NArgs - mov rdx, [rbp+4*8] - -.top: - mov rax, [rdx+rcx*8-8] - push rax - loop .top + push r10 + push r11 + + mov [rbp+2*8], rdi ; Save Ptr to stack - mov rax, [rbp+2*8] + mov r11, rsi ; NArgs + mov r10, rdx ; Args + + ; Arg 1: RDI + mov rdi, [r10] + add r10, 8 + dec r11 + jz .call + ; Arg 2: RSI + mov rsi, [r10] + add r10, 8 + dec r11 + jz .call + ; Arg 3: RDX + mov rdx, [r10] + add r10, 8 + dec r11 + jz .call + ; Arg 4: RCX + mov rcx, [r10] + add r10, 8 + dec r11 + jz .call + ; Arg 5: R8 + mov r8, [r10] + add r10, 8 + dec r11 + jz .call + ; Arg 6: R9 + mov r9, [r10] + add r10, 8 + dec r11 + jz .call + ; No support for more + +.call: + mov rax, [rbp+2*8] ; Ptr call rax + + pop r11 + pop r10 + lea rsp, [rbp] pop rbp ret diff --git a/Kernel/system.c b/Kernel/system.c index a9960384..54508830 100644 --- a/Kernel/system.c +++ b/Kernel/system.c @@ -338,7 +338,8 @@ void System_ExecuteScript(void) if(line->Parts[0][0] == ':') continue; // Ignore labels // Prescan and eliminate variables - for( j = 1; j < line->nParts; j++ ) { + for( j = 1; j < line->nParts; j++ ) + { Log_Debug("Config", "Arg #%i is '%s'", j, line->Parts[j]); bReplaced[j] = 0; if( line->Parts[j][0] != '$' ) continue; @@ -356,13 +357,16 @@ void System_ExecuteScript(void) bReplaced[j] = 1; } + // Find the command name for( j = 0; j < NUM_CONFIG_COMMANDS; j++ ) { Uint args[N_MAX_ARGS]; + if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0) continue; Log_Debug("Config", "Command '%s', %i args passed", line->Parts[0], line->nParts-1); + // Check against minimum argument count if( line->nParts - 1 < caConfigCommands[j].MinArgs ) { Log_Warning("Config", "Configuration command '%s' requires at least %i arguments, %i given", @@ -371,6 +375,7 @@ void System_ExecuteScript(void) break; } + // Check for extra arguments if( line->nParts - 1 > caConfigCommands[j].MaxArgs ) { Log_Warning("Config", "Configuration command '%s' takes at most %i arguments, %i given", @@ -379,10 +384,12 @@ void System_ExecuteScript(void) break; } + // Fill in defaults for( k = caConfigCommands[j].MaxArgs-1; k > line->nParts - 1; k-- ) { args[k] = caConfigCommands[j].OptDefaults[k]; } + // Convert arguments to integers for( k = line->nParts-1; k--; ) { if( caConfigCommands[j].IntArgs & (1 << k) ) { -- 2.20.1