// === 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
// === 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;
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(;;);
* \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;
// 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*);
+ 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;
strcpy(envpSaved[i], EnvP[i]);
strBuf += strlen(EnvP[i])+1;
}
+ envpSaved[i] = NULL;
savedFile = malloc(strlen(File)+1);
strcpy(savedFile, File);
free(savedFile);
if(bases[0] == 0)
{
- Warning("Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
- Threads_Exit(0, 0);
+ Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
+ LEAVE('-');
+ Threads_Exit(0, -10);
for(;;);
}
/**
* \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) {
// 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)) )
* \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;
// 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;
}
}
- //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);
* \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;
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;
// 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);
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 );
}
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 );
}
VFS_Close(fp);
// Add to the list
- LOCK(&glBinListLock);
+ SHORTLOCK(&glBinListLock);
pBinary->Next = glLoadedBinaries;
glLoadedBinaries = pBinary;
- RELEASE(&glBinListLock);
+ SHORTREL(&glBinListLock);
// Return
LEAVE('p', pBinary);
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;
}
// 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;
Uint addr;
int i;
- ENTER("sfile", File);
+ ENTER("sFile", File);
// Sanity Check Argument
if(File == NULL) {
// - 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;
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;
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;
}
* 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;
* 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;
}
}
- Warning("[BIN ] Unable to find symbol '%s'", Name);
+ Log_Warning("BIN", "Unable to find symbol '%s'", Name);
return 0;
}
* \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;
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;
}