Replace rand() implementation - fixes threading lockups
[tpg/acess2.git] / Kernel / binary.c
index 9455a62..dffb178 100644 (file)
@@ -2,7 +2,7 @@
  * Acess2
  * Common Binary Loader
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <binary.h>
 #include <mm_virt.h>
@@ -10,7 +10,6 @@
 // === CONSTANTS ===
 #define BIN_LOWEST     MM_USER_MIN             // 1MiB
 #define BIN_GRANUALITY 0x10000         // 64KiB
-//! \todo Move 0xBC000000 to mm_virt.h
 #define BIN_HIGHEST    (USER_LIB_MAX-BIN_GRANUALITY)           // Just below the kernel
 #define        KLIB_LOWEST     MM_MODULE_MIN
 #define KLIB_GRANUALITY        0x10000         // 32KiB
@@ -46,11 +45,11 @@ Uint        Binary_GetSymbolEx(char *Name, Uint *Value);
 Uint   Binary_FindSymbol(void *Base, char *Name, Uint *Val);
 
 // === GLOBALS ===
- int   glBinListLock = 0;
+tShortSpinlock glBinListLock;
 tBinary        *glLoadedBinaries = NULL;
 char   **gsaRegInterps = NULL;
  int   giRegInterps = 0;
- int   glKBinListLock = 0;
+tShortSpinlock glKBinListLock;
 tKernelBin     *glLoadedKernelLibs;
 tBinaryType    *gRegBinTypes = &gELF_Info;
  
@@ -121,7 +120,8 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
        // Allocate
        argenvBuf = malloc(argenvBytes);
        if(argenvBuf == NULL) {
-               Warning("Proc_Execve - What the hell? The kernel is out of heap space");
+               Log_Error("BIN", "Proc_Execve - What the hell? The kernel is out of heap space");
+               LEAVE('i', 0);
                return 0;
        }
        strBuf = argenvBuf + (argc+1)*sizeof(void*) + (envc+1)*sizeof(void*);
@@ -142,6 +142,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
                strcpy(envpSaved[i], EnvP[i]);
                strBuf += strlen(EnvP[i])+1;
        }
+       envpSaved[i] = NULL;
        
        savedFile = malloc(strlen(File)+1);
        strcpy(savedFile, File);
@@ -157,7 +158,8 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
        free(savedFile);
        if(bases[0] == 0)
        {
-               Warning("Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
+               Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
+               LEAVE('-');
                Threads_Exit(0, 0);
                for(;;);
        }
@@ -171,6 +173,9 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
 
 /**
  * \fn Uint Binary_Load(char *file, Uint *entryPoint)
+ * \brief Load a binary into the current address space
+ * \param file Path to binary to load
+ * \param entryPoint   Pointer for exectuable entry point
  */
 Uint Binary_Load(char *file, Uint *entryPoint)
 {
@@ -178,7 +183,7 @@ Uint Binary_Load(char *file, Uint *entryPoint)
        tBinary *pBinary;
        Uint    base = -1;
 
-       ENTER("sfile", file);
+       ENTER("sfile pentryPoint", file, entryPoint);
        
        // Sanity Check Argument
        if(file == NULL) {
@@ -188,14 +193,17 @@ Uint Binary_Load(char *file, Uint *entryPoint)
 
        // Get True File Path
        sTruePath = VFS_GetTruePath(file);
+       LOG("sTruePath = %p", sTruePath);
        
        if(sTruePath == NULL) {
-               Warning("[BIN  ] '%s' does not exist.", file);
+               Log_Warning("BIN", "'%s' does not exist.", file);
                LEAVE('x', 0);
                return 0;
        }
        
        LOG("sTruePath = '%s'", sTruePath);
+       
+       // TODO: Also get modifcation time
 
        // Check if the binary has already been loaded
        if( !(pBinary = Binary_GetInfo(sTruePath)) )
@@ -314,7 +322,7 @@ Uint Binary_MapIn(tBinary *binary)
        
        // Error Check
        if(base < BIN_LOWEST) {
-               Warning("[BIN ] Executable '%s' cannot be loaded, no space", binary->TruePath);
+               Log_Warning("BIN", "Executable '%s' cannot be loaded, no space", binary->TruePath);
                return 0;
        }
        
@@ -341,7 +349,7 @@ Uint Binary_MapIn(tBinary *binary)
                
        }
        
-       //Log("Mapped '%s' to 0x%x", binary->TruePath, base);
+       Log_Debug("Binary", "PID %i - Mapped '%s' to 0x%x", Threads_GetPID(), binary->TruePath, base);
        
        //LOG("*0x%x = 0x%x\n", binary->Pages[0].Virtual, *(Uint*)binary->Pages[0].Virtual);
        
@@ -410,7 +418,7 @@ tBinary *Binary_DoLoad(char *truePath)
                break;
        }
        if(!bt) {
-               Warning("[BIN ] '%s' is an unknown file type. (0x%x 0x%x 0x%x 0x%x)",
+               Log_Warning("BIN", "'%s' is an unknown file type. (%02x %02x %02x %02x)",
                        truePath, ident&0xFF, (ident>>8)&0xFF, (ident>>16)&0xFF, (ident>>24)&0xFF);
                LEAVE('n');
                return NULL;
@@ -433,13 +441,13 @@ tBinary *Binary_DoLoad(char *truePath)
        LOG("NumPages: %i", pBinary->NumPages);
        
        // Read Data
-       for(i=0;i<pBinary->NumPages;i++)
+       for(i = 0; i < pBinary->NumPages; i ++)
        {
                Uint    dest;
                tPAddr  paddr;
                paddr = (Uint)MM_AllocPhys();
                if(paddr == 0) {
-                       Warning("Binary_DoLoad - Physical memory allocation failed");
+                       Log_Warning("BIN", "Binary_DoLoad - Physical memory allocation failed");
                        for( ; i--; ) {
                                MM_DerefPhys( pBinary->Pages[i].Physical );
                        }
@@ -460,12 +468,34 @@ tBinary *Binary_DoLoad(char *truePath)
                else
                {
                        VFS_Seek( fp, pBinary->Pages[i].Physical, 1 );
-                       if(pBinary->Pages[i].Size != 0x1000) {
+                       // If the address is not aligned, or the page is not full
+                       // sized, copy part of it
+                       if( (dest & 0xFFF) > 0 || pBinary->Pages[i].Size < 0x1000)
+                       {
+                               // Validate the size to prevent Kernel page faults
+                               // Clips to one page and prints a warning
+                               if( pBinary->Pages[i].Size + (dest & 0xFFF) > 0x1000) {
+                                       Log_Warning("Binary", "Loader error: Page %i (%p) of '%s' is %i bytes (> 4096)",
+                                               i, pBinary->Pages[i].Virtual, truePath,
+                                               (dest&0xFFF) + pBinary->Pages[i].Size);
+                                       pBinary->Pages[i].Size = 0x1000 - (dest & 0xFFF);
+                               }               
                                LOG("%i - 0x%llx - 0x%x bytes",
                                        i, pBinary->Pages[i].Physical, pBinary->Pages[i].Size);
-                               memset( (void*)dest, 0, 0x1000 -(dest&0xFFF) );
+                               // Zero from `dest` to the end of the page
+                               memset( (void*)dest, 0, 0x1000 - (dest&0xFFF) );
+                               // Read in the data
                                VFS_Read( fp, pBinary->Pages[i].Size, (void*)dest );
-                       } else {
+                       }
+                       // Full page
+                       else
+                       {
+                               // Check if the page is oversized
+                               if(pBinary->Pages[i].Size > 0x1000)
+                                       Log_Warning("Binary", "Loader error - Page %i (%p) of '%s' is %i bytes (> 4096)",
+                                               i, pBinary->Pages[i].Virtual, truePath,
+                                               pBinary->Pages[i].Size);
+                               // Read data
                                LOG("%i - 0x%x", i, pBinary->Pages[i].Physical);
                                VFS_Read( fp, 0x1000, (void*)dest );
                        }
@@ -479,10 +509,10 @@ tBinary *Binary_DoLoad(char *truePath)
        VFS_Close(fp);
        
        // Add to the list
-       LOCK(&glBinListLock);
+       SHORTLOCK(&glBinListLock);
        pBinary->Next = glLoadedBinaries;
        glLoadedBinaries = pBinary;
-       RELEASE(&glBinListLock);
+       SHORTREL(&glBinListLock);
        
        // Return
        LEAVE('p', pBinary);
@@ -504,7 +534,7 @@ void Binary_Unload(void *Base)
        if((Uint)Base < 0xC0000000)
        {
                // TODO: User Binaries
-               Warning("[BIN ] Unloading user binaries is currently unimplemented");
+               Log_Warning("BIN", "Unloading user binaries is currently unimplemented");
                return;
        }
        
@@ -686,7 +716,7 @@ void *Binary_LoadKernel(char *File)
        
        // - Error Check
        if(base >= KLIB_HIGHEST) {
-               Warning("[BIN ] Executable '%s' cannot be loaded into kernel, no space", pBinary->TruePath);
+               Log_Warning("BIN", "Executable '%s' cannot be loaded into kernel, no space", pBinary->TruePath);
                Binary_Dereference( pBinary );
                LEAVE('n');
                return 0;
@@ -723,10 +753,10 @@ void *Binary_LoadKernel(char *File)
        pKBinary = malloc(sizeof(*pKBinary));
        pKBinary->Base = (void*)base;
        pKBinary->Info = pBinary;
-       LOCK( &glKBinListLock );
+       SHORTLOCK( &glKBinListLock );
        pKBinary->Next = glLoadedKernelLibs;
        glLoadedKernelLibs = pKBinary;
-       RELEASE( &glKBinListLock );
+       SHORTREL( &glKBinListLock );
        
        LEAVE('p', base);
        return (void*)base;
@@ -749,7 +779,7 @@ Uint Binary_Relocate(void *Base)
                        return bt->Relocate( (void*)Base);
        }
        
-       Warning("[BIN ] 0x%x is an unknown file type. (0x%x 0x%x 0x%x 0x%x)",
+       Log_Warning("BIN", "%p is an unknown file type. (%02x %02x %02x %02x)",
                Base, ident&0xFF, (ident>>8)&0xFF, (ident>>16)&0xFF, (ident>>24)&0xFF);
        return 0;
 }
@@ -800,7 +830,7 @@ Uint Binary_GetSymbolEx(char *Name, Uint *Value)
                }
        }
        
-       Warning("[BIN ] Unable to find symbol '%s'", Name);
+       Log_Warning("BIN", "Unable to find symbol '%s'", Name);
        return 0;
 }
 
@@ -822,7 +852,7 @@ Uint Binary_FindSymbol(void *Base, char *Name, Uint *Val)
                        return bt->GetSymbol(Base, Name, Val);
        }
        
-       Warning("[BIN ] 0x%x is an unknown file type. (0x%x 0x%x 0x%x 0x%x)",
+       Log_Warning("BIN", "Binary_FindSymbol - %p is an unknown file type. (%02x %02x %02x %02x)",
                Base, ident&0xFF, ident>>8, ident>>16, ident>>24);
        return 0;
 }

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