Kernel - Fixing very slow CheckMem function
[tpg/acess2.git] / Kernel / binary.c
index 94c347f..8c28d72 100644 (file)
@@ -28,7 +28,6 @@ extern char   *Threads_GetName(int ID);
 extern tKernelSymbol   gKernelSymbols[];
 extern tKernelSymbol   gKernelSymbolsEnd[];
 extern tBinaryType     gELF_Info;
-extern void    MM_DumpTables(tVAddr, tVAddr);
 
 // === PROTOTYPES ===
  int   Proc_Execve(const char *File, const char **ArgV, const char **EnvP);
@@ -92,7 +91,6 @@ int Proc_Spawn(const char *Path)
 }
 
 /**
- * \fn int Proc_Execve(char *File, char **ArgV, char **EnvP)
  * \brief Replace the current user image with another
  * \param File File to load as the next image
  * \param ArgV Arguments to pass to user
@@ -107,7 +105,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);
        
@@ -119,6 +117,7 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP)
                argenvBytes += strlen(ArgV[argc])+1;
        for( envc = 0; EnvP && EnvP[envc]; envc++ )
                argenvBytes += strlen(EnvP[envc])+1;
+       LOG("argc = %i, envc = %i", envc);
        argenvBytes = (argenvBytes + sizeof(void*)-1) & ~(sizeof(void*)-1);
        argenvBytes += (argc+1)*sizeof(void*) + (envc+1)*sizeof(void*);
        
@@ -137,6 +136,7 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP)
        {
                argvSaved[i] = strBuf;
                strcpy(argvSaved[i], ArgV[i]);
+               LOG("argv[%i] = '%s'", i, strBuf);
                strBuf += strlen(ArgV[i])+1;
        }
        argvSaved[i] = NULL;
@@ -144,6 +144,7 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP)
        for( i = 0; i < envc; i++ )
        {
                envpSaved[i] = strBuf;
+               LOG("envp[%i] = '%s'", i, strBuf);
                strcpy(envpSaved[i], EnvP[i]);
                strBuf += strlen(EnvP[i])+1;
        }
@@ -159,31 +160,32 @@ 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);
+//     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
 }
 
 /**
- * \fn tVAddr Binary_Load(char *Path, tVAddr *EntryPoint)
  * \brief Load a binary into the current address space
  * \param Path Path to binary to load
  * \param EntryPoint   Pointer for exectuable entry point
+ * \return Virtual address where the binary has been loaded
  */
 tVAddr Binary_Load(const char *Path, tVAddr *EntryPoint)
 {
@@ -218,6 +220,7 @@ tVAddr Binary_Load(const char *Path, tVAddr *EntryPoint)
                VFS_Close(fd);
                mount_id = info.mount;
                inode = info.inode;
+               LOG("mount_id = %i, inode = %i", mount_id, inode);
        }
 
        // TODO: Also get modifcation time?
@@ -261,26 +264,29 @@ tVAddr Binary_Load(const char *Path, tVAddr *EntryPoint)
 
 /**
  * \brief Finds a matching binary entry
- * \param TruePath     File Identifier (True path name)
+ * \param MountID      Mountpoint ID of binary file
+ * \param InodeID      Inode ID of the file
+ * \return Pointer to the binary definition (if already loaded)
  */
 tBinary *Binary_GetInfo(tMount MountID, tInode InodeID)
 {
        tBinary *pBinary;
-       pBinary = glLoadedBinaries;
-       while(pBinary)
+       for(pBinary = glLoadedBinaries; pBinary; pBinary = pBinary->Next)
        {
                if(pBinary->MountID == MountID && pBinary->Inode == InodeID)
                        return pBinary;
-               pBinary = pBinary->Next;
        }
        return NULL;
 }
 
 /**
- \fn Uint Binary_MapIn(tBinary *binary)
- \brief Maps an already-loaded binary into an address space.
- \param binary Pointer to globally stored data.
-*/
+ * \brief Maps an already-loaded binary into an address space.
+ * \param Binary       Pointer to globally stored binary definition
+ * \param Path Path to the binary's file (for debug)
+ * \param LoadMin      Lowest location to map to
+ * \param LoadMax      Highest location to map to
+ * \return Base load address
+ */
 tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr LoadMax)
 {
        tVAddr  base;
@@ -298,7 +304,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
        if(base != 0)
        {
                LOG("Checking base %p", base);
-               for(i=0;i<Binary->NumSections;i++)
+               for( i = 0; i < Binary->NumSections; i ++ )
                {
                        if( Binary_int_CheckMemFree( Binary->LoadSections[i].Virtual, Binary->LoadSections[i].MemSize ) )
                        {
@@ -344,13 +350,14 @@ 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;
 
                if( sect->Flags & BIN_SECTFLAG_EXEC )
                        protflags |= MMAP_PROT_EXEC;
+               // Read only pages are COW
                if( sect->Flags & BIN_SECTFLAG_RO  ) {
                        VFS_MMap( (void*)addr, sect->FileSize, protflags, MMAP_MAP_SHARED|mapflags, fd, sect->Offset );
                }
@@ -358,6 +365,8 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
                        protflags |= MMAP_PROT_WRITE;
                        VFS_MMap( (void*)addr, sect->FileSize, protflags, MMAP_MAP_PRIVATE|mapflags, fd, sect->Offset );
                }
+               
+               // Apply anonymous memory for BSS
                if( sect->FileSize < sect->MemSize ) {
                        mapflags |= MMAP_MAP_ANONYMOUS;
                        VFS_MMap(
@@ -369,8 +378,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
        }
        
        Log_Debug("Binary", "PID %i - Mapped '%s' to 0x%x", Threads_GetPID(), Path, base);
-       
-       //LOG("*0x%x = 0x%x\n", binary->Pages[0].Virtual, *(Uint*)binary->Pages[0].Virtual);
+       VFS_Close(fd);
        
        LEAVE('p', base);
        return base;
@@ -413,7 +421,7 @@ tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path)
 {
        tBinary *pBinary;
         int    fp;
-       Uint    ident;
+       Uint32  ident;
        tBinaryType     *bt = gRegBinTypes;
        
        ENTER("iMountID XInode sPath", MountID, Inode, Path);
@@ -425,19 +433,26 @@ tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path)
                LEAVE('n');
                return NULL;
        }
+
+       LOG("fp = 0x%x", fp);
        
        // Read File Type
        VFS_Read(fp, 4, &ident);
        VFS_Seek(fp, 0, SEEK_SET);
 
+       LOG("ident = 0x%x", ident);
+
        // Determine the type   
        for(; bt; bt = bt->Next)
        {
-               if( (ident & bt->Mask) != (Uint)bt->Ident )
+               if( (ident & bt->Mask) != (Uint32)bt->Ident )
                        continue;
+               LOG("bt = %p (%s)", bt, bt->Name);
                pBinary = bt->Load(fp);
                break;
        }
+
+       LOG("pBinary = %p", pBinary);
        
        // Close File
        VFS_Close(fp);

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