/* ================= Sys_LoadGameDll Used to load a development dll instead of a virtual machine ================= */ void *Sys_LoadGameDll(const char *name, intptr_t (QDECL **entryPoint)(intptr_t, ...), intptr_t (*systemcalls)(intptr_t, ...)) { void *libHandle; void (*dllEntry)(intptr_t (*syscallptr)(intptr_t, ...)); assert(name); Com_DPrintf( "Loading DLL file: %s\n", name); libHandle = Sys_LoadLibrary(name); if(!libHandle) { Com_Printf("Sys_LoadGameDll(%s) failed:\n\"%s\"\n", name, Sys_LibraryError()); return NULL; } dllEntry = Sys_LoadFunction( libHandle, "dllEntry" ); *entryPoint = Sys_LoadFunction( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { Com_Printf ( "Sys_LoadGameDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError( ) ); Sys_UnloadLibrary(libHandle); return NULL; } Com_DPrintf ( "Sys_LoadGameDll(%s) found vmMain function at %p\n", name, *entryPoint ); dllEntry( systemcalls ); return libHandle; }
/* ===================== idModelExport::LoadMayaDll Checks to see if we can load the Maya export dll ===================== */ void idModelExport::LoadMayaDll( void ) { exporterDLLEntry_t dllEntry; char dllPath[ MAX_OSPATH ]; fileSystem->FindDLL( "MayaImport", dllPath, false ); if( !dllPath[ 0 ] ) { return; } importDLL = sys->DLL_Load( dllPath ); if( !importDLL ) { return; } // look up the dll interface functions dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" ); Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" ); Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" ); if( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) { Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Invalid interface on export DLL." ); return; } // initialize the DLL if( !dllEntry( MD5_VERSION, common, sys ) ) { // init failed Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Export DLL init failed." ); return; } }
qbool VM_LoadNative( vm_t * vm ) { char name[MAX_OSPATH]; char *gpath = NULL; void ( *dllEntry ) ( void * ); while ( ( gpath = FS_NextPath( gpath ) ) ) { snprintf(name, sizeof(name), "%s/%s." DLEXT, gpath, vm->name); vm->hInst = Sys_DLOpen( name ); if ( vm->hInst ) { Con_DPrintf( "LoadLibrary (%s)\n", name ); break; } } if ( !vm->hInst ) return false; dllEntry = (void (EXPORT_FN *)(void *)) Sys_DLProc( (DL_t) vm->hInst, "dllEntry" ); vm->vmMain = (intptr_t (EXPORT_FN *)(int,int,int,int,int,int,int,int,int,int,int,int,int)) Sys_DLProc( (DL_t) vm->hInst, "vmMain" ); if ( !dllEntry || !vm->vmMain ) { VM_Unload( vm ); SV_Error( "VM_LoadNative: couldn't initialize module %s", name ); } dllEntry( (void *) vm->syscall ); Info_SetValueForStarKey( svs.info, "*progs", DLEXT, MAX_SERVERINFO_STRING ); vm->type = VM_NATIVE; return true; }
void *Sys_LoadDll( const char *name, int (**entryPoint)(int, ...), int (*systemCalls)(int, ...) ) { dllEntry( systemCalls ); *entryPoint = vmMain; return (void *)1; }
void * Sys_LoadCgame( intptr_t (**entryPoint)(intptr_t, ...), intptr_t (*systemcalls)(intptr_t, ...) ) { void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) ); dllEntry = ( void (*)( intptr_t (*)( intptr_t, ... ) ) )dlsym( game_library, "dllEntry" ); *entryPoint = (intptr_t (*)(intptr_t,...))dlsym( game_library, "vmMain" ); if ( !*entryPoint || !dllEntry ) { return NULL; } dllEntry( systemcalls ); return game_library; }
/* ================= Sys_LoadDll Used to load a development dll instead of a virtual machine #1 look down current path #2 look in fs_homepath #3 look in fs_basepath ================= */ void *Sys_LoadDll( const char *name, char *fqpath , intptr_t (**entryPoint)(int, ...), intptr_t (*systemcalls)(intptr_t, ...) ) { void *libHandle; void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) ); char fname[MAX_OSPATH]; char *basepath; char *homepath; char *pwdpath; char *gamedir; assert( name ); Q_snprintf (fname, sizeof(fname), "%s" ARCH_STRING DLL_EXT, name); // TODO: use fs_searchpaths from files.c pwdpath = Sys_Cwd(); basepath = Cvar_VariableString( "fs_basepath" ); homepath = Cvar_VariableString( "fs_homepath" ); gamedir = Cvar_VariableString( "fs_game" ); libHandle = Sys_TryLibraryLoad(pwdpath, gamedir, fname, fqpath); if(!libHandle && homepath) libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname, fqpath); if(!libHandle && basepath) libHandle = Sys_TryLibraryLoad(basepath, gamedir, fname, fqpath); if(!libHandle) { Com_Printf ( "Sys_LoadDll(%s) failed to load library\n", name ); return NULL; } dllEntry = Sys_LoadFunction( libHandle, "dllEntry" ); *entryPoint = Sys_LoadFunction( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { Com_Printf ( "Sys_LoadDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError( ) ); Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf ( "Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint ); dllEntry( systemcalls ); return libHandle; }
/* ================= Sys_LoadCgame Used to hook up a development dll ================= */ void * Sys_LoadCgame( int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) ) { void (*dllEntry)( int (*syscallptr)(int, ...) ); dllEntry = ( void (*)( int (*)( int, ... ) ) )Sys_LoadFunction( game_library, "dllEntry" ); *entryPoint = (int (*)(int,...))Sys_LoadFunction( game_library, "vmMain" ); if ( !*entryPoint || !dllEntry ) { Sys_UnloadLibrary( game_library ); return NULL; } dllEntry( systemcalls ); return game_library; }
/* ================= Sys_LoadCgame Used to hook up a development dll ================= */ void * Sys_LoadCgame( int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) ) { void (*dllEntry)( int (*syscallptr)(int, ...) ); dllEntry = ( void (*)( int (*)( int, ... ) ) )GetProcAddress( game_library, "dllEntry" ); *entryPoint = (int (*)(int,...))GetProcAddress( game_library, "vmMain" ); if ( !*entryPoint || !dllEntry ) { FreeLibrary( game_library ); return NULL; } dllEntry( systemcalls ); return game_library; }
/* ================= Sys_LoadDll Used to load a development dll instead of a virtual machine #1 look in fs_homepath #2 look in fs_basepath ================= */ void *Sys_LoadDll( const char *name, intptr_t (**entryPoint)(int, ...), intptr_t (*systemcalls)(intptr_t, ...) ) { void *libHandle; void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) ); char fname[MAX_OSPATH]; char *netpath; assert( name ); Com_sprintf(fname, sizeof(fname), "%s" ARCH_STRING DLL_EXT, name); netpath = FS_FindDll(fname); if(!netpath) { Com_Printf( "Sys_LoadDll(%s) could not find it\n", fname ); return NULL; } Com_Printf( "Loading DLL file: %s\n", netpath); libHandle = Sys_LoadLibrary(netpath); if(!libHandle) { Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", netpath, Sys_LibraryError() ); return NULL; } dllEntry = Sys_LoadFunction( libHandle, "dllEntry" ); *entryPoint = Sys_LoadFunction( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { Com_Printf ( "Sys_LoadDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError( ) ); Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf ( "Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint ); dllEntry( systemcalls ); return libHandle; }
/* ================= Sys_LoadCgame Used to hook up a development dll ================= */ void * Sys_LoadCgame( intptr_t (**entryPoint)(int, ...), intptr_t (*systemcalls)(intptr_t, ...) ) { void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) ); dllEntry = ( void (*)( intptr_t (*)( intptr_t, ... ) ) )GetProcAddress( game_library, "dllEntry" ); *entryPoint = (intptr_t (*)(int,...))GetProcAddress( game_library, "vmMain" ); if ( !*entryPoint || !dllEntry ) { #ifdef JK2_MODE Com_Printf( "Sys_LoadCgame: CGame Entry point not found in jk2game" ARCH_STRING DLL_EXT ". Failed with system error code 0x%X.\n", GetLastError() ); #else Com_Printf( "Sys_LoadCgame: CGame Entry point not found in jagame" ARCH_STRING DLL_EXT ". Failed with system error code 0x%X.\n", GetLastError() ); #endif FreeLibrary( game_library ); return NULL; } dllEntry( systemcalls ); return game_library; }
/* ===================== idModelExport::LoadMayaDll Checks to see if we can load the Maya export dll ===================== */ void idModelExport::LoadMayaDll( void ) { exporterDLLEntry_t dllEntry; char dllPath[ MAX_OSPATH ]; fileSystem->FindDLL( "MayaImport", dllPath, false ); if( !dllPath[ 0 ] ) { return; } importDLL = sys->DLL_Load( dllPath ); if( !importDLL ) { #ifdef WIN32 // greebo: Do another attempt in Win32 to get a better error message idStr win32DllPath( dllPath ); win32DllPath.Replace( "/", "\\" ); HMODULE dll = LoadLibrary( win32DllPath ); if( dll == 0 ) { gameLocal.Warning( "Could not load MayaImport DLL: %s ", FormatGetLastError() ); } #endif return; } // look up the dll interface functions dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" ); Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" ); Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" ); if( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) { Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Invalid interface on export DLL." ); return; } // initialize the DLL if( !dllEntry( MD5_VERSION, common, sys ) ) { // init failed Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Export DLL init failed." ); return; } }
//----------------------------------------------------------------------------- //Function Name : void* __dlopen_r(const char* filename, int flag) //Description : To open the given dll filename. //Return Value : Valid handle value if no error, Null if dll couldn't be loaded //----------------------------------------------------------------------------- void* __dlopen_r(const char* filename,const int flag) { //convert filename to TFileName TPtrC8 ptr8( (unsigned char*)filename); TFileName fileNameBuf; CnvUtfConverter::ConvertToUnicodeFromUtf8(fileNameBuf, ptr8); TParsePtr filePathName(fileNameBuf); //if file name contains wild character if ( filePathName.IsWild() ) { SetError(KDlOpenErrNoSupport); return NULL; } //to load dll RLibrary library; TInt err; TBool isLibraryLoaded = EFalse; RFs fs; err = fs.Connect(); if ( KErrNone == err ) { TUint tempAtt; //if path is there load from this path if ( filePathName.PathPresent() ) { err = fs.Att(filePathName.FullName(), tempAtt); fs.Close(); if ( KErrNotFound != err && KErrPathNotFound != err) { err = library.Load(filePathName.FullName()); if ( KErrNone != err ) { SetError(KDlOpenErrLoading); return NULL; } isLibraryLoaded = ETrue; } } else//if there is no path its only file name { TPtrC fileName(filePathName.NameAndExt()); char* envPathName = getenv("LD_LIBRARY_PATH"); if ( envPathName ) { TPtrC8 tempPtr8((unsigned char*)envPathName); TFileName envPathBuf; CnvUtfConverter::ConvertToUnicodeFromUtf8(envPathBuf, tempPtr8); TPtrC envPath(envPathBuf); TChar delim(';'); TFileName fileToLoad; TInt pos = envPath.Locate(delim); //if delim does not found and still envPath contains value //i.e. this one is last path without delim(';') so take //this also, for this length is checked while ( KErrNotFound != pos || envPath.Length()) { //if there is no delim if (KErrNotFound == pos ) {// so last path without delim pos = envPath.Length(); } TPtrC thisPath(envPath.Left(pos)); fileToLoad = thisPath; fileToLoad.Trim(); //to check ";;" and "; ;" if (fileToLoad.Length()) { //if path does not conatin trailing \ add one if ( L'\\' != fileToLoad[fileToLoad.Length()-1] ) { fileToLoad.Append(TChar(L'\\')); } fileToLoad.Append(fileName); err = fs.Att(fileToLoad, tempAtt); if ( KErrNotFound != err && KErrPathNotFound != err) { //load file from this path err = library.Load(fileToLoad); if ( KErrNone == err ) { // dll loaded successfully from thispath isLibraryLoaded = ETrue; break; } } } if ( pos == envPath.Length()) { break; } else { envPath.Set(envPath.Mid(pos + 1)); } pos = envPath.Locate(delim); } fs.Close(); } else//load dll if only name is there and LD_LIBRARY_PATH path not set { fs.Close(); TInt err = library.Load(filePathName.NameAndExt()); if ( KErrNone != err ) { SetError(KDlOpenErrLoading); return NULL; } isLibraryLoaded = ETrue; } } //if library is loaded if ( isLibraryLoaded ) { //handle value to return void* handle = NULL; //lock list before any operation LoadedDlls()->Lock(); //is this dll already there TInt listIdx = LoadedDlls()->Find(library); //if not already open if ( KErrNotFound == listIdx ) { TDllEntry dllEntry(library, flag); dllEntry.iSymbolHeader = (TE32ExpSymInfoHdr*)library.Lookup(0); err = dllEntry.iLibrary.Duplicate(RThread()); //Close the library irrespective of the result of duplicate library.Close(); if ( KErrNone != err ) { SetError(KDlOpenErrLoading); LoadedDlls()->UnLock(); return NULL; } //add to list err = LoadedDlls()->Add(dllEntry); handle = (void*) dllEntry.iLibrary.Handle(); LoadedDlls()->UnLock(); if ( KErrNone != err ) { SetError(KDlOpenErrNoMemory); dllEntry.iLibrary.Close(); return NULL; } } else//if this dll is already in list. { //close library we already have loaded library.Close(); TDllEntry& dllEntry = LoadedDlls()->At(listIdx); //if flag is RTLD_GLOBAL store it otherwise ignore //as RTLD_LAZY and RTLD_NOW both means RTLD_NOW //so can be ignored. RTLD_LOCAL does not change previous flag if ( flag & RTLD_GLOBAL ) { dllEntry.iFlags |= RTLD_GLOBAL; } dllEntry.iRefCount++; handle = (void*) dllEntry.iLibrary.Handle(); LoadedDlls()->UnLock(); } return handle; } } SetError(KDlOpenErrLoading); return NULL; }
void *Sys_LoadDll( const char *name, int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) ) { void *libHandle; void (*dllEntry)( int (*syscallptr)(int, ...) ); char curpath[MAX_OSPATH]; char fname[MAX_OSPATH]; //char loadname[MAX_OSPATH]; char *basepath; char *cdpath; char *gamedir; char *fn; const char* err = NULL; // bk001206 // rb0101023 - now const // bk001206 - let's have some paranoia assert( name ); getcwd(curpath, sizeof(curpath)); #if defined __i386__ #ifndef NDEBUG snprintf (fname, sizeof(fname), "%sx86-debug.so", name); // bk010205 - different DLL name #else snprintf (fname, sizeof(fname), "%sx86.so", name); #endif #elif defined(__amd64__) || defined(__x86_64__) snprintf (fname, sizeof(fname), "%samd64.so", name); #elif defined __powerpc__ //rcg010207 - PPC support. snprintf (fname, sizeof(fname), "%sppc.so", name); #elif defined __axp__ snprintf (fname, sizeof(fname), "%saxp.so", name); #elif defined __mips__ snprintf (fname, sizeof(fname), "%smips.so", name); #else #error Unknown arch #endif // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW #if 0 // bk010205 - was NDEBUG // bk001129 - FIXME: what is this good for? // bk001206 - do not have different behavior in builds Q_strncpyz(loadname, curpath, sizeof(loadname)); // bk001129 - from cvs1.17 (mkv) Q_strcat(loadname, sizeof(loadname), "/"); Q_strcat(loadname, sizeof(loadname), fname); Com_Printf( "Sys_LoadDll(%s)... \n", loadname ); libHandle = dlopen( loadname, Q_RTLD ); //if ( !libHandle ) { // bk001206 - report any problem //Com_Printf( "Sys_LoadDll(%s) failed: \"%s\"\n", loadname, dlerror() ); #endif // bk010205 - do not load from installdir basepath = Cvar_VariableString( "fs_basepath" ); cdpath = Cvar_VariableString( "fs_cdpath" ); gamedir = Cvar_VariableString( "fs_game" ); fn = FS_BuildOSPath( basepath, gamedir, fname ); // bk001206 - verbose Com_Printf( "Sys_LoadDll(%s)... \n", fn ); // bk001129 - from cvs1.17 (mkv), was fname not fn libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { if( cdpath[0] ) { // bk001206 - report any problem Com_Printf( "Sys_LoadDll(%s) failed: \"%s\"\n", fn, dlerror() ); fn = FS_BuildOSPath( cdpath, gamedir, fname ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { // bk001206 - report any problem Com_Printf( "Sys_LoadDll(%s) failed: \"%s\"\n", fn, dlerror() ); } else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); if ( !libHandle ) { #ifdef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } } // bk001206 - no different behavior //#ifndef NDEBUG } //else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", loadname ); //#endif dllEntry = (void (*)(int (*)(int,...))) dlsym( libHandle, "dllEntry" ); *entryPoint = (int(*)(int,...))dlsym( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { err = dlerror(); #ifdef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain): \"%s\" !\n", name, err ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain): \"%s\" !\n", name, err ); #endif dlclose( libHandle ); err = dlerror(); if ( err != NULL ) Com_Printf ( "Sys_LoadDll(%s) failed dlcose: \"%s\"\n", name, err ); return NULL; } Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212 dllEntry( systemcalls ); Com_Printf ( "Sys_LoadDll(%s) succeeded!\n", name ); return libHandle; }
/* ===================== idModelExport::LoadMayaDll Checks to see if we can load the Maya export dll ===================== */ void idModelExport::LoadMayaDll( void ) { exporterDLLEntry_t dllEntry; char dllPath[ MAX_OSPATH ]; fileSystem->FindDLL( "MayaImport", dllPath, false ); if ( !dllPath[ 0 ] ) { return; } importDLL = sys->DLL_Load( dllPath ); if ( !importDLL ) { return; } // look up the dll interface functions dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" ); Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" ); Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" ); if ( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) { Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Invalid interface on export DLL." ); return; } // initialize the DLL // RAVEN BEGIN // rhummer: unify allocation strategy to try to fix some of our crashes #ifdef RV_UNIFIED_ALLOCATOR if ( !dllEntry( MD5_VERSION, common, sys, Memory::Allocate, Memory::Free, Memory::MSize ) ) { #else if ( !dllEntry( MD5_VERSION, common, sys ) ) { #endif // RAVEN END // init failed Maya_ConvertModel = NULL; Maya_Shutdown = NULL; sys->DLL_Unload( importDLL ); importDLL = 0; gameLocal.Error( "Export DLL init failed." ); return; } // RAVEN BEGIN // jscott: maya needs the source control in the tools dll common->LoadToolsDLL(); // RAVEN END } /* ===================== idModelExport::ConvertMayaToMD5 Checks if a Maya model should be converted to an MD5, and converts if if the time/date or version number has changed. ===================== */ bool idModelExport::ConvertMayaToMD5( void ) { unsigned sourceTime; unsigned destTime; int version; idToken cmdLine; idStr path; // check if our DLL got loaded if ( initialized && !Maya_ConvertModel ) { Maya_Error = "MayaImport dll not loaded."; return false; } // if idAnimManager::forceExport is set then we always reexport Maya models if ( idAnimManager::forceExport ) { force = true; } // RAVEN BEGIN // bdube: fs_import path // we need to make sure we have a full path, so convert the filename to an OS path path.AppendPath( cvarSystem->GetCVarString ("fs_importpath")); path.AppendPath(src); idFile* f = fileSystem->OpenExplicitFileRead ( path ); if ( !f ) { Maya_Error = "could not open source file"; return false; } sourceTime = f->Timestamp ( ); fileSystem->CloseFile ( f ); /* // get the source file's time if ( fileSystem->ReadFile( src, NULL, &sourceTime ) < 0 ) { // source file doesn't exist return true; } */ // RAVEN END // get the destination file's time if ( !force && ( fileSystem->ReadFile( dest, NULL, &destTime ) >= 0 ) ) { idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); parser.LoadFile( dest ); // read the file version if ( parser.CheckTokenString( MD5_VERSION_STRING ) ) { version = parser.ParseInt(); // check the command line if ( parser.CheckTokenString( "commandline" ) ) { parser.ReadToken( &cmdLine ); // check the file time, scale, and version if ( ( destTime >= sourceTime ) && ( version == MD5_VERSION ) && ( cmdLine == commandLine ) ) { // don't convert it return true; } } } } // if this is the first time we've been run, check if Maya is installed and load our DLL if ( !initialized ) { initialized = true; if ( !CheckMayaInstall() ) { Maya_Error = "Maya not installed in registry."; return false; } LoadMayaDll(); // check if our DLL got loaded if ( !Maya_ConvertModel ) { Maya_Error = "Could not load MayaImport dll."; return false; } } // we need to make sure we have a full path, so convert the filename to an OS path src = fileSystem->RelativePathToOSPath( src ); dest = fileSystem->RelativePathToOSPath( dest ); dest.ExtractFilePath( path ); if ( path.Length() ) { fileSystem->CreateOSPath( path ); } // get the os path in case it needs to create one path = fileSystem->RelativePathToOSPath( "" ); common->SetRefreshOnPrint( true ); // RAVEN BEGIN // scork: if this assert ever triggers it means there's a call to ConvertMayaToMD5() that doesn't have a 'MayaConversionCleaner' object above it. Go and put one in. Now. assert( g_bMayaConversionCleanerRunning ); // bdube: support src and dest ospath Maya_Error = Maya_ConvertModel( cvarSystem->GetCVarString ( "fs_importpath" ), path, commandLine ); // RAVEN END common->SetRefreshOnPrint( false ); if ( Maya_Error != "Ok" ) { return false; } // conversion succeded return true; }
/** * @brief Loads a mod library. * #1 look in fs_homepath * #2 look in fs_basepath * #3 try to revert to the default mod library */ void *Sys_LoadGameDll(const char *name, intptr_t(**entryPoint) (int, ...), intptr_t (*systemcalls)(intptr_t, ...)) { void *libHandle; void (*dllEntry)(intptr_t (*syscallptr)(intptr_t, ...)); char fname[MAX_OSPATH]; char *basepath; char *homepath; char *gamedir; assert(name); Com_sprintf(fname, sizeof(fname), Sys_GetDLLName("%s"), name); // TODO: use fs_searchpaths from files.c basepath = Cvar_VariableString("fs_basepath"); homepath = Cvar_VariableString("fs_homepath"); gamedir = Cvar_VariableString("fs_game"); #ifndef DEDICATED // if the server is pure, extract the dlls from the mod_bin.pk3 so // that they can be referenced if (Cvar_VariableValue("sv_pure") && Q_stricmp(name, "qagame")) { Com_Printf("Sys_LoadGameDll -> FS_CL_ExtractFromPakFile(%s, %s, %s)\n", homepath, gamedir, fname); FS_CL_ExtractFromPakFile(homepath, gamedir, fname); } #endif libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname); if (!libHandle && basepath) { libHandle = Sys_TryLibraryLoad(basepath, gamedir, fname); } #ifndef DEDICATED // According to the code above, if the server is not pure, then the // lib must either already be in the homepath, or in the basepath, // without being in a pak. For a pure server, it always grabs the lib // from within a pak. This means there must be two copies of the lib! // // So now, if connecting to an impure server, and the lib was not // loaded from homepath or the basepath, let's pull it out of the pak. // This means we only *need* the copy that's in the pak, and will use // it if another copy isn't found first. if (!libHandle && !Cvar_VariableValue("sv_pure") && Q_stricmp(name, "qagame")) { Com_Printf("Sys_LoadGameDll -> FS_CL_ExtractFromPakFile(%s, %s, %s)\n", homepath, gamedir, fname); FS_CL_ExtractFromPakFile(homepath, gamedir, fname); libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname); } #endif // HACK: sometimes a library is loaded from the mod dir when it shouldn't. Why? if (!libHandle && strcmp(gamedir, DEFAULT_MODGAME)) { Com_Printf("Sys_LoadDll: failed to load the mod library. Trying to revert to the default one.\n"); libHandle = Sys_TryLibraryLoad(basepath, DEFAULT_MODGAME, fname); } if (!libHandle) { Com_Printf("Sys_LoadDll(%s) failed to load library\n", name); return NULL; } dllEntry = (void (QDECL *)(intptr_t (QDECL *)(intptr_t, ...)))Sys_LoadFunction(libHandle, "dllEntry"); *entryPoint = (intptr_t (QDECL *)(int, ...))Sys_LoadFunction(libHandle, "vmMain"); if (!*entryPoint || !dllEntry) { Com_Printf("Sys_LoadDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError()); Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf("Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint); dllEntry(systemcalls); return libHandle; }
void *Sys_LoadDll(const char *name, char *fqpath, int (**entryPoint)(int, ...), int (*systemcalls)(int, ...)) { image_id libHandle = -1; void (*dllEntry)( int (*syscallptr)(int, ...) ); char curpath[MAX_OSPATH]; char fname[MAX_OSPATH]; char *basepath; char *homepath; char *pwdpath; char *gamedir; char *fn; const char* err = NULL; *fqpath = 0; // bk001206 - let's have some paranoia assert(name); getcwd(curpath, sizeof(curpath)); snprintf (fname, sizeof(fname), "%si386.so", name); // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW pwdpath = Sys_Cwd(); basepath = Cvar_VariableString( "fs_basepath" ); homepath = Cvar_VariableString( "fs_homepath" ); gamedir = Cvar_VariableString( "fs_game" ); //pwdpath fn = FS_BuildOSPath( pwdpath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... \n", fn ); //libHandle = dlopen( fn, Q_RTLD ); libHandle = load_add_on(fn); if (/*!libHandle*/libHandle < 0) { Com_Printf("Sys_LoadDll(%s) failed:\n", fn /*dlerror()*/); // fs_homepath fn = FS_BuildOSPath( homepath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... \n", fn ); //libHandle = dlopen( fn, Q_RTLD ); libHandle = load_add_on(fn); if (/*!libHandle*/libHandle < 0) { Com_Printf("Sys_LoadDll(%s) failed:\n", fn /*dlerror()*/); // fs_basepath fn = FS_BuildOSPath( basepath, gamedir, fname ); Com_Printf("Sys_LoadDll(%s)... \n", fn); //libHandle = dlopen( fn, Q_RTLD ); libHandle = load_add_on(fn); if (/*!libHandle*/libHandle < 0) { #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); get_image_symbol(libHandle, "dllEntry", B_SYMBOL_TYPE_TEXT, (void**)&dllEntry); get_image_symbol(libHandle, "vmMain", B_SYMBOL_TYPE_TEXT, (void**)entryPoint); if (!*entryPoint || !dllEntry) { //jens err = dlerror(); #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err); #else Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err); #endif //dlclose(libHandle); unload_add_on(libHandle); //jenserr = dlerror(); if (err != NULL) Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err); return NULL; } Com_Printf("Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint); // bk001212 dllEntry(systemcalls); Com_Printf("Sys_LoadDll(%s) succeeded!\n", name ); if (libHandle) Q_strncpyz(fqpath, fn, MAX_QPATH); // added 7/20/02 by T.Ray return (void*)libHandle; }
void *Sys_LoadDll( const char *name, char *fqpath , int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) ) { void *libHandle; void (*dllEntry)( int (*syscallptr)(int, ...) ); char fname[MAX_OSPATH]; char *cdpath; char *basepath; char *homepath; char *pwdpath; char *gamedir; char *fn; const char* err = NULL; *fqpath = 0; // bk001206 - let's have some paranoia assert( name ); #ifdef _PANDORA_ snprintf (fname, sizeof(fname), "%s.so", name); #else snprintf (fname, sizeof(fname), "%s." SHLIB_SUFFIX, name); #endif // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW pwdpath = Sys_Cwd(); cdpath = Cvar_VariableString( "fs_cdpath" ); basepath = Cvar_VariableString( "fs_basepath" ); homepath = Cvar_VariableString( "fs_homepath" ); gamedir = Cvar_VariableString( "fs_game" ); // pwdpath fn = FS_BuildOSPath( pwdpath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_cdpath fn = FS_BuildOSPath( cdpath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_homepath fn = FS_BuildOSPath( homepath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_basepath fn = FS_BuildOSPath( basepath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn); dllEntry = dlsym( libHandle, "dllEntry" ); *entryPoint = dlsym( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { err = dlerror(); #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #endif dlclose( libHandle ); err = dlerror(); if ( err != NULL ) Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err ); return NULL; } Com_DPrintf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212 dllEntry( systemcalls ); Com_DPrintf ( "Sys_LoadDll(%s) succeeded!\n", name ); if ( libHandle ) Q_strncpyz ( fqpath , fn , MAX_QPATH ) ; // added 7/20/02 by T.Ray return libHandle; }
void *Sys_LoadDll( const char *name, int( **entryPoint ) ( int, ... ), int ( *systemcalls )( int, ... ) ) #endif { void *libHandle; void ( *dllEntry )( int ( *syscallptr )( int, ... ) ); char fname[MAX_OSPATH]; char *homepath; char *basepath; char *pwdpath; char *gamedir; char *fn; const char* err = NULL; // bk001206 // rb0101023 - now const // bk001206 - let's have some paranoia assert( name ); #if defined __i386__ snprintf( fname, sizeof( fname ), "%si386.so", name ); #elif defined __powerpc__ //rcg010207 - PPC support. snprintf( fname, sizeof( fname ), "%sppc.so", name ); #elif defined __axp__ snprintf( fname, sizeof( fname ), "%saxp.so", name ); #elif defined __mips__ snprintf( fname, sizeof( fname ), "%smips.so", name ); #elif defined __arm__ snprintf( fname, sizeof( fname ), "%sarm.so", name ); #else #error Unknown arch #endif // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW homepath = Cvar_VariableString( "fs_homepath" ); basepath = Cvar_VariableString( "fs_basepath" ); gamedir = Cvar_VariableString( "fs_game" ); pwdpath = Sys_Cwd(); fn = FS_BuildOSPath( pwdpath, gamedir, fname ); // bk001206 - verbose Com_Printf( "Sys_LoadDll(%s)... ", fn ); // bk001129 - from cvs1.17 (mkv), was fname not fn libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "failed (%s)\n", dlerror() ); // homepath fn = FS_BuildOSPath( homepath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "failed (%s)\n", dlerror() ); // basepath fn = FS_BuildOSPath( basepath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "failed (%s)\n", dlerror() ); if ( strlen( gamedir ) && Q_stricmp( gamedir, BASEGAME ) ) { // begin BASEGAME != fs_game section // media-only mods: no DLL whatsoever in the fs_game // start the loop again using the hardcoded BASEDIRNAME fn = FS_BuildOSPath( pwdpath, BASEGAME, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "failed (%s)\n", dlerror() ); // homepath fn = FS_BuildOSPath( homepath, BASEGAME, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "failed (%s)\n", dlerror() ); // homepath fn = FS_BuildOSPath( basepath, BASEGAME, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { // ok, this time things are really f****d Com_Printf( "failed (%s)\n", dlerror() ); } else { Com_Printf( "ok\n" ); } } else { Com_Printf( "ok\n" ); } } else { Com_Printf( "ok\n" ); } } // end BASEGAME != fs_game section } else { Com_Printf( "ok\n" ); } } else { Com_Printf( "ok\n" ); } } else { Com_Printf( "ok\n" ); } if ( !libHandle ) { #ifndef NDEBUG // in debug, abort on failure Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } dllEntry = dlsym( libHandle, "dllEntry" ); *entryPoint = dlsym( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { err = dlerror(); #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #else Com_Printf( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #endif dlclose( libHandle ); err = dlerror(); if ( err != NULL ) { Com_Printf( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err ); } return NULL; } Com_Printf( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212 dllEntry( systemcalls ); Com_Printf( "Sys_LoadDll(%s) succeeded!\n", name ); return libHandle; }
/** * @brief Loads a mod library. * #1 look in fs_homepath * #2 look in fs_basepath * #3 try to revert to the default mod library */ void *Sys_LoadGameDll(const char *name, qboolean extract, intptr_t(**entryPoint) (int, ...), intptr_t (*systemcalls)(intptr_t, ...)) { void *libHandle; void (*dllEntry)(intptr_t (*syscallptr)(intptr_t, ...)); char fname[MAX_OSPATH]; char *basepath; char *homepath; char *gamedir; assert(name); Com_sprintf(fname, sizeof(fname), Sys_GetDLLName("%s"), name); // TODO: use fs_searchpaths from files.c basepath = Cvar_VariableString("fs_basepath"); homepath = Cvar_VariableString("fs_homepath"); gamedir = Cvar_VariableString("fs_game"); // STORY TIME // //When doing an debug build just load the mod lib from the basepath as that will have the debug pointers // // Now the code always just unpacks new libraries from the packs on release builds. // So the libraryfiles in the homepath are always refreshed with latest from the packs. // This fixes many issues with clients loading old libraries from the mod paths. // // The way it used to work is described under (or in debug mode).. // // if the server is pure, extract the dlls from the mod_bin.pk3 so // that they can be referenced // // If the server is not pure, then the // lib must either already be in the homepath, or in the basepath, // without being in a pak. For a pure server, it always grabs the lib // from within a pak. This means there must be two copies of the lib! // // So now, if connecting to an impure server, and the lib was not // loaded from homepath or the basepath, let's pull it out of the pak. // This means we only *need* the copy that's in the pak, and will use // it if another copy isn't found first. #ifdef LEGACY_DEBUG #define SEARCHPATH1 basepath #define SEARCHPATH2 homepath #define LIB_DO_UNPACK Cvar_VariableIntegerValue("sv_pure") #else #define LIB_DO_UNPACK qtrue #define SEARCHPATH1 homepath #define SEARCHPATH2 basepath #endif #ifndef DEDICATED if (LIB_DO_UNPACK && extract) { Com_Printf("Sys_LoadGameDll -> FS_CL_ExtractFromPakFile(%s, %s, %s)\n", homepath, gamedir, fname); FS_CL_ExtractFromPakFile(homepath, gamedir, fname); } #endif libHandle = Sys_TryLibraryLoad(SEARCHPATH1, gamedir, fname); if (!libHandle && SEARCHPATH2) { libHandle = Sys_TryLibraryLoad(SEARCHPATH2, gamedir, fname); } #ifndef DEDICATED if (!libHandle && !LIB_DO_UNPACK && extract) { Com_Printf("Sys_LoadGameDll -> FS_CL_ExtractFromPakFile(%s, %s, %s)\n", homepath, gamedir, fname); FS_CL_ExtractFromPakFile(homepath, gamedir, fname); libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname); } #endif if (!libHandle) { Com_Printf("Sys_LoadDll(%s/%s) failed to load library\n", gamedir, name); return NULL; } dllEntry = (void (QDECL *)(intptr_t (QDECL *)(intptr_t, ...)))Sys_LoadFunction(libHandle, "dllEntry"); *entryPoint = (intptr_t (QDECL *)(int, ...))Sys_LoadFunction(libHandle, "vmMain"); if (!*entryPoint || !dllEntry) { Com_Printf("Sys_LoadDll(%s/%s) failed to find vmMain function:\n\"%s\" !\n", gamedir, name, Sys_LibraryError()); Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf("Sys_LoadDll(%s/%s) found vmMain function at %p\n", gamedir, name, *entryPoint); dllEntry(systemcalls); return libHandle; }
/* ================= Sys_LoadDll Used to load a development dll instead of a virtual machine #1 look in fs_homepath #2 look in fs_basepath #4 look in fs_libpath under FreeBSD ================= */ void *QDECL Sys_LoadDll( const char *name, char *fqpath, intptr_t (QDECL **entryPoint)(int, ...), intptr_t (QDECL *systemcalls)(intptr_t, ...) ) { void *libHandle = NULL, (QDECL *dllEntry)( intptr_t (QDECL *syscallptr)(intptr_t, ...) ); char fname[MAX_QPATH], *basepath, *homepath, *gamedir, *libpath; assert( name ); //Q_snprintf (fname, sizeof(fname), Sys_GetDLLName( "%s" ), name); Q_strncpyz(fname, Sys_GetDLLName(name), sizeof(fname)); // TODO: use fs_searchpaths from files.c basepath = Cvar_VariableString( "fs_basepath" ); homepath = Cvar_VariableString( "fs_homepath" ); gamedir = Cvar_VariableString( "fs_game" ); libpath = Cvar_VariableString( "fs_libpath" ); #ifndef DEDICATED // if the server is pure, extract the dlls from the mp_bin.pk3 so // that they can be referenced if ( Cvar_VariableValue( "sv_pure" ) && Q_stricmp( name, "qagame" ) ) { FS_CL_ExtractFromPakFile( homepath, gamedir, fname ); } #endif libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname, fqpath); if (!libHandle && libpath && libpath[0]) { libHandle = Sys_TryLibraryLoad(libpath, gamedir, fname, fqpath); } if(!libHandle && basepath) { libHandle = Sys_TryLibraryLoad(basepath, gamedir, fname, fqpath); } if(!libHandle) { Com_Printf( "Sys_LoadDll(%s) could not find it\n", fname ); return NULL; } if(!libHandle) { Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", name, Sys_LibraryError() ); return NULL; } // Try to load the dllEntry and vmMain function. dllEntry = ( void ( QDECL * )( intptr_t ( QDECL * )( intptr_t, ... ) ) )Sys_LoadFunction( libHandle, "dllEntry" ); *entryPoint = ( intptr_t ( QDECL * )( int,... ) )Sys_LoadFunction( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { #ifndef NDEBUG if (!dllEntry) { Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed SDL_LoadFunction(dllEntry):\n\"%p\" !\n", name, Sys_LibraryError() ); } else { Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed SDL_LoadFunction(vmMain):\n\"%p\" !\n", name, Sys_LibraryError() ); } #else if (!dllEntry) { Com_Printf ( "Sys_LoadDll(%s) failed SDL_LoadFunction(dllEntry):\n\"%p\" !\n", name, Sys_LibraryError() ); } else { Com_Printf ( "Sys_LoadDll(%s) failed SDL_LoadFunction(vmMain):\n\"%p\" !\n", name, Sys_LibraryError() ); } #endif Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf ( "Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint ); dllEntry( systemcalls ); Com_Printf ( "Sys_LoadDll(%s) succeeded!\n", name ); // Copy the fname to fqpath. Q_strncpyz ( fqpath , fname , MAX_QPATH ) ; return libHandle; }
vm_t *VM_Create( const char *module, int (*systemCalls)(int *), vmInterpret_t interpret ) { vm_t *vm; int i, remaining; #ifdef PSP_VM #error vm not available -> only static vmHeader_t *header; int length; int dataLength; char filename[MAX_QPATH]; #endif if ( !module || !module[0] || !systemCalls ) { Com_Error( ERR_FATAL, "VM_Create: bad parms" ); } remaining = Hunk_MemoryRemaining(); // see if we already have the VM for ( i = 0 ; i < MAX_VM ; i++ ) { if (!Q_stricmp(vmTable[i].name, module)) { vm = &vmTable[i]; return vm; } } // find a free vm for ( i = 0 ; i < MAX_VM ; i++ ) { if ( !vmTable[i].name[0] ) { break; } } if ( i == MAX_VM ) { Com_Error( ERR_FATAL, "VM_Create: no free vm_t" ); } vm = &vmTable[i]; Q_strncpyz( vm->name, module, sizeof( vm->name ) ); vm->systemCall = systemCalls; // never allow dll loading with a demo if ( interpret == VMI_NATIVE ) { if ( Cvar_VariableValue( "fs_restrict" ) ) { interpret = VMI_COMPILED; } } if ( interpret == VMI_NATIVE ) { #ifdef PSP_DYNAMIC_LINKING #error dynamic not available -> only static // try to load as a system dll Com_Printf( "Loading dll file %s.\n", vm->name ); vm->dllHandle = Sys_LoadDll( module, vm->fqpath , &vm->entryPoint, VM_DllSyscall ); if ( vm->dllHandle ) { return vm; } Com_Printf( "Failed to load dll, looking for qvm.\n" ); interpret = VMI_COMPILED; #endif } #ifdef PSP_VM #error vm not available -> only static // load the image Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name ); Com_Printf( "Loading vm file %s.\n", filename ); length = FS_ReadFile( filename, (void **)&header ); if ( !header ) { Com_Printf( "Failed.\n" ); VM_Free( vm ); return NULL; } // byte swap the header for ( i = 0 ; i < sizeof( *header ) / 4 ; i++ ) { ((int *)header)[i] = LittleLong( ((int *)header)[i] ); } // validate if ( header->vmMagic != VM_MAGIC || header->bssLength < 0 || header->dataLength < 0 || header->litLength < 0 || header->codeLength <= 0 ) { VM_Free( vm ); Com_Error( ERR_FATAL, "%s has bad header", filename ); } // round up to next power of 2 so all data operations can // be mask protected dataLength = header->dataLength + header->litLength + header->bssLength; for ( i = 0 ; dataLength > ( 1 << i ) ; i++ ) { } dataLength = 1 << i; // allocate zero filled space for initialized and uninitialized data vm->dataBase = Hunk_Alloc( dataLength, h_high ); vm->dataMask = dataLength - 1; // copy the intialized data Com_Memcpy( vm->dataBase, (byte *)header + header->dataOffset, header->dataLength + header->litLength ); // byte swap the longs for ( i = 0 ; i < header->dataLength ; i += 4 ) { *(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) ); } // allocate space for the jump targets, which will be filled in by the compile/prep functions vm->instructionPointersLength = header->instructionCount * 4; vm->instructionPointers = Hunk_Alloc( vm->instructionPointersLength, h_high ); // copy or compile the instructions vm->codeLength = header->codeLength; if ( interpret >= VMI_COMPILED ) { vm->compiled = qtrue; VM_Compile( vm, header ); } else { vm->compiled = qfalse; VM_PrepareInterpreter( vm, header ); } // free the original file FS_FreeFile( header ); // load the map file VM_LoadSymbols( vm ); // the stack is implicitly at the end of the image vm->programStack = vm->dataMask + 1; vm->stackBottom = vm->programStack - STACK_SIZE; Com_Printf("%s loaded in %d bytes on the hunk\n", module, remaining - Hunk_MemoryRemaining()); return vm; #endif #ifndef PSP_DYNAMIC_LINKING #ifndef PSP_VM extern int vmMain ( int callNum, ... ); vm->entryPoint = vmMain; Com_Printf("VM_Create(%s) found **vmMain** at %p \n",module,vmMain); vm->dllHandle = (void *) 1; //some strange but works :) void dllEntry( int (QDECL *syscallptr)( int arg,... ) ) ; dllEntry(VM_DllSyscall); Com_Printf ( "VM_Create(%s) succeeded!\n", module ); return vm; #endif #endif }
/** * @brief Loads a mod library. * #1 look in fs_homepath * #2 look in fs_basepath * #3 try to revert to the default mod library */ void *Sys_LoadDll(const char *name, intptr_t(**entryPoint) (int, ...), intptr_t (*systemcalls)(intptr_t, ...)) { void *libHandle; void (*dllEntry)(intptr_t (*syscallptr)(intptr_t, ...)); char fname[MAX_OSPATH]; char *basepath; char *homepath; char *gamedir; assert(name); Com_sprintf(fname, sizeof(fname), Sys_GetDLLName("%s"), name); // TODO: use fs_searchpaths from files.c basepath = Cvar_VariableString("fs_basepath"); homepath = Cvar_VariableString("fs_homepath"); gamedir = Cvar_VariableString("fs_game"); #ifndef DEDICATED // if the server is pure, extract the dlls from the mp_bin.pk3 so // that they can be referenced if (Cvar_VariableValue("sv_pure") && Q_stricmp(name, "qagame")) { FS_CL_ExtractFromPakFile(homepath, gamedir, fname); } #endif libHandle = Sys_TryLibraryLoad(homepath, gamedir, fname); if (!libHandle && basepath) { libHandle = Sys_TryLibraryLoad(basepath, gamedir, fname); } // HACK: sometimes a library is loaded from the mod dir when it shouldn't. Why? if (!libHandle && strcmp(gamedir, DEFAULT_MODGAME)) { Com_Printf("Sys_LoadDll: failed to load the mod library. Trying to revert to the default one.\n"); libHandle = Sys_TryLibraryLoad(basepath, DEFAULT_MODGAME, fname); } if (!libHandle) { Com_Printf("Sys_LoadDll(%s) failed to load library\n", name); return NULL; } dllEntry = (void (QDECL *)(intptr_t (QDECL *)(intptr_t, ...)))Sys_LoadFunction(libHandle, "dllEntry"); *entryPoint = (intptr_t (QDECL *)(int, ...))Sys_LoadFunction(libHandle, "vmMain"); if (!*entryPoint || !dllEntry) { Com_Printf("Sys_LoadDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError()); Sys_UnloadLibrary(libHandle); return NULL; } Com_Printf("Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint); dllEntry(systemcalls); return libHandle; }
void *Sys_LoadDll( const char *name, char *fqpath, int( **entryPoint ) ( int, ... ), int ( *systemcalls )( int, ... ) ) { void *libHandle; void ( *dllEntry )( int ( *syscallptr )( int, ... ) ); char fname[MAX_OSPATH]; char *pwdpath; char *homepath; char *basepath; char *gamedir; char *fn; const char* err = NULL; // bk001206 // rb0101023 - now const #if !defined( DEDICATED ) char *cvar_name = NULL; #endif *fqpath = 0 ; // added 2/15/02 by T.Ray // bk001206 - let's have some paranoia assert( name ); Q_strncpyz( fname, Sys_GetDLLName( name ), sizeof( fname ) ); // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW pwdpath = Sys_Cwd(); homepath = Cvar_VariableString( "fs_homepath" ); basepath = Cvar_VariableString( "fs_basepath" ); gamedir = Cvar_VariableString( "fs_game" ); // this is relevant to client only // this code is in for full client hosting a game, but it's not affected by it #if !defined( DEDICATED ) // do a first scan to identify what we are going to dlopen // we need to pass this to FS_ExtractFromPakFile so that it checksums the right file // NOTE: if something fails (not found, or file operation failed), we will ERR_FATAL (in the checksum itself, we only ERR_DROP) #ifndef NDEBUG fn = FS_BuildOSPath( pwdpath, gamedir, fname ); if ( access( fn, R_OK ) == -1 ) { #endif fn = FS_BuildOSPath( homepath, gamedir, fname ); if ( access( fn, R_OK ) == 0 ) { // there is a .so in fs_homepath, but is it a valid one version-wise? // we use a persistent variable in config.cfg to make sure // this is set in FS_CL_ExtractFromPakFile when the file is extracted cvar_t *lastVersion; cvar_name = va( "cl_lastVersion%s", name ); lastVersion = Cvar_Get( cvar_name, "(uninitialized)", CVAR_ARCHIVE ); if ( Q_stricmp( Cvar_VariableString( "version" ), lastVersion->string ) ) { Com_DPrintf( "clearing non matching version of %s .so: %s\n", name, fn ); if ( remove( fn ) == -1 ) { Com_Error( ERR_FATAL, "failed to remove outdated '%s' file:\n\"%s\"\n", fn, strerror( errno ) ); } // we cancelled fs_homepath, go work on basepath now fn = FS_BuildOSPath( basepath, gamedir, fname ); if ( access( fn, R_OK ) == -1 ) { // we may be dealing with a media-only mod, check wether we can find 'reference' DLLs and copy them over if ( !CopyDLLForMod( &fn, gamedir, pwdpath, homepath, basepath, fname ) ) { Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed, no corresponding .so file found in fs_homepath or fs_basepath\n", name ); } } } // the .so in fs_homepath is valid version-wise .. FS_CL_ExtractFromPakFile will have to decide wether it's valid pk3-wise later } else { fn = FS_BuildOSPath( basepath, gamedir, fname ); if ( access( fn, R_OK ) == -1 ) { // we may be dealing with a media-only mod, check wether we can find 'reference' DLLs and copy them over if ( !CopyDLLForMod( &fn, gamedir, pwdpath, homepath, basepath, fname ) ) { Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed, no corresponding .so file found in fs_homepath or fs_basepath\n", name ); } } } #ifndef NDEBUG } #endif // NERVE - SMF - extract dlls from pak file for security // we have to handle the game dll a little differently // NOTE #2: we may have found a file in fs_basepath, and if the checksum is wrong, FS_Extract will write in fs_homepath // won't be a problem since we start a brand new scan next if ( cl_connectedToPureServer && Q_strncmp( name, "qagame", 6 ) ) { if ( !FS_CL_ExtractFromPakFile( fn, gamedir, fname, cvar_name ) ) { Com_Error( ERR_DROP, "Game code(%s) failed Pure Server check", fname ); } } #endif #ifndef NDEBUG // current directory // NOTE: only for debug build, see Sys_LoadDll discussion fn = FS_BuildOSPath( pwdpath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "\nSys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); #endif // homepath fn = FS_BuildOSPath( homepath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_Printf( "\nSys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // basepath fn = FS_BuildOSPath( basepath, gamedir, fname ); Com_Printf( "Sys_LoadDll(%s)... ", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { // report any problem Com_Printf( "\nSys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); } else { Com_Printf( "ok\n" ); } // not found, bail if ( !libHandle ) { #ifndef NDEBUG // in debug abort on failure Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } } else { Com_Printf( "ok\n" ); } #ifndef NDEBUG } else { Com_Printf( "ok\n" ); } #endif Q_strncpyz( fqpath, fn, MAX_QPATH ) ; // added 2/15/02 by T.Ray dllEntry = dlsym( libHandle, "dllEntry" ); *entryPoint = dlsym( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { err = dlerror(); #ifndef NDEBUG // in debug abort on failure Com_Error( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #else Com_Printf( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #endif dlclose( libHandle ); err = dlerror(); if ( err != NULL ) { Com_Printf( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err ); } return NULL; } Com_Printf( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); dllEntry( systemcalls ); Com_Printf( "Sys_LoadDll(%s) succeeded!\n", name ); return libHandle; }
void *Sys_LoadDll( const char *name, char *fqpath , int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) ) { #ifdef IPHONE extern int baseq3_ui_vmMain(int, ...), baseq3_qagame_vmMain(int, ...), baseq3_cgame_vmMain(int, ...); extern void baseq3_ui_dllEntry(int (*)(int, ...)), baseq3_qagame_dllEntry(int (*)(int, ...)), baseq3_cgame_dllEntry(int (*)(int, ...)); static const struct { const char *game; const char *name; void (*dllEntry)(int (*)(int, ...)); int (*entryPoint)(int, ...); } dllDescriptions[] = { {"", "ui", baseq3_ui_dllEntry, baseq3_ui_vmMain}, {"", "qagame", baseq3_qagame_dllEntry, baseq3_qagame_vmMain}, {"", "cgame", baseq3_cgame_dllEntry, baseq3_cgame_vmMain}, }; char *game = Cvar_VariableString("fs_game"); int i; for (i = 0; i < sizeof(dllDescriptions) / sizeof(dllDescriptions[0]); ++i) { if (!strcmp(game, dllDescriptions[i].game) && !strcmp(name, dllDescriptions[i].name)) { *entryPoint = dllDescriptions[i].entryPoint; dllDescriptions[i].dllEntry(systemcalls); return (void *)0xdeadc0de; } } Com_Printf("Sys_LoadDll(%s) could not find appropriate entry point for game %s\n", name, game); return NULL; #else void *libHandle; void (*dllEntry)( int (*syscallptr)(int, ...) ); char fname[MAX_OSPATH]; char *cdpath; char *basepath; char *homepath; char *pwdpath; char *gamedir; char *fn; const char* err = NULL; *fqpath = 0; // bk001206 - let's have some paranoia assert( name ); snprintf (fname, sizeof(fname), "%s." SHLIB_SUFFIX, name); // bk001129 - was RTLD_LAZY #define Q_RTLD RTLD_NOW pwdpath = Sys_Cwd(); cdpath = Cvar_VariableString( "fs_cdpath" ); basepath = Cvar_VariableString( "fs_basepath" ); homepath = Cvar_VariableString( "fs_homepath" ); gamedir = Cvar_VariableString( "fs_game" ); // pwdpath fn = FS_BuildOSPath( pwdpath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_cdpath fn = FS_BuildOSPath( cdpath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_homepath fn = FS_BuildOSPath( homepath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { Com_DPrintf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() ); // fs_basepath fn = FS_BuildOSPath( basepath, gamedir, fname ); Com_Printf( "Loading '%s'.\n", fn ); libHandle = dlopen( fn, Q_RTLD ); if ( !libHandle ) { #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name ); #endif return NULL; } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn ); } else Com_DPrintf ( "Sys_LoadDll(%s): succeeded ...\n", fn); dllEntry = dlsym( libHandle, "dllEntry" ); *entryPoint = dlsym( libHandle, "vmMain" ); if ( !*entryPoint || !dllEntry ) { err = dlerror(); #ifndef NDEBUG // bk001206 - in debug abort on failure Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #else Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err ); #endif dlclose( libHandle ); err = dlerror(); if ( err != NULL ) Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err ); return NULL; } Com_DPrintf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212 dllEntry( systemcalls ); Com_DPrintf ( "Sys_LoadDll(%s) succeeded!\n", name ); if ( libHandle ) Q_strncpyz ( fqpath , fn , MAX_QPATH ) ; // added 7/20/02 by T.Ray return libHandle; #endif // IPHONE }