Kernel - Cleaning up proc/syscalls
authorJohn Hodge <[email protected]>
Sat, 15 Oct 2011 00:22:33 +0000 (08:22 +0800)
committerJohn Hodge <[email protected]>
Sat, 15 Oct 2011 00:22:33 +0000 (08:22 +0800)
- Moved SYS_CLONE stack switch to userland
- Cleaned up the Proc_StartUser spec (and removed memory leak)

Kernel/arch/x86/proc.c
Kernel/arch/x86_64/desctab.asm
Kernel/arch/x86_64/proc.c
Kernel/binary.c
Kernel/include/hal_proc.h
Kernel/syscalls.c

index 3c298fc..255765a 100644 (file)
@@ -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);
index c9c217c..2ad44a0 100644 (file)
@@ -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
index ce6ebbd..d05e9ae 100644 (file)
@@ -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);
 }
index 7e271ed..76893a3 100644 (file)
@@ -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;
index e7ca891..fad225b 100644 (file)
@@ -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);
index e304b40..7de7b15 100644 (file)
@@ -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;

UCC git Repository :: git.ucc.asn.au