X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fbinary.c;h=76f84ed864f777e52a178b9dc3c5cf0de552b816;hb=d7d0479311c4dba418ee880f27f01418fd536344;hp=de4d813b787716133c95e235f307461cd9725cf5;hpb=e29b02ca55d580b2f7f10d1093c3d6ad1bc59458;p=tpg%2Facess2.git diff --git a/Kernel/binary.c b/Kernel/binary.c index de4d813b..76f84ed8 100644 --- a/Kernel/binary.c +++ b/Kernel/binary.c @@ -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 @@ -26,31 +25,34 @@ typedef struct sKernelBin { // === IMPORTS === extern int Proc_Clone(Uint *Err, Uint Flags); extern char *Threads_GetName(int ID); -extern void Threads_Exit(int, int); extern Uint MM_ClearUser(void); extern void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize); extern tKernelSymbol gKernelSymbols[]; -extern void gKernelSymbolsEnd; +extern tKernelSymbol gKernelSymbolsEnd[]; extern tBinaryType gELF_Info; // === PROTOTYPES === - int Proc_Execve(char *File, char **ArgV, char **EnvP); -Uint Binary_Load(char *file, Uint *entryPoint); -tBinary *Binary_GetInfo(char *truePath); + int Proc_Execve(const char *File, const char **ArgV, const char **EnvP); +Uint Binary_Load(const char *file, Uint *entryPoint); +tBinary *Binary_GetInfo(const char *truePath); Uint Binary_MapIn(tBinary *binary); Uint Binary_IsMapped(tBinary *binary); -tBinary *Binary_DoLoad(char *truePath); +tBinary *Binary_DoLoad(const char *truePath); void Binary_Dereference(tBinary *Info); +#if 0 Uint Binary_Relocate(void *Base); -Uint Binary_GetSymbolEx(char *Name, Uint *Value); -Uint Binary_FindSymbol(void *Base, char *Name, Uint *Val); +#endif +Uint Binary_GetSymbolEx(const char *Name, Uint *Value); +#if 0 +Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val); +#endif // === 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; @@ -66,11 +68,12 @@ int Binary_RegisterType(tBinaryType *Type) } /** - * \fn int Proc_Spawn(char *Path) + * \fn int Proc_Spawn(const char *Path) */ -int Proc_Spawn(char *Path) +int Proc_Spawn(const char *Path) { char stackPath[strlen(Path)+1]; + ENTER("sPath", Path); strcpy(stackPath, Path); @@ -79,11 +82,12 @@ int Proc_Spawn(char *Path) if(Proc_Clone(NULL, CLONE_VM) == 0) { // CHILD - char *args[2] = {stackPath, NULL}; + const char *args[2] = {stackPath, NULL}; LOG("stackPath = '%s'\n", stackPath); Proc_Execve(stackPath, args, &args[1]); for(;;); } + LEAVE('i', 0); return 0; } @@ -95,11 +99,11 @@ int Proc_Spawn(char *Path) * \param EnvP User's environment * \note Called Proc_ for historical reasons */ -int Proc_Execve(char *File, char **ArgV, char **EnvP) +int Proc_Execve(const char *File, const char **ArgV, const char **EnvP) { int argc, envc, i; int argenvBytes; - char *argenvBuf, *strBuf; + char **argenvBuf, *strBuf; char **argvSaved, **envpSaved; char *savedFile; Uint entry; @@ -121,13 +125,14 @@ 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("Binary", "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*); + strBuf = (char*)argenvBuf + (argc+1)*sizeof(void*) + (envc+1)*sizeof(void*); // Populate - argvSaved = (char **) argenvBuf; + argvSaved = argenvBuf; for( i = 0; i < argc; i++ ) { argvSaved[i] = strBuf; @@ -158,8 +163,9 @@ 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)); - Threads_Exit(0, 0); + Log_Warning("Binary", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1)); + LEAVE('-'); + Threads_Exit(0, -10); for(;;); } @@ -172,14 +178,17 @@ 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) +Uint Binary_Load(const char *file, Uint *entryPoint) { char *sTruePath; tBinary *pBinary; Uint base = -1; - ENTER("sfile", file); + ENTER("sfile pentryPoint", file, entryPoint); // Sanity Check Argument if(file == NULL) { @@ -189,14 +198,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("Binary", "%p '%s' does not exist.", file, 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)) ) @@ -249,7 +261,7 @@ Uint Binary_Load(char *file, Uint *entryPoint) * \brief Finds a matching binary entry * \param TruePath File Identifier (True path name) */ -tBinary *Binary_GetInfo(char *TruePath) +tBinary *Binary_GetInfo(const char *TruePath) { tBinary *pBinary; pBinary = glLoadedBinaries; @@ -315,7 +327,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; } @@ -342,7 +354,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); @@ -382,7 +394,7 @@ Uint Binary_IsMapped(tBinary *binary) * \brief Loads a binary file into memory * \param truePath Absolute filename of binary */ -tBinary *Binary_DoLoad(char *truePath) +tBinary *Binary_DoLoad(const char *truePath) { tBinary *pBinary; int fp, i; @@ -411,7 +423,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; @@ -425,8 +437,7 @@ tBinary *Binary_DoLoad(char *truePath) // Initialise Structure pBinary->ReferenceCount = 0; - pBinary->TruePath = malloc( strlen(truePath) + 1 ); - strcpy(pBinary->TruePath, truePath); + pBinary->TruePath = strdup(truePath); // Debug Information LOG("Interpreter: '%s'", pBinary->Interpreter); @@ -434,13 +445,13 @@ tBinary *Binary_DoLoad(char *truePath) LOG("NumPages: %i", pBinary->NumPages); // Read Data - for(i=0;iNumPages;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 ); } @@ -461,12 +472,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 ); } @@ -480,10 +513,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); @@ -505,7 +538,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; } @@ -586,12 +619,12 @@ char *Binary_RegInterp(char *Path) // Kernel Binary Handling // ============ /** - * \fn void *Binary_LoadKernel(char *File) + * \fn void *Binary_LoadKernel(const char *File) * \brief Load a binary into kernel space * \note This function shares much with #Binary_Load, but does it's own mapping * \param File File to load into the kernel */ -void *Binary_LoadKernel(char *File) +void *Binary_LoadKernel(const char *File) { char *sTruePath; tBinary *pBinary; @@ -600,7 +633,7 @@ void *Binary_LoadKernel(char *File) Uint addr; int i; - ENTER("sfile", File); + ENTER("sFile", File); // Sanity Check Argument if(File == NULL) { @@ -687,7 +720,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; @@ -713,7 +746,7 @@ void *Binary_LoadKernel(char *File) // Relocate Library if( !Binary_Relocate( (void*)base ) ) { - Warning("[BIN ] Relocation of '%s' failed, unloading", sTruePath); + Log_Warning("BIN", "Relocation of '%s' failed, unloading", sTruePath); Binary_Unload( (void*)base ); Binary_Dereference( pBinary ); LEAVE('n'); @@ -724,10 +757,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; @@ -750,7 +783,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; } @@ -763,7 +796,7 @@ Uint Binary_Relocate(void *Base) * Gets the value of a symbol from either the currently loaded * libraries or the kernel's exports. */ -int Binary_GetSymbol(char *Name, Uint *Val) +int Binary_GetSymbol(const char *Name, Uint *Val) { if( Binary_GetSymbolEx(Name, Val) ) return 1; return 0; @@ -776,7 +809,7 @@ int Binary_GetSymbol(char *Name, Uint *Val) * Gets the value of a symbol from either the currently loaded * libraries or the kernel's exports. */ -Uint Binary_GetSymbolEx(char *Name, Uint *Value) +Uint Binary_GetSymbolEx(const char *Name, Uint *Value) { int i; tKernelBin *pKBin; @@ -801,7 +834,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; } @@ -812,7 +845,7 @@ Uint Binary_GetSymbolEx(char *Name, Uint *Value) * \param Name Name of symbol to find * \param Val Pointer to place final value */ -Uint Binary_FindSymbol(void *Base, char *Name, Uint *Val) +Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val) { Uint32 ident = *(Uint32*) Base; tBinaryType *bt = gRegBinTypes; @@ -823,7 +856,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; }