Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}