+++ /dev/null
-/*
- * Acess2
- * Common Binary Loader
- */
-#define DEBUG 0
-#include <acess.h>
-#include <binary.h>
-#include <mm_virt.h>
-#include <hal_proc.h>
-#include <vfs_threads.h>
-
-// === CONSTANTS ===
-#define BIN_LOWEST MM_USER_MIN // 1MiB
-#define BIN_GRANUALITY 0x10000 // 64KiB
-#define BIN_HIGHEST (USER_LIB_MAX-BIN_GRANUALITY) // Just below the kernel
-#define KLIB_LOWEST MM_MODULE_MIN
-#define KLIB_GRANUALITY 0x10000 // 32KiB
-#define KLIB_HIGHEST (MM_MODULE_MAX-KLIB_GRANUALITY)
-
-// === TYPES ===
-typedef struct sKernelBin {
- struct sKernelBin *Next;
- void *Base;
- tBinary *Info;
-} tKernelBin;
-
-// === IMPORTS ===
-extern char *Threads_GetName(int ID);
-extern tKernelSymbol gKernelSymbols[];
-extern tKernelSymbol gKernelSymbolsEnd[];
-extern tBinaryType gELF_Info;
-
-// === PROTOTYPES ===
- int Binary_int_CacheArgs(const char **Path, const char ***ArgV, const char ***EnvP, void *DestBuffer);
-tVAddr Binary_Load(const char *Path, tVAddr *EntryPoint);
-tBinary *Binary_GetInfo(tMount MountID, tInode InodeID);
-tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr LoadMax);
-tVAddr Binary_IsMapped(tBinary *Binary);
-tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path);
-void Binary_Dereference(tBinary *Info);
-#if 0
-Uint Binary_Relocate(void *Base);
-#endif
-Uint Binary_GetSymbolEx(const char *Name, Uint *Value);
-#if 0
-Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val);
-#endif
- int Binary_int_CheckMemFree( tVAddr _start, size_t _len );
-
-// === GLOBALS ===
-tShortSpinlock glBinListLock;
-tBinary *glLoadedBinaries = NULL;
-char **gsaRegInterps = NULL;
- int giRegInterps = 0;
-tShortSpinlock glKBinListLock;
-tKernelBin *glLoadedKernelLibs;
-tBinaryType *gRegBinTypes = &gELF_Info;
-
-// === FUNCTIONS ===
-/**
- * \brief Registers a binary type
- */
-int Binary_RegisterType(tBinaryType *Type)
-{
- Type->Next = gRegBinTypes;
- gRegBinTypes = Type;
- return 1;
-}
-
-/**
- * \fn int Proc_Spawn(const char *Path)
- */
-int Proc_Spawn(const char *Path)
-{
- char stackPath[strlen(Path)+1];
- ENTER("sPath", Path);
-
- strcpy(stackPath, Path);
-
- LOG("stackPath = '%s'", stackPath);
-
- if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0)
- {
- // CHILD
- const char *args[2] = {stackPath, NULL};
- LOG("stackPath = '%s'", stackPath);
- Proc_Execve(stackPath, args, &args[1], 0);
- for(;;);
- }
- LEAVE('i', 0);
- return 0;
-}
-
-/**
- * \todo Document
- */
-int Binary_int_CacheArgs(const char **Path, const char ***ArgV, const char ***EnvP, void *DestBuffer)
-{
- int size, argc=0, envc=0;
- int i;
- char *strbuf;
- const char **arrays;
-
- // Calculate size
- size = 0;
- if( ArgV && *ArgV )
- {
- const char **argv = *ArgV;
- for( argc = 0; argv[argc]; argc ++ )
- size += strlen( argv[argc] ) + 1;
- }
- if( EnvP && *EnvP )
- {
- const char **envp = *EnvP;
- for( envc = 0; envp[envc]; envc ++ )
- size += strlen( envp[envc] ) + 1;
- }
- size = (size + sizeof(void*)-1) & ~(sizeof(void*)-1); // Word align
- size += (argc+1+envc+1)*sizeof(void*); // Arrays
- if( Path )
- {
- size += strlen( *Path ) + 1;
- }
-
- if( DestBuffer )
- {
- arrays = DestBuffer;
- strbuf = (void*)&arrays[argc+1+envc+1];
-
- // Fill ArgV
- if( ArgV && *ArgV )
- {
- const char **argv = *ArgV;
- for( i = 0; argv[i]; i ++ )
- {
- arrays[i] = strbuf;
- strcpy(strbuf, argv[i]);
- strbuf += strlen( argv[i] ) + 1;
- }
- *ArgV = arrays;
- arrays += i;
- }
- *arrays++ = NULL;
- // Fill EnvP
- if( EnvP && *EnvP )
- {
- const char **envp = *EnvP;
- for( i = 0; envp[i]; i ++ )
- {
- arrays[i] = strbuf;
- strcpy(strbuf, envp[i]);
- strbuf += strlen( envp[i] ) + 1;
- }
- *EnvP = arrays;
- arrays += i;
- }
- *arrays++ = NULL;
- // Fill path
- if( Path )
- {
- strcpy(strbuf, *Path);
- *Path = strbuf;
- }
- }
-
- return size;
-}
-
-/**
- * \brief Create a new process with the specified set of file descriptors
- */
-int Proc_SysSpawn(const char *Binary, const char **ArgV, const char **EnvP, int nFD, int *FDs)
-{
- void *handles;
- void *cachebuf;
- int size;
- tPID ret;
-
- // --- Save File, ArgV and EnvP
- size = Binary_int_CacheArgs( &Binary, &ArgV, &EnvP, NULL );
- cachebuf = alloca( size );
- Binary_int_CacheArgs( &Binary, &ArgV, &EnvP, cachebuf );
-
- // Cache the VFS handles
- handles = VFS_SaveHandles(nFD, FDs);
-
- // Create new process
- ret = Proc_Clone(CLONE_VM|CLONE_NOUSER);
- if( ret == 0 )
- {
- VFS_RestoreHandles(nFD, handles);
- VFS_FreeSavedHandles(nFD, handles);
- Proc_Execve(Binary, ArgV, EnvP, size);
- for(;;);
- }
- if( ret < 0 )
- {
- VFS_FreeSavedHandles(nFD, handles);
- }
-
- return ret;
-}
-
-/**
- * \brief Replace the current user image with another
- * \param File File to load as the next image
- * \param ArgV Arguments to pass to user
- * \param EnvP User's environment
- * \note Called Proc_ for historical reasons
- */
-int Proc_Execve(const char *File, const char **ArgV, const char **EnvP, int DataSize)
-{
- void *cachebuf;
- tVAddr entry;
- Uint base; // Uint because Proc_StartUser wants it
- int argc;
-
- ENTER("sFile pArgV pEnvP", File, ArgV, EnvP);
-
- // --- Save File, ArgV and EnvP
- if( DataSize == 0 )
- {
- DataSize = Binary_int_CacheArgs( &File, &ArgV, &EnvP, NULL );
- cachebuf = malloc( DataSize );
- Binary_int_CacheArgs( &File, &ArgV, &EnvP, cachebuf );
- }
-
- // --- Get argc
- for( argc = 0; ArgV && ArgV[argc]; argc ++ );
-
- // --- Set Process Name
- Threads_SetName(File);
-
- // --- Clear User Address space
- MM_ClearUser();
-
- // --- Load new binary
- base = Binary_Load(File, &entry);
- if(base == 0)
- {
- Log_Warning("Binary", "Proc_Execve - Unable to load '%s'", File);
- LEAVE('-');
- Threads_Exit(0, -10);
- for(;;);
- }
-
- LOG("entry = 0x%x, base = 0x%x", entry, base);
- LEAVE('-');
- // --- And... Jump to it
- Proc_StartUser(entry, base, argc, ArgV, DataSize);
- for(;;); // Tell GCC that we never return
-}
-
-/**
- * \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)
-{
- tMount mount_id;
- tInode inode;
- tBinary *pBinary;
- tVAddr base = -1;
-
- ENTER("sPath pEntryPoint", Path, EntryPoint);
-
- // Sanity Check Argument
- if(Path == NULL) {
- LEAVE('x', 0);
- return 0;
- }
-
- // Check if this path has been loaded before.
- #if 0
- // TODO: Implement a list of string/tBinary pairs for loaded bins
- #endif
-
- // Get Inode
- {
- int fd;
- tFInfo info;
- fd = VFS_Open(Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_EXEC);
- if( fd == -1 ) {
- LOG("%s does not exist", Path);
- LEAVE_RET('x', 0);
- }
- VFS_FInfo(fd, &info, 0);
- VFS_Close(fd);
- mount_id = info.mount;
- inode = info.inode;
- LOG("mount_id = %i, inode = %i", mount_id, inode);
- }
-
- // TODO: Also get modifcation time?
-
- // Check if the binary has already been loaded
- if( !(pBinary = Binary_GetInfo(mount_id, inode)) )
- pBinary = Binary_DoLoad(mount_id, inode, Path); // Else load it
-
- // Error Check
- if(pBinary == NULL) {
- LEAVE('x', 0);
- return 0;
- }
-
- // Map into process space
- base = Binary_MapIn(pBinary, Path, BIN_LOWEST, BIN_HIGHEST);
-
- // Check for errors
- if(base == 0) {
- LEAVE('x', 0);
- return 0;
- }
-
- // Interpret
- if(pBinary->Interpreter) {
- tVAddr start;
- if( Binary_Load(pBinary->Interpreter, &start) == 0 ) {
- LEAVE('x', 0);
- return 0;
- }
- *EntryPoint = start;
- }
- else
- *EntryPoint = pBinary->Entry - pBinary->Base + base;
-
- // Return
- LOG("*EntryPoint = 0x%x", *EntryPoint);
- LEAVE('x', base);
- return base; // Pass the base as an argument to the user if there is an interpreter
-}
-
-/**
- * \brief Finds a matching binary entry
- * \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;
- for(pBinary = glLoadedBinaries; pBinary; pBinary = pBinary->Next)
- {
- if(pBinary->MountID == MountID && pBinary->Inode == InodeID)
- return pBinary;
- }
- return NULL;
-}
-
-/**
- * \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 ++;
-
- // Get Binary Base
- base = Binary->Base;
-
- // Check if base is free
- if(base != 0)
- {
- LOG("Checking base %p", base);
- for( i = 0; i < Binary->NumSections; i ++ )
- {
- if( Binary_int_CheckMemFree( Binary->LoadSections[i].Virtual, Binary->LoadSections[i].MemSize ) )
- {
- base = 0;
- LOG("Address 0x%x is taken\n", Binary->LoadSections[i].Virtual);
- break;
- }
- }
- }
-
- // Check if the executable has no base or it is not free
- if(base == 0)
- {
- // If so, give it a base
- base = LoadMax;
- while(base >= LoadMin)
- {
- for( i = 0; i < Binary->NumSections; i ++ )
- {
- tVAddr addr = Binary->LoadSections[i].Virtual - Binary->Base + base;
- if( Binary_int_CheckMemFree( addr, Binary->LoadSections[i].MemSize ) )
- break;
- }
- // If space was found, break
- if(i == Binary->NumSections) break;
- // 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;
- }
-
- // Map Executable In
- fd = VFS_OpenInode(Binary->MountID, Binary->Inode, VFS_OPENFLAG_READ);
- for( i = 0; i < Binary->NumSections; i ++ )
- {
- tBinarySection *sect = &Binary->LoadSections[i];
- Uint protflags, mapflags;
- tVAddr addr = sect->Virtual - Binary->Base + base;
- 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 );
- }
- else {
- 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(
- (void*)(addr + sect->FileSize), sect->MemSize - sect->FileSize,
- protflags, MMAP_MAP_PRIVATE|mapflags,
- 0, 0
- );
- }
- }
-
- Log_Debug("Binary", "PID %i - Mapped '%s' to %p", Threads_GetPID(), Path, base);
- VFS_Close(fd);
-
- LEAVE('p', base);
- return base;
-}
-
-#if 0
-/**
- * \fn Uint Binary_IsMapped(tBinary *binary)
- * \brief Check if a binary is already mapped into the address space
- * \param binary Binary information to check
- * \return Current Base or 0
- */
-Uint Binary_IsMapped(tBinary *binary)
-{
- Uint iBase;
-
- // Check prefered base
- iBase = binary->Base;
- if(MM_GetPage( iBase ) == (binary->Pages[0].Physical & ~0xFFF))
- return iBase;
-
- for(iBase = BIN_HIGHEST;
- iBase >= BIN_LOWEST;
- iBase -= BIN_GRANUALITY)
- {
- if(MM_GetPage( iBase ) == (binary->Pages[0].Physical & ~0xFFF))
- return iBase;
- }
-
- return 0;
-}
-#endif
-
-/**
- * \fn tBinary *Binary_DoLoad(char *truePath)
- * \brief Loads a binary file into memory
- * \param truePath Absolute filename of binary
- */
-tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path)
-{
- tBinary *pBinary;
- int fp;
- Uint32 ident;
- tBinaryType *bt = gRegBinTypes;
-
- ENTER("iMountID XInode sPath", MountID, Inode, Path);
-
- // Open File
- fp = VFS_OpenInode(MountID, Inode, VFS_OPENFLAG_READ);
- if(fp == -1) {
- LOG("Unable to load file, access denied");
- 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) != (Uint32)bt->Ident )
- continue;
- LOG("bt = %p (%s)", bt, bt->Name);
- pBinary = bt->Load(fp);
- break;
- }
-
- // Close File
- VFS_Close(fp);
-
- // Catch errors
- if(!bt) {
- Log_Warning("Binary", "'%s' is an unknown file type. (%02x %02x %02x %02x)",
- Path, ident&0xFF, (ident>>8)&0xFF, (ident>>16)&0xFF, (ident>>24)&0xFF);
- LEAVE('n');
- return NULL;
- }
-
- LOG("pBinary = %p", pBinary);
-
- // Error Check
- if(pBinary == NULL) {
- LEAVE('n');
- return NULL;
- }
-
- // Initialise Structure
- pBinary->ReferenceCount = 0;
- pBinary->MountID = MountID;
- pBinary->Inode = Inode;
-
- // Debug Information
- LOG("Interpreter: '%s'", pBinary->Interpreter);
- LOG("Base: 0x%x, Entry: 0x%x", pBinary->Base, pBinary->Entry);
- LOG("NumSections: %i", pBinary->NumSections);
-
- // Add to the list
- SHORTLOCK(&glBinListLock);
- pBinary->Next = glLoadedBinaries;
- glLoadedBinaries = pBinary;
- SHORTREL(&glBinListLock);
-
- // TODO: Register the path with the binary
-
- // Return
- LEAVE('p', pBinary);
- return pBinary;
-}
-
-/**
- * \fn void Binary_Unload(void *Base)
- * \brief Unload / Unmap a binary
- * \param Base Loaded Base
- * \note Currently used only for kernel libaries
- */
-void Binary_Unload(void *Base)
-{
- tKernelBin *pKBin;
- tKernelBin *prev = NULL;
- int i;
-
- if((Uint)Base < 0xC0000000)
- {
- // TODO: User Binaries
- Log_Warning("BIN", "Unloading user binaries is currently unimplemented");
- return;
- }
-
- // Kernel Libraries
- for(pKBin = glLoadedKernelLibs;
- pKBin;
- prev = pKBin, pKBin = pKBin->Next)
- {
- // Check the base
- if(pKBin->Base != Base) continue;
- // Deallocate Memory
- for(i = 0; i < pKBin->Info->NumSections; i++)
- {
- // TODO: VFS_MUnmap();
- }
- // Dereference Binary
- Binary_Dereference( pKBin->Info );
- // Remove from list
- if(prev) prev->Next = pKBin->Next;
- else glLoadedKernelLibs = pKBin->Next;
- // Free Kernel Lib
- free(pKBin);
- return;
- }
-}
-
-/**
- * \fn void Binary_Dereference(tBinary *Info)
- * \brief Dereferences and if nessasary, deletes a binary
- * \param Info Binary information structure
- */
-void Binary_Dereference(tBinary *Info)
-{
- // Decrement reference count
- Info->ReferenceCount --;
-
- // Check if it is still in use
- if(Info->ReferenceCount) return;
-
- /// \todo Implement binary freeing
-}
-
-/**
- * \fn char *Binary_RegInterp(char *Path)
- * \brief Registers an Interpreter
- * \param Path Path to interpreter provided by executable
- */
-char *Binary_RegInterp(char *Path)
-{
- int i;
- // NULL Check Argument
- if(Path == NULL) return NULL;
- // NULL Check the array
- if(gsaRegInterps == NULL)
- {
- giRegInterps = 1;
- gsaRegInterps = malloc( sizeof(char*) );
- gsaRegInterps[0] = malloc( strlen(Path) );
- strcpy(gsaRegInterps[0], Path);
- return gsaRegInterps[0];
- }
-
- // Scan Array
- for( i = 0; i < giRegInterps; i++ )
- {
- if(strcmp(gsaRegInterps[i], Path) == 0)
- return gsaRegInterps[i];
- }
-
- // Interpreter is not in list
- giRegInterps ++;
- gsaRegInterps = malloc( sizeof(char*)*giRegInterps );
- gsaRegInterps[i] = malloc( strlen(Path) );
- strcpy(gsaRegInterps[i], Path);
- return gsaRegInterps[i];
-}
-
-// ============
-// Kernel Binary Handling
-// ============
-/**
- * \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(const char *File)
-{
- tBinary *pBinary;
- tKernelBin *pKBinary;
- tVAddr base = -1;
- tMount mount_id;
- tInode inode;
-
- ENTER("sFile", File);
-
- // Sanity Check Argument
- if(File == NULL) {
- LEAVE('n');
- return 0;
- }
-
- {
- int fd = VFS_Open(File, VFS_OPENFLAG_READ);
- tFInfo info;
- if(fd == -1) {
- LEAVE('n');
- return NULL;
- }
- VFS_FInfo(fd, &info, 0);
- mount_id = info.mount;
- inode = info.inode;
- VFS_Close(fd);
- }
-
- // Check if the binary has already been loaded
- if( (pBinary = Binary_GetInfo(mount_id, inode)) )
- {
- for(pKBinary = glLoadedKernelLibs;
- pKBinary;
- pKBinary = pKBinary->Next )
- {
- if(pKBinary->Info == pBinary) {
- LEAVE('p', pKBinary->Base);
- return pKBinary->Base;
- }
- }
- }
- else
- pBinary = Binary_DoLoad(mount_id, inode, File); // Else load it
-
- // Error Check
- if(pBinary == NULL) {
- LEAVE('n');
- return NULL;
- }
-
- // --------------
- // Now pBinary is valid (either freshly loaded or only user mapped)
- // So, map it into kernel space
- // --------------
-
- // Reference Executable (Makes sure that it isn't unloaded)
- pBinary->ReferenceCount ++;
-
- Binary_MapIn(pBinary, File, KLIB_LOWEST, KLIB_HIGHEST);
-
- // Relocate Library
- if( !Binary_Relocate( (void*)base ) )
- {
- Log_Warning("Binary", "Relocation of '%s' failed, unloading", File);
- Binary_Unload( (void*)base );
- Binary_Dereference( pBinary );
- LEAVE('n');
- return 0;
- }
-
- // Add to list (relocator must look at itself manually, not via Binary_GetSymbol)
- pKBinary = malloc(sizeof(*pKBinary));
- pKBinary->Base = (void*)base;
- pKBinary->Info = pBinary;
- SHORTLOCK( &glKBinListLock );
- pKBinary->Next = glLoadedKernelLibs;
- glLoadedKernelLibs = pKBinary;
- SHORTREL( &glKBinListLock );
-
- LEAVE('p', base);
- return (void*)base;
-}
-
-/**
- * \fn Uint Binary_Relocate(void *Base)
- * \brief Relocates a loaded binary (used by kernel libraries)
- * \param Base Loaded base address of binary
- * \return Boolean Success
- */
-Uint Binary_Relocate(void *Base)
-{
- Uint32 ident = *(Uint32*) Base;
- tBinaryType *bt = gRegBinTypes;
-
- for(; bt; bt = bt->Next)
- {
- if( (ident & bt->Mask) == (Uint)bt->Ident )
- return bt->Relocate( (void*)Base);
- }
-
- 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;
-}
-
-/**
- * \fn int Binary_GetSymbol(char *Name, Uint *Val)
- * \brief Get a symbol value
- * \return Value of symbol or -1 on error
- *
- * Gets the value of a symbol from either the currently loaded
- * libraries or the kernel's exports.
- */
-int Binary_GetSymbol(const char *Name, Uint *Val)
-{
- if( Binary_GetSymbolEx(Name, Val) ) return 1;
- return 0;
-}
-
-/**
- * \fn Uint Binary_GetSymbolEx(char *Name, Uint *Value)
- * \brief Get a symbol value
- *
- * Gets the value of a symbol from either the currently loaded
- * libraries or the kernel's exports.
- */
-Uint Binary_GetSymbolEx(const char *Name, Uint *Value)
-{
- int i;
- tKernelBin *pKBin;
- int numKSyms = ((Uint)&gKernelSymbolsEnd-(Uint)&gKernelSymbols)/sizeof(tKernelSymbol);
-
- // Scan Kernel
- for( i = 0; i < numKSyms; i++ )
- {
- if(strcmp(Name, gKernelSymbols[i].Name) == 0) {
- *Value = gKernelSymbols[i].Value;
- return 1;
- }
- }
-
- // Scan Loaded Libraries
- for(pKBin = glLoadedKernelLibs;
- pKBin;
- pKBin = pKBin->Next )
- {
- if( Binary_FindSymbol(pKBin->Base, Name, Value) ) {
- return 1;
- }
- }
-
- Log_Warning("BIN", "Unable to find symbol '%s'", Name);
- return 0;
-}
-
-/**
- * \fn Uint Binary_FindSymbol(void *Base, char *Name, Uint *Val)
- * \brief Get a symbol from the specified library
- * \param Base Base address
- * \param Name Name of symbol to find
- * \param Val Pointer to place final value
- */
-Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val)
-{
- Uint32 ident = *(Uint32*) Base;
- tBinaryType *bt = gRegBinTypes;
-
- for(; bt; bt = bt->Next)
- {
- if( (ident & bt->Mask) == (Uint)bt->Ident )
- return bt->GetSymbol(Base, Name, Val);
- }
-
- 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;
-}
-
-/**
- * \brief Check if a range of memory is fully free
- * \return Inverse boolean free (0 if all pages are unmapped)
- */
-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 )
- return 1;
- }
- if( _len == PAGE_SIZE && MM_GetPhysAddr(_start) != 0 )
- return 1;
- return 0;
-}
-
-
-// === EXPORTS ===
-EXPORT(Binary_FindSymbol);
-EXPORT(Binary_Unload);