HB_BOOL hb_libFree( PHB_ITEM pDynLib ) { HB_BOOL fResult = HB_FALSE; void ** pDynLibPtr = ( void ** ) hb_itemGetPtrGC( pDynLib, &s_gcDynlibFuncs ); if( pDynLibPtr && *pDynLibPtr && hb_vmLockModuleSymbols() ) { void * hDynLib = *pDynLibPtr; if( hDynLib ) { *pDynLibPtr = NULL; hb_vmExitSymbolGroup( hDynLib ); #if defined( HB_OS_WIN ) fResult = FreeLibrary( ( HMODULE ) hDynLib ); #elif defined( HB_OS_OS2 ) fResult = DosFreeModule( ( HMODULE ) hDynLib ) == NO_ERROR; #elif defined( HB_HAS_DLFCN ) fResult = dlclose( hDynLib ) == 0; #elif defined( HB_CAUSEWAY_DLL ) FreeLibrary( hDynLib ); fResult = HB_TRUE; #endif } hb_vmUnlockModuleSymbols(); } return fResult; }
PHB_ITEM hb_libLoad( PHB_ITEM pLibName, PHB_ITEM pArgs ) { void * hDynLib = NULL; if( hb_itemGetCLen( pLibName ) > 0 ) { int argc = pArgs ? ( int ) hb_arrayLen( pArgs ) : 0, i; const char ** argv = NULL; if( argc > 0 ) { argv = ( const char ** ) hb_xgrab( sizeof( char * ) * argc ); for( i = 0; i < argc; ++i ) argv[ i ] = hb_arrayGetCPtr( pArgs, i + 1 ); } if( hb_vmLockModuleSymbols() ) { /* use stack address as first level marker */ hb_vmBeginSymbolGroup( ( void * ) hb_stackId(), HB_TRUE ); #if defined( HB_OS_WIN ) { void * hFileName; hDynLib = ( void * ) LoadLibraryEx( HB_ITEMGETSTR( pLibName, &hFileName, NULL ), NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); hb_strfree( hFileName ); } #elif defined( HB_OS_OS2 ) { HB_UCHAR LoadError[ 256 ] = ""; /* Area for load failure information */ HMODULE hDynModule; if( DosLoadModule( ( PSZ ) LoadError, sizeof( LoadError ), ( PCSZ ) hb_itemGetCPtr( pLibName ), &hDynModule ) == NO_ERROR ) hDynLib = ( void * ) hDynModule; } #elif defined( HB_HAS_DLFCN ) hDynLib = ( void * ) dlopen( hb_itemGetCPtr( pLibName ), RTLD_LAZY | RTLD_GLOBAL ); if( ! hDynLib ) { HB_TRACE( HB_TR_DEBUG, ( "hb_libLoad(): dlopen(): %s", dlerror() ) ); } #elif defined( HB_CAUSEWAY_DLL ) hDynLib = LoadLibrary( hb_itemGetCPtr( pLibName ) ); #else { int iTODO; } #endif /* set real marker */ hb_vmInitSymbolGroup( hDynLib, argc, argv ); hb_vmUnlockModuleSymbols(); } if( argv ) hb_xfree( ( void * ) argv ); } if( hDynLib ) { void ** pLibPtr = ( void ** ) hb_gcAllocate( sizeof( void * ), &s_gcDynlibFuncs ); *pLibPtr = hDynLib; return hb_itemPutPtrGC( NULL, pLibPtr ); } return NULL; }
static PHRB_BODY hb_hrbLoad( const char * szHrbBody, HB_SIZE nBodySize, HB_USHORT usMode, const char * szFileName ) { PHRB_BODY pHrbBody = NULL; if( szHrbBody ) { HB_SIZE nBodyOffset = 0; HB_SIZE nSize; /* Size of function */ HB_SIZE nPos; HB_ULONG ul; char * buffer, ch; HB_USHORT usBind = ( usMode & HB_HRB_BIND_MODEMASK ); PHB_SYMB pSymRead; /* Symbols read */ PHB_DYNF pDynFunc; /* Functions read */ PHB_DYNS pDynSym; int iVersion = hb_hrbReadHead( szHrbBody, nBodySize, &nBodyOffset ); if( iVersion == 0 ) { hb_errRT_BASE( EG_CORRUPTION, 9995, NULL, HB_ERR_FUNCNAME, 0 ); return NULL; } pHrbBody = ( PHRB_BODY ) hb_xgrab( sizeof( HRB_BODY ) ); pHrbBody->fInit = HB_FALSE; pHrbBody->fExit = HB_FALSE; pHrbBody->lSymStart = -1; pHrbBody->ulFuncs = 0; pHrbBody->pSymRead = NULL; pHrbBody->pDynFunc = NULL; pHrbBody->pModuleSymbols = NULL; if( ! hb_hrbReadValue( szHrbBody, nBodySize, &nBodyOffset, &pHrbBody->ulSymbols ) || pHrbBody->ulSymbols == 0 ) { hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_CORRUPTION, 9996, NULL, HB_ERR_FUNCNAME, 0 ); return NULL; } /* calculate the size of dynamic symbol table */ nPos = nBodyOffset; nSize = 0; for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Read symbols in .hrb */ { while( nBodyOffset < nBodySize ) { ++nSize; if( szHrbBody[ nBodyOffset++ ] == 0 ) break; } nBodyOffset += 2; if( nBodyOffset >= nBodySize ) { hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_CORRUPTION, 9997, NULL, HB_ERR_FUNCNAME, 0 ); return NULL; } } nBodyOffset = nPos; ul = pHrbBody->ulSymbols * sizeof( HB_SYMB ); pSymRead = ( PHB_SYMB ) hb_xgrab( nSize + ul ); buffer = ( ( char * ) pSymRead ) + ul; for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Read symbols in .hrb */ { pSymRead[ ul ].szName = buffer; do { ch = *buffer++ = szHrbBody[ nBodyOffset++ ]; } while( ch ); pSymRead[ ul ].scope.value = ( HB_BYTE ) szHrbBody[ nBodyOffset++ ]; pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) ( HB_PTRDIFF ) szHrbBody[ nBodyOffset++ ]; pSymRead[ ul ].pDynSym = NULL; if( pHrbBody->lSymStart == -1 && ( pSymRead[ ul ].scope.value & HB_FS_FIRST ) != 0 && ( pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == 0 ) { pHrbBody->lSymStart = ul; } } /* Read number of functions */ if( ! hb_hrbReadValue( szHrbBody, nBodySize, &nBodyOffset, &pHrbBody->ulFuncs ) ) { hb_xfree( pSymRead ); hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_CORRUPTION, 9997, NULL, HB_ERR_FUNCNAME, 0 ); return NULL; } pHrbBody->pSymRead = pSymRead; if( pHrbBody->ulFuncs ) { pDynFunc = ( PHB_DYNF ) hb_xgrab( pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); memset( pDynFunc, 0, pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); pHrbBody->pDynFunc = pDynFunc; for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) { HB_ULONG ulValue; /* Read name of function */ pDynFunc[ ul ].szName = hb_hrbReadId( szHrbBody, nBodySize, &nBodyOffset ); if( pDynFunc[ ul ].szName == NULL ) break; /* Read size of function */ if( ! hb_hrbReadValue( szHrbBody, nBodySize, &nBodyOffset, &ulValue ) ) break; nSize = ( HB_SIZE ) ulValue; if( nBodyOffset + nSize > nBodySize ) break; /* Copy function body */ pDynFunc[ ul ].pCode = ( HB_BYTE * ) hb_xgrab( nSize ); memcpy( ( char * ) pDynFunc[ ul ].pCode, szHrbBody + nBodyOffset, nSize ); nBodyOffset += nSize; pDynFunc[ ul ].pCodeFunc = ( PHB_PCODEFUNC ) hb_xgrab( sizeof( HB_PCODEFUNC ) ); pDynFunc[ ul ].pCodeFunc->pCode = pDynFunc[ ul ].pCode; pDynFunc[ ul ].pCodeFunc->pSymbols = pSymRead; } if( ul < pHrbBody->ulFuncs ) { hb_xfree( pSymRead ); hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_CORRUPTION, 9998, NULL, HB_ERR_FUNCNAME, 0 ); return NULL; } } /* End of PCODE loading, now linking */ for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) { if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_FUNC ) { nPos = hb_hrbFindSymbol( pSymRead[ ul ].szName, pHrbBody->pDynFunc, pHrbBody->ulFuncs ); if( nPos == SYM_NOT_FOUND ) { pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) SYM_EXTERN; } else { pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) pHrbBody->pDynFunc[ nPos ].pCodeFunc; pSymRead[ ul ].scope.value |= HB_FS_PCODEFUNC | HB_FS_LOCAL | ( usBind == HB_HRB_BIND_FORCELOCAL ? HB_FS_STATIC : 0 ); } } else if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_DEFERRED ) { pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) SYM_EXTERN; pSymRead[ ul ].scope.value |= HB_FS_DEFERRED; } /* External function */ if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_EXTERN ) { pSymRead[ ul ].value.pCodeFunc = NULL; pDynSym = hb_dynsymFind( pSymRead[ ul ].szName ); if( pDynSym ) { pSymRead[ ul ].value.pFunPtr = pDynSym->pSymbol->value.pFunPtr; if( pDynSym->pSymbol->scope.value & HB_FS_PCODEFUNC ) { pSymRead[ ul ].scope.value |= HB_FS_PCODEFUNC; } } else if( ( pSymRead[ ul ].scope.value & HB_FS_DEFERRED ) == 0 ) { if( ( usMode & HB_HRB_BIND_LAZY ) != 0 ) pSymRead[ ul ].scope.value |= HB_FS_DEFERRED; else { char szName[ HB_SYMBOL_NAME_LEN + 1 ]; hb_strncpy( szName, pSymRead[ ul ].szName, sizeof( szName ) - 1 ); hb_xfree( pSymRead ); hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_ARG, 6101, "Unknown or unregistered symbol", szName, 0 ); return NULL; } } } } if( hb_vmLockModuleSymbols() ) { if( usBind == HB_HRB_BIND_LOCAL ) { for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) { if( ( pSymRead[ ul ].scope.value & ( HB_FS_LOCAL | HB_FS_STATIC ) ) == HB_FS_LOCAL ) { pDynSym = hb_dynsymFind( pSymRead[ ul ].szName ); if( pDynSym ) { /* convert public function to static one */ pSymRead[ ul ].scope.value |= HB_FS_STATIC; } } } } pHrbBody->pModuleSymbols = hb_vmRegisterSymbols( pHrbBody->pSymRead, ( HB_USHORT ) pHrbBody->ulSymbols, szFileName ? szFileName : "pcode.hrb", 0, HB_TRUE, HB_FALSE, usBind == HB_HRB_BIND_OVERLOAD ); if( pHrbBody->pModuleSymbols->pModuleSymbols != pSymRead ) { /* * Old unused symbol table has been recycled - free the one * we allocated and disactivate static initialization [druzus] */ pHrbBody->pSymRead = pHrbBody->pModuleSymbols->pModuleSymbols; hb_xfree( pSymRead ); pHrbBody->fInit = HB_TRUE; } else { /* mark symbol table as dynamically allocated so HVM will free it on exit */ pHrbBody->pModuleSymbols->fAllocated = HB_TRUE; /* initialize static variables */ hb_hrbInitStatic( pHrbBody ); } hb_vmUnlockModuleSymbols(); } else { hb_xfree( pSymRead ); hb_hrbUnLoad( pHrbBody ); pHrbBody = NULL; } } return pHrbBody; }