X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fbinary.c;h=20da5c4eb70e81259d084452ddc8b91f1429d842;hb=c8a4887d3ccd366dc84bfcb31ffff843e4b2c59f;hp=f00e8518e1966d9c395ce7befddf828d7d52f265;hpb=6adbfe017566048fc15e152aa842bbe1cd6f430c;p=tpg%2Facess2.git diff --git a/Kernel/binary.c b/Kernel/binary.c index f00e8518..20da5c4e 100644 --- a/Kernel/binary.c +++ b/Kernel/binary.c @@ -2,7 +2,7 @@ * Acess2 * Common Binary Loader */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include @@ -76,13 +76,13 @@ int Proc_Spawn(const char *Path) strcpy(stackPath, Path); - LOG("stackPath = '%s'\n", stackPath); + LOG("stackPath = '%s'", stackPath); if(Proc_Clone(CLONE_VM) == 0) { // CHILD const char *args[2] = {stackPath, NULL}; - LOG("stackPath = '%s'\n", stackPath); + LOG("stackPath = '%s'", stackPath); Proc_Execve(stackPath, args, &args[1]); for(;;); } @@ -91,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 @@ -106,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); @@ -118,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*); @@ -136,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; @@ -143,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; } @@ -158,28 +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); + 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) { @@ -214,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? @@ -257,30 +264,36 @@ 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; int i, fd; + + ENTER("pBinary sPath pLoadMin pLoadMax", Binary, Path, LoadMin, LoadMax); + // Reference Executable (Makes sure that it isn't unloaded) Binary->ReferenceCount ++; @@ -290,7 +303,8 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo // Check if base is free if(base != 0) { - for(i=0;iNumSections;i++) + LOG("Checking base %p", base); + for( i = 0; i < Binary->NumSections; i ++ ) { if( Binary_int_CheckMemFree( Binary->LoadSections[i].Virtual, Binary->LoadSections[i].MemSize ) ) { @@ -319,11 +333,13 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo // Else decrement pointer and try again base -= BIN_GRANUALITY; } + LOG("Allocated base %p", base); } // Error Check if(base < LoadMin) { Log_Warning("Binary", "Executable '%s' cannot be loaded, no space", Path); + LEAVE('i', 0); return 0; } @@ -334,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 - 0x%x to 0x%x", i, addr, sect->Offset); + 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 ); } @@ -348,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( @@ -358,10 +377,10 @@ 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); + Log_Debug("Binary", "PID %i - Mapped '%s' to %p", Threads_GetPID(), Path, base); + VFS_Close(fd); + LEAVE('p', base); return base; } @@ -402,10 +421,10 @@ 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", Path); + ENTER("iMountID XInode sPath", MountID, Inode, Path); // Open File fp = VFS_OpenInode(MountID, Inode, VFS_OPENFLAG_READ); @@ -414,20 +433,25 @@ 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; } - + // Close File VFS_Close(fp); @@ -439,6 +463,8 @@ tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path) return NULL; } + LOG("pBinary = %p", pBinary); + // Error Check if(pBinary == NULL) { LEAVE('n'); @@ -756,6 +782,7 @@ Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val) int Binary_int_CheckMemFree( tVAddr _start, size_t _len ) { _len += _start & (PAGE_SIZE-1); + _len = (_len + PAGE_SIZE - 1) & ~(PAGE_SIZE-1); _start &= ~(PAGE_SIZE-1); for( ; _len > PAGE_SIZE; _len -= PAGE_SIZE, _start += PAGE_SIZE ) { if( MM_GetPhysAddr(_start) != 0 )