From 61c8b3334fb9bb3c1fb48d9f1f3508ffbe5341bf Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 15 Oct 2011 08:22:33 +0800 Subject: [PATCH] Kernel - Cleaning up proc/syscalls - Moved SYS_CLONE stack switch to userland - Cleaned up the Proc_StartUser spec (and removed memory leak) --- Kernel/arch/x86/proc.c | 42 ++++++++++++---------------------- Kernel/arch/x86_64/desctab.asm | 2 +- Kernel/arch/x86_64/proc.c | 20 +++++++--------- Kernel/binary.c | 13 ++++++----- Kernel/include/hal_proc.h | 11 ++++++++- Kernel/syscalls.c | 6 ++--- 6 files changed, 42 insertions(+), 52 deletions(-) diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 3c298fce..255765a8 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -75,7 +75,7 @@ void Proc_ChangeStack(void); // int Proc_Clone(Uint *Err, Uint Flags); Uint Proc_MakeUserStack(void); //void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize); -void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP); +void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NORETURN; int Proc_Demote(Uint *Err, int Dest, tRegs *Regs); //void Proc_CallFaultHandler(tThread *Thread); //void Proc_DumpThreadCPUState(tThread *Thread); @@ -695,51 +695,37 @@ Uint Proc_MakeUserStack(void) return base + USER_STACK_SZ; } -/** - * \fn void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) - * \brief Starts a user task - */ -void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) +void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, char **ArgV, int DataSize) { - Uint *stack = (void*)Proc_MakeUserStack(); + Uint *stack; int i; - Uint delta; + char **envp = NULL; Uint16 ss, cs; - //Log("stack = %p", stack); - - // Copy Arguments + // Copy data to the user stack and free original buffer + stack = (void*)Proc_MakeUserStack(); stack -= DataSize/sizeof(*stack); memcpy( stack, ArgV, DataSize ); + free(ArgV); - //Log("stack = %p", stack); - + // Adjust Arguments and environment if( DataSize ) { - // Adjust Arguments and environment - delta = (Uint)stack - (Uint)ArgV; + Uint delta = (Uint)stack - (Uint)ArgV; ArgV = (char**)stack; - for( i = 0; ArgV[i]; i++ ) - ArgV[i] += delta; - i ++; - - // Do we care about EnvP? - if( EnvP ) { - EnvP = &ArgV[i]; - for( i = 0; EnvP[i]; i++ ) - EnvP[i] += delta; - } + for( i = 0; ArgV[i]; i++ ) ArgV[i] += delta; + envp = &ArgV[i+1]; + for( i = 0; envp[i]; i++ ) envp[i] += delta; } // User Mode Segments ss = 0x23; cs = 0x1B; // Arguments - *--stack = (Uint)EnvP; + *--stack = (Uint)envp; *--stack = (Uint)ArgV; *--stack = (Uint)ArgC; - while(*Bases) - *--stack = *Bases++; + *--stack = Base; *--stack = 0; // Return Address Proc_StartProcess(ss, (Uint)stack, 0x202, cs, Entrypoint); diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index c9c217c4..2ad44a0c 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -394,7 +394,7 @@ SyscallStub: ; R9 sub rsp, (6+2)*8 mov [rsp+0x00], rax ; Number -; mov [rsp+0x08], rax ; Errno (don't care really) +; mov [rsp+0x08], rax ; Errno (output only) mov [rsp+0x10], rdi ; Arg1 mov [rsp+0x18], rsi ; Arg2 mov [rsp+0x20], rdx ; Arg3 diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index ce6ebbde..d05e9ae6 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -592,13 +592,10 @@ Uint Proc_MakeUserStack(void) } -/** - * \fn void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) - * \brief Starts a user task - */ -void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) +void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, char **ArgV, int DataSize) { Uint *stack = (void*)Proc_MakeUserStack(); + char **envp; int i; Uint delta; Uint16 ss, cs; @@ -606,27 +603,26 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char ** LOG("stack = 0x%x", stack); // Copy Arguments - stack = (void*)( (Uint)stack - DataSize ); + stack = (void*)( Proc_MakeUserStack() - DataSize ); memcpy( stack, ArgV, DataSize ); + free(ArgV); // Adjust Arguments and environment delta = (Uint)stack - (Uint)ArgV; ArgV = (char**)stack; for( i = 0; ArgV[i]; i++ ) ArgV[i] += delta; - i ++; - EnvP = &ArgV[i]; - for( i = 0; EnvP[i]; i++ ) EnvP[i] += delta; + envp = &ArgV[i+1]; + for( i = 0; envp[i]; i++ ) envp[i] += delta; // User Mode Segments // 0x2B = 64-bit ss = 0x23; cs = 0x2B; // Arguments - *--stack = (Uint)EnvP; + *--stack = (Uint)envp; *--stack = (Uint)ArgV; *--stack = (Uint)ArgC; - while(*Bases) - *--stack = *Bases++; + *--stack = Base; Proc_StartProcess(ss, (Uint)stack, 0x202, cs, Entrypoint); } diff --git a/Kernel/binary.c b/Kernel/binary.c index 7e271ed7..76893a38 100644 --- a/Kernel/binary.c +++ b/Kernel/binary.c @@ -106,7 +106,7 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP) char **argvSaved, **envpSaved; char *savedFile; tVAddr entry; - Uint bases[2] = {0}; // Uint because Proc_StartUser wants it + Uint base; // Uint because Proc_StartUser wants it ENTER("sFile pArgV pEnvP", File, ArgV, EnvP); @@ -158,23 +158,24 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP) MM_ClearUser(); // --- Load new binary - bases[0] = Binary_Load(savedFile, &entry); + base = Binary_Load(savedFile, &entry); free(savedFile); - if(bases[0] == 0) + if(base == 0) { + free(argvSaved); Log_Warning("Binary", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1)); LEAVE('-'); Threads_Exit(0, -10); for(;;); } - LOG("entry = 0x%x, bases[0] = 0x%x", entry, bases[0]); + LOG("entry = 0x%x, base = 0x%x", entry, base); // MM_DumpTables(0, KERNEL_BASE); LEAVE('-'); // --- And... Jump to it - Proc_StartUser(entry, bases, argc, argvSaved, envpSaved, argenvBytes); + Proc_StartUser(entry, base, argc, argvSaved, argenvBytes); for(;;); // Tell GCC that we never return } @@ -344,7 +345,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo tBinarySection *sect = &Binary->LoadSections[i]; Uint protflags, mapflags; tVAddr addr = sect->Virtual - Binary->Base + base; - LOG("%i - %p to 0x%llx (%x)", i, addr, sect->Offset, sect->Flags); + LOG("%i - %p to offset 0x%llx (%x)", i, addr, sect->Offset, sect->Flags); protflags = MMAP_PROT_READ; mapflags = MMAP_MAP_FIXED; diff --git a/Kernel/include/hal_proc.h b/Kernel/include/hal_proc.h index e7ca8918..fad225b8 100644 --- a/Kernel/include/hal_proc.h +++ b/Kernel/include/hal_proc.h @@ -15,7 +15,16 @@ extern void ArchThreads_Init(void); extern void Proc_Start(void); extern int GetCPUNum(void); extern tTID Proc_Clone(Uint Flags); -extern void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize); +/** + * \brief Start a user task + * \param Entrypoint User entrypoint + * \param Base Base of executable (argument for ld-acess) + * \param ArgC Number of arguments when the program was invoked + * \param ArgV Heap allocated arguments and environment (two NULL terminated lists) + * \param DataSize Size of the \a ArgV buffer in bytes + * \note This function should free \a ArgV + */ +extern void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, char **ArgV, int DataSize) NORETURN; extern void Proc_CallFaultHandler(tThread *Thread); extern void Proc_DumpThreadCPUState(tThread *Thread); extern void Proc_Reschedule(void); diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index e304b40e..7de7b15d 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -68,9 +68,6 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_CLONE: // Call clone system call ret = Proc_Clone(Regs->Arg1); - // Change user stack if a new stack address is passed - if(ret == 0 && Regs->Arg2) - Regs->StackPointer = Regs->Arg2; break; // -- Send a signal @@ -315,8 +312,9 @@ void SyscallHandler(tSyscallRegs *Regs) // -- Debug //#if DEBUG_BUILD case SYS_DEBUG: + CHECK_STR_NONULL( (char*)Regs->Arg1 ); LogF("Log: [%i] ", Threads_GetTID()); - LogF((char*)Regs->Arg1, + LogF((const char*)Regs->Arg1, Regs->Arg2, Regs->Arg3, Regs->Arg4, Regs->Arg5, Regs->Arg6); LogF("\r\n"); break; -- 2.20.1